diff --git a/DEPS b/DEPS
index 01dabbc..fd254dc 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'ec553c59e4816ab49fbc3dac1994c7e0b0a9333e',
+  'v8_revision': '7d4656480331054baf7de03388c234d84f861d1e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '555b31faa192c7a85c84979bea28d4914e93c784',
+  'pdfium_revision': 'cf7df1bfba955f48f1f70211e55dc0d5c87afcfe',
   # 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': 'c9667ecd29cbb003b7fbdcd6f2da0f02bf0e7257',
+  'catapult_revision': '29f450ae4dcb657197866e4d48bc465834b8d8c6',
   # 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/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h
index 61fca1b..5917a9f 100644
--- a/ash/wm/tablet_mode/tablet_mode_controller.h
+++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -102,6 +102,8 @@
   // the feature is enabled and we are in tablet mode.
   bool ShouldAutoHideTitlebars() const;
 
+  bool auto_hide_title_bars() const { return auto_hide_title_bars_; }
+
   // ShellObserver:
   void OnShellInitialized() override;
 
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index d9228a1..56e16fc 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -137,6 +137,7 @@
  public:
   TestSequencedTaskRunner()
       : worker_pool_(2 /* max_threads */, "Test Task Runner"),
+        token_(worker_pool_.pool()->GetSequenceToken()),
         enabled_(true),
         num_of_post_tasks_(0) {}
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 00557dce..6b9c0a1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -716,12 +716,6 @@
                 : ColorUtils.getTextBoxAlphaForToolbarBackground(mTabVisible);
     }
 
-    @Override
-    public boolean areBrowserControlsPermanentlyHidden() {
-        return mFullscreenManager != null
-                && mFullscreenManager.areBrowserControlsPermanentlyHidden();
-    }
-
     /**
      * @return The height of the top browser controls in pixels.
      */
@@ -738,9 +732,7 @@
 
     @Override
     public float getOverlayTranslateY() {
-        return areBrowserControlsPermanentlyHidden()
-                ? getTopControlsHeightPixels()
-                : mFullscreenManager.getTopVisibleContentOffset();
+        return mFullscreenManager.getTopVisibleContentOffset();
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java
index 7f00f54..d10bade 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java
@@ -62,11 +62,6 @@
     float getBrowserControlsUrlBarAlpha();
 
     /**
-     * @return Whether or not the toolbar is currently being faked.
-     */
-    boolean areBrowserControlsPermanentlyHidden();
-
-    /**
      * @return The {@link ResourceManager}.
      */
     ResourceManager getResourceManager();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
index f8da09a..dcecebd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
@@ -69,7 +69,6 @@
     private boolean mInGesture;
     private boolean mContentViewScrolling;
 
-    private boolean mBrowserControlsPermanentlyHidden;
     private boolean mBrowserControlsAndroidViewHidden;
 
     private final ArrayList<FullscreenListener> mListeners = new ArrayList<>();
@@ -324,22 +323,6 @@
     }
 
     /**
-     * @param remove Whether or not to forcefully remove the toolbar.
-     */
-    public void setBrowserControlsPermamentlyHidden(boolean remove) {
-        if (remove == mBrowserControlsPermanentlyHidden) return;
-        mBrowserControlsPermanentlyHidden = remove;
-        updateVisuals();
-    }
-
-    /**
-     * @return Whether or not the toolbar is forcefully being removed.
-     */
-    public boolean areBrowserControlsPermanentlyHidden() {
-        return mBrowserControlsPermanentlyHidden;
-    }
-
-    /**
      * @return Whether the browser controls should be drawn as a texture.
      */
     public boolean drawControlsAsTexture() {
@@ -371,7 +354,6 @@
 
     @Override
     public float getContentOffset() {
-        if (mBrowserControlsPermanentlyHidden) return 0;
         return mRendererTopContentOffset;
     }
 
@@ -379,7 +361,6 @@
      * @return The offset of the controls from the top of the screen.
      */
     public float getTopControlOffset() {
-        if (mBrowserControlsPermanentlyHidden) return -getTopControlsHeight();
         // This is to avoid a problem with -0f in tests.
         if (mControlOffsetRatio == 0f) return 0f;
         return mControlOffsetRatio * -getTopControlsHeight();
@@ -389,7 +370,6 @@
      * @return The offset of the controls from the bottom of the screen.
      */
     public float getBottomControlOffset() {
-        if (mBrowserControlsPermanentlyHidden) return getBottomControlsHeight();
         if (mControlOffsetRatio == 0f) return 0f;
         return mControlOffsetRatio * getBottomControlsHeight();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java
index 7c7680c..806d6e1a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java
@@ -13,6 +13,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions;
 import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager;
+import org.chromium.components.url_formatter.UrlFormatter;
 
 /**
  * Interface for native code to interact with Android notification channels.
@@ -98,7 +99,8 @@
         }
 
         public NotificationChannel toChannel() {
-            NotificationChannel channel = new NotificationChannel(mId, mOrigin,
+            NotificationChannel channel = new NotificationChannel(mId,
+                    UrlFormatter.formatUrlForSecurityDisplay(mOrigin, false /* showScheme */),
                     mStatus == NotificationChannelStatus.BLOCKED
                             ? NotificationManager.IMPORTANCE_NONE
                             : NotificationManager.IMPORTANCE_DEFAULT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoBottomSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoBottomSheetContent.java
index 4a2cfef6..1c61936 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoBottomSheetContent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoBottomSheetContent.java
@@ -52,11 +52,11 @@
         mScrollView.setBackgroundColor(ApiCompatibilityUtils.getColor(
                 mIncognitoNewTabPageView.getResources(), R.color.incognito_primary_color));
         // Remove some additional padding that's not necessary when using Chrome Home.
-        mScrollView.setPaddingRelative(mScrollView.getPaddingStart(),
+        mScrollView.setPaddingRelative(ApiCompatibilityUtils.getPaddingStart(mScrollView),
                 mScrollView.getPaddingTop()
                         - ((int) activity.getResources().getDimension(
                                   R.dimen.toolbar_height_no_shadow)),
-                mScrollView.getPaddingEnd(), mScrollView.getPaddingBottom());
+                ApiCompatibilityUtils.getPaddingEnd(mScrollView), mScrollView.getPaddingBottom());
 
         mScrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
             @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
index 03b53ec..9fe47896 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -607,6 +607,7 @@
                     @Override
                     public void onCancel() {
                         setButtonsEnabled(true);
+                        onSigninConfirmationCancel();
                     }
                 });
     }
@@ -658,17 +659,21 @@
         mNegativeButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                if (mUndoBehavior == UNDO_BACK_TO_SELECTION) {
-                    RecordUserAction.record("Signin_Undo_Signin");
-                    showSigninPage();
-                } else {
-                    assert mUndoBehavior == UNDO_ABORT;
-                    mListener.onAccountSelectionCanceled();
-                }
+                RecordUserAction.record("Signin_Undo_Signin");
+                onSigninConfirmationCancel();
             }
         });
     }
 
+    private void onSigninConfirmationCancel() {
+        if (mUndoBehavior == UNDO_BACK_TO_SELECTION) {
+            showSigninPage();
+        } else {
+            assert mUndoBehavior == UNDO_ABORT;
+            mListener.onAccountSelectionCanceled();
+        }
+    }
+
     private void setUpConfirmButton() {
         mPositiveButton.setText(getResources().getText(R.string.signin_accept));
         mPositiveButton.setOnClickListener(new OnClickListener() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java
index 1c20f20..20ee2b0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java
@@ -71,11 +71,6 @@
         }
 
         @Override
-        public boolean areBrowserControlsPermanentlyHidden() {
-            return false;
-        }
-
-        @Override
         public ResourceManager getResourceManager() {
             return null;
         }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
index 710001ff..1092db0c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
@@ -128,11 +128,6 @@
     }
 
     @Override
-    public boolean areBrowserControlsPermanentlyHidden() {
-        return false;
-    }
-
-    @Override
     public ResourceManager getResourceManager() {
         return null;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
index 32f2ae8..456c727 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
@@ -34,6 +34,7 @@
 import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl;
 import org.chromium.chrome.browser.notifications.NotificationSettingsBridge;
 import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.content.browser.test.NativeLibraryTestRule;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -52,16 +53,24 @@
     private Context mContext;
 
     @Rule
+    public NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule();
+
+    @Rule
     @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     public Features.Processor processor = new Features.Processor();
 
     @Before
     public void setUp() throws Exception {
+        // Not initializing the browser process is safe because
+        // UrlFormatter.formatUrlForSecurityDisplay() is stand-alone.
+        mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
+
         mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
         mNotificationManagerProxy = new NotificationManagerProxyImpl(
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE));
         mChannelsInitializer =
                 new ChannelsInitializer(mNotificationManagerProxy, mContext.getResources());
+
         // Delete any channels and channel groups that may already have been initialized. Cleaning
         // up here rather than in tearDown in case tests running before these ones caused channels
         // to be created.
@@ -252,7 +261,7 @@
         assertThat(getChannelsIgnoringDefault(), hasSize(1));
 
         NotificationChannel channel = getChannelsIgnoringDefault().get(0);
-        assertThat(channel.getName().toString(), is("https://example.com"));
+        assertThat(channel.getName().toString(), is("example.com"));
         assertThat(channel.getImportance(), is(NotificationManager.IMPORTANCE_DEFAULT));
         assertThat(channel.getGroup(), is(ChannelDefinitions.CHANNEL_GROUP_ID_SITES));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdaterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdaterTest.java
index a37393f..2c849989 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdaterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdaterTest.java
@@ -20,14 +20,19 @@
 import android.support.test.filters.SmallTest;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.InMemorySharedPreferences;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.notifications.NotificationManagerProxy;
 import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.content.browser.test.NativeLibraryTestRule;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -43,8 +48,19 @@
     private ChannelsInitializer mChannelsInitializer;
     private Resources mMockResources;
 
+    @Rule
+    @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public Features.Processor processor = new Features.Processor();
+
+    @Rule
+    public NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule();
+
     @Before
     public void setUp() throws Exception {
+        // Not initializing the browser process is safe because
+        // UrlFormatter.formatUrlForSecurityDisplay() is stand-alone.
+        mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
+
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         mNotificationManagerProxy = new NotificationManagerProxyImpl(
                 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
@@ -124,6 +140,7 @@
     @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @TargetApi(Build.VERSION_CODES.O)
+    @Features(@Features.Register(ChromeFeatureList.SITE_NOTIFICATION_CHANNELS))
     public void testUpdateChannels_createsExpectedChannelsAndUpdatesPref() throws Exception {
         ChannelsUpdater updater = new ChannelsUpdater(
                 true /* isAtLeastO */, mMockSharedPreferences, mChannelsInitializer, 21);
@@ -134,7 +151,7 @@
                 containsInAnyOrder(ChannelDefinitions.CHANNEL_ID_BROWSER,
                         ChannelDefinitions.CHANNEL_ID_DOWNLOADS,
                         ChannelDefinitions.CHANNEL_ID_INCOGNITO,
-                        ChannelDefinitions.CHANNEL_ID_SITES, ChannelDefinitions.CHANNEL_ID_MEDIA));
+                        ChannelDefinitions.CHANNEL_ID_MEDIA));
         assertThat(mMockSharedPreferences.getInt(ChannelsUpdater.CHANNELS_VERSION_KEY, -1), is(21));
     }
 
@@ -142,6 +159,7 @@
     @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @TargetApi(Build.VERSION_CODES.O)
+    @Features(@Features.Register(ChromeFeatureList.SITE_NOTIFICATION_CHANNELS))
     public void testUpdateChannels_deletesLegacyChannelsAndCreatesExpectedOnes() throws Exception {
         // Set up any legacy channels.
         for (String id : ChannelDefinitions.getLegacyChannelIds()) {
@@ -159,7 +177,7 @@
                 containsInAnyOrder(ChannelDefinitions.CHANNEL_ID_BROWSER,
                         ChannelDefinitions.CHANNEL_ID_DOWNLOADS,
                         ChannelDefinitions.CHANNEL_ID_INCOGNITO,
-                        ChannelDefinitions.CHANNEL_ID_SITES, ChannelDefinitions.CHANNEL_ID_MEDIA));
+                        ChannelDefinitions.CHANNEL_ID_MEDIA));
     }
 
     private static List<String> getChannelIds(List<NotificationChannel> channels) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManagerTest.java
index 97d05f3..1eb08ef 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManagerTest.java
@@ -4,6 +4,7 @@
 package org.chromium.chrome.browser.notifications.channels;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 
@@ -19,6 +20,7 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -28,8 +30,11 @@
 import org.chromium.chrome.browser.notifications.NotificationManagerProxy;
 import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl;
 import org.chromium.chrome.browser.notifications.NotificationSettingsBridge;
+import org.chromium.content.browser.test.NativeLibraryTestRule;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Instrumentation unit tests for SiteChannelsManager.
@@ -43,9 +48,15 @@
 @RunWith(BaseJUnit4ClassRunner.class)
 public class SiteChannelsManagerTest {
     private SiteChannelsManager mSiteChannelsManager;
+    @Rule
+    public NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule();
 
     @Before
     public void setUp() throws Exception {
+        // Not initializing the browser process is safe because
+        // UrlFormatter.formatUrlForSecurityDisplay() is stand-alone.
+        mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
+
         Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
         NotificationManagerProxy notificationManagerProxy = new NotificationManagerProxyImpl(
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE));
@@ -82,6 +93,22 @@
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @TargetApi(Build.VERSION_CODES.O)
     @SmallTest
+    public void testCreateSiteChannel_stripsSchemaForChannelName() throws Exception {
+        mSiteChannelsManager.createSiteChannel("http://127.0.0.1", 0L, true);
+        mSiteChannelsManager.createSiteChannel("https://example.com", 0L, true);
+        mSiteChannelsManager.createSiteChannel("ftp://127.0.0.1", 0L, true);
+        List<String> channelNames = new ArrayList<>();
+        for (NotificationSettingsBridge.SiteChannel siteChannel :
+                mSiteChannelsManager.getSiteChannels()) {
+            channelNames.add(siteChannel.toChannel().getName().toString());
+        }
+        assertThat(channelNames, containsInAnyOrder("ftp://127.0.0.1", "example.com", "127.0.0.1"));
+    }
+
+    @Test
+    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
+    @TargetApi(Build.VERSION_CODES.O)
+    @SmallTest
     public void testCreateSiteChannel_disabled() throws Exception {
         mSiteChannelsManager.createSiteChannel("https://example-blocked.org", 0L, false);
         assertThat(Arrays.asList(mSiteChannelsManager.getSiteChannels()), hasSize(1));
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ec607079..a078696 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9255,15 +9255,6 @@
       <message name="IDS_NOTIFICATION_PERMISSIONS_FRAGMENT" desc="Permission sentence fragment to show following the prompt 'This site wants to:' in a permissions request">
         Show notifications
       </message>
-      <message name="IDS_NOTIFICATION_WELCOME_BODY" desc="Notification body for the Welcome Notification">
-        Stay connected to what you need to know, across all devices.
-      </message>
-      <message name="IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE" desc="Learn more button text for the Welcome Notification">
-        Learn more
-      </message>
-      <message name="IDS_NOTIFICATION_WELCOME_TITLE" desc="Notification title for the Welcome Notification">
-        Google Now for Chrome!
-      </message>
       <message name="IDS_NOTIFICATION_BUTTON_SETTINGS" desc="Short button label to go to the notification settings panel">
         Settings
       </message>
@@ -9273,9 +9264,6 @@
       <message name="IDS_NOTIFICATION_BUTTON_MORE" desc="Label shown on the second button of a MAC OSX system notification used to expand further options. [CHAR-LIMIT=12]">
         More
       </message>
-      <message name="IDS_NOTIFIER_WELCOME_BUTTON" desc="Notification body for when a new notifier service is introduced.">
-        Turn off these notifications
-      </message>
       <message name="IDS_NOTIFICATION_REPLY_PLACEHOLDER" desc="Placeholder text shown in the text box before any text is entered when replying directly to a notification.">
         Send message
       </message>
diff --git a/chrome/app/theme/default_100_percent/common/block_notifier.png b/chrome/app/theme/default_100_percent/common/block_notifier.png
deleted file mode 100644
index d6f1f65..0000000
--- a/chrome/app/theme/default_100_percent/common/block_notifier.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/notification_welcome_learn_more.png b/chrome/app/theme/default_100_percent/cros/downloads/learn_more.png
similarity index 100%
rename from chrome/app/theme/default_100_percent/common/notification_welcome_learn_more.png
rename to chrome/app/theme/default_100_percent/cros/downloads/learn_more.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/block_notifier.png b/chrome/app/theme/default_200_percent/common/block_notifier.png
deleted file mode 100644
index 6c7b057f..0000000
--- a/chrome/app/theme/default_200_percent/common/block_notifier.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_welcome_icon.png b/chrome/app/theme/default_200_percent/common/notification_welcome_icon.png
deleted file mode 100644
index 10705ac..0000000
--- a/chrome/app/theme/default_200_percent/common/notification_welcome_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_welcome_learn_more.png b/chrome/app/theme/default_200_percent/cros/downloads/learn_more.png
similarity index 100%
rename from chrome/app/theme/default_200_percent/common/notification_welcome_learn_more.png
rename to chrome/app/theme/default_200_percent/cros/downloads/learn_more.png
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 331e9e1..98334cad 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -150,6 +150,7 @@
         <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DELETE" file="cros/downloads/delete.png" />
         <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DOWNLOAD" file="cros/downloads/download.png" />
         <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_FOLDER" file="cros/downloads/folder.png" />
+        <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_LEARN_MORE" file="cros/downloads/learn_more.png" />
         <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_PAUSE" file="cros/downloads/pause.png" />
         <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_COPY_TO_CLIPBOARD" file="cros/downloads/copy_to_clipboard.png" />
         <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_FAILURE" file="cros/enable_debugging_failure.png" />
@@ -268,9 +269,6 @@
         <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_ENABLED" file="cros/notification_easyunlock_enabled.png" />
         <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_PROMO" file="cros/notification_easyunlock_promo.png" />
       </if>
-      <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_ICON" file="common/notification_welcome_icon.png" />
-      <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_LEARN_MORE" file="common/notification_welcome_learn_more.png" />
-      <structure type="chrome_scaled_image" name="IDR_NOTIFIER_BLOCK_BUTTON" file="common/block_notifier.png" />
       <if expr="is_macosx">
         <structure type="chrome_scaled_image" name="IDR_OVERLAY_DROP_SHADOW" file="mac/overlay_drop_shadow.png" />
       </if>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 20c3b001..b16202e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3354,10 +3354,6 @@
       "notifications/application_notifier_source.h",
       "notifications/arc_application_notifier_source_chromeos.cc",
       "notifications/arc_application_notifier_source_chromeos.h",
-      "notifications/extension_welcome_notification.cc",
-      "notifications/extension_welcome_notification.h",
-      "notifications/extension_welcome_notification_factory.cc",
-      "notifications/extension_welcome_notification_factory.h",
       "notifications/message_center_notification_manager.cc",
       "notifications/message_center_notification_manager.h",
       "notifications/message_center_settings_controller.cc",
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc
index 1cf49d7..c9e9c827 100644
--- a/chrome/browser/certificate_manager_model.cc
+++ b/chrome/browser/certificate_manager_model.cc
@@ -210,8 +210,8 @@
           x509_certificate_model::GetSerialNumberHexified(cert, std::string()));
       break;
     case COL_EXPIRES_ON: {
-      base::Time not_before, not_after;
-      if (net::x509_util::GetValidityTimes(cert, &not_before, &not_after))
+      base::Time not_after;
+      if (net::x509_util::GetValidityTimes(cert, nullptr, &not_after))
         rv = base::TimeFormatShortDateNumeric(not_after);
       break;
     }
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index e3b0e44..c315b604 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -789,11 +789,11 @@
 
   drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
   if (logger) {
-    logger->Log(logging::LOG_INFO,
-                "%s[%d] called. (types: '%s', maxResults: '%d')", name(),
-                request_id(), api::file_manager_private::ToString(
-                                  params->search_params.types).c_str(),
-                params->search_params.max_results);
+    logger->Log(
+        logging::LOG_INFO, "%s[%d] called. (types: '%s', maxResults: '%d')",
+        name(), request_id(),
+        api::file_manager_private::ToString(params->search_params.types),
+        params->search_params.max_results);
   }
   set_log_on_completion(true);
 
diff --git a/chrome/browser/chromeos/options/cert_library.cc b/chrome/browser/chromeos/options/cert_library.cc
index dad898a0..e060790 100644
--- a/chrome/browser/chromeos/options/cert_library.cc
+++ b/chrome/browser/chromeos/options/cert_library.cc
@@ -21,6 +21,7 @@
 #include "crypto/nss_util.h"
 #include "net/cert/cert_database.h"
 #include "net/cert/nss_cert_database.h"
+#include "net/cert/x509_util_nss.h"
 #include "third_party/icu/source/i18n/unicode/coll.h"  // icu::Collator
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_collator.h"
@@ -32,20 +33,14 @@
 // Root CA certificates that are built into Chrome use this token name.
 const char kRootCertificateTokenName[] = "Builtin Object Token";
 
-base::string16 GetDisplayString(net::X509Certificate* cert,
-                                bool hardware_backed) {
-  std::string alt_text;
-  if (!cert->subject().organization_names.empty())
-    alt_text = cert->subject().organization_names[0];
-  if (alt_text.empty())
-    alt_text = cert->subject().GetDisplayName();
-  base::string16 issued_by = base::UTF8ToUTF16(
-      certificate::GetIssuerCommonName(cert->os_cert_handle(), alt_text));
+base::string16 GetDisplayString(CERTCertificate* cert, bool hardware_backed) {
+  base::string16 issued_by =
+      base::UTF8ToUTF16(certificate::GetIssuerDisplayName(cert));
 
-  base::string16 issued_to = base::UTF8ToUTF16(
-      certificate::GetCertNameOrNickname(cert->os_cert_handle()));
-  base::string16 issued_to_ascii = base::UTF8ToUTF16(
-      certificate::GetCertAsciiNameOrNickname(cert->os_cert_handle()));
+  base::string16 issued_to =
+      base::UTF8ToUTF16(certificate::GetCertNameOrNickname(cert));
+  base::string16 issued_to_ascii =
+      base::UTF8ToUTF16(certificate::GetCertAsciiNameOrNickname(cert));
   if (issued_to_ascii != issued_to) {
     // Input contained encoded data, show original and decoded forms.
     issued_to = l10n_util::GetStringFUTF16(IDS_CERT_INFO_IDN_VALUE_FORMAT,
@@ -66,10 +61,9 @@
   }
 }
 
-std::string CertToPEM(const net::X509Certificate& cert) {
+std::string CertToPEM(CERTCertificate* cert) {
   std::string pem_encoded_cert;
-  if (!net::X509Certificate::GetPEMEncoded(cert.os_cert_handle(),
-                                           &pem_encoded_cert)) {
+  if (!net::x509_util::GetPEMEncoded(cert, &pem_encoded_cert)) {
     LOG(ERROR) << "Couldn't PEM-encode certificate";
     return std::string();
   }
@@ -84,8 +78,8 @@
       : collator_(collator) {
   }
 
-  bool operator()(const scoped_refptr<net::X509Certificate>& lhs,
-                  const scoped_refptr<net::X509Certificate>& rhs) const {
+  bool operator()(const net::ScopedCERTCertificate& lhs,
+                  const net::ScopedCERTCertificate& rhs) const {
     base::string16 lhs_name = GetDisplayString(lhs.get(), false);
     base::string16 rhs_name = GetDisplayString(rhs.get(), false);
     if (collator_ == NULL)
@@ -149,28 +143,29 @@
 }
 
 int CertLibrary::NumCertificates(CertType type) const {
-  const net::CertificateList& cert_list = GetCertificateListForType(type);
+  const net::ScopedCERTCertificateList& cert_list =
+      GetCertificateListForType(type);
   return static_cast<int>(cert_list.size());
 }
 
 base::string16 CertLibrary::GetCertDisplayStringAt(CertType type,
                                                    int index) const {
-  net::X509Certificate* cert = GetCertificateAt(type, index);
+  CERTCertificate* cert = GetCertificateAt(type, index);
   bool hardware_backed = IsCertHardwareBackedAt(type, index);
   return GetDisplayString(cert, hardware_backed);
 }
 
 std::string CertLibrary::GetServerCACertPEMAt(int index) const {
-  return CertToPEM(*GetCertificateAt(CERT_TYPE_SERVER_CA, index));
+  return CertToPEM(GetCertificateAt(CERT_TYPE_SERVER_CA, index));
 }
 
 std::string CertLibrary::GetUserCertPkcs11IdAt(int index, int* slot_id) const {
-  net::X509Certificate* cert = GetCertificateAt(CERT_TYPE_USER, index);
-  return CertLoader::GetPkcs11IdAndSlotForCert(*cert, slot_id);
+  CERTCertificate* cert = GetCertificateAt(CERT_TYPE_USER, index);
+  return CertLoader::GetPkcs11IdAndSlotForCert(cert, slot_id);
 }
 
 bool CertLibrary::IsCertHardwareBackedAt(CertType type, int index) const {
-  net::X509Certificate* cert = GetCertificateAt(type, index);
+  CERTCertificate* cert = GetCertificateAt(type, index);
   return CertLoader::IsCertificateHardwareBacked(cert);
 }
 
@@ -178,8 +173,8 @@
     const std::string& pem_encoded) const {
   int num_certs = NumCertificates(CERT_TYPE_SERVER_CA);
   for (int index = 0; index < num_certs; ++index) {
-    net::X509Certificate* cert = GetCertificateAt(CERT_TYPE_SERVER_CA, index);
-    if (CertToPEM(*cert) != pem_encoded)
+    CERTCertificate* cert = GetCertificateAt(CERT_TYPE_SERVER_CA, index);
+    if (CertToPEM(cert) != pem_encoded)
       continue;
     return index;
   }
@@ -190,17 +185,18 @@
     const std::string& pkcs11_id) const {
   int num_certs = NumCertificates(CERT_TYPE_USER);
   for (int index = 0; index < num_certs; ++index) {
-    net::X509Certificate* cert = GetCertificateAt(CERT_TYPE_USER, index);
+    CERTCertificate* cert = GetCertificateAt(CERT_TYPE_USER, index);
     int slot_id = -1;
-    std::string id = CertLoader::GetPkcs11IdAndSlotForCert(*cert, &slot_id);
+    std::string id = CertLoader::GetPkcs11IdAndSlotForCert(cert, &slot_id);
     if (id == pkcs11_id)
       return index;
   }
   return -1;  // Not found.
 }
 
-void CertLibrary::OnCertificatesLoaded(const net::CertificateList& cert_list,
-                                       bool initial_load) {
+void CertLibrary::OnCertificatesLoaded(
+    const net::ScopedCERTCertificateList& cert_list,
+    bool initial_load) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG(1) << "CertLibrary::OnCertificatesLoaded: " << cert_list.size();
   certs_.clear();
@@ -209,24 +205,23 @@
   server_ca_certs_.clear();
 
   // Add certificates to the appropriate list.
-  for (net::CertificateList::const_iterator iter = cert_list.begin();
-       iter != cert_list.end(); ++iter) {
-    certs_.push_back(iter->get());
-    net::X509Certificate::OSCertHandle cert_handle =
-        iter->get()->os_cert_handle();
-    net::CertType type = certificate::GetCertType(cert_handle);
+  certs_.reserve(cert_list.size());
+  for (const net::ScopedCERTCertificate& cert : cert_list) {
+    certs_.push_back(net::x509_util::DupCERTCertificate(cert.get()));
+    net::CertType type = certificate::GetCertType(cert.get());
     switch (type) {
       case net::USER_CERT:
-        user_certs_.push_back(iter->get());
+        user_certs_.push_back(net::x509_util::DupCERTCertificate(cert.get()));
         break;
       case net::SERVER_CERT:
-        server_certs_.push_back(iter->get());
+        server_certs_.push_back(net::x509_util::DupCERTCertificate(cert.get()));
         break;
       case net::CA_CERT: {
         // Exclude root CA certificates that are built into Chrome.
-        std::string token_name = certificate::GetCertTokenName(cert_handle);
+        std::string token_name = certificate::GetCertTokenName(cert.get());
         if (token_name != kRootCertificateTokenName)
-          server_ca_certs_.push_back(iter->get());
+          server_ca_certs_.push_back(
+              net::x509_util::DupCERTCertificate(cert.get()));
         break;
       }
       default:
@@ -256,15 +251,15 @@
     observer.OnCertificatesLoaded(initial_load);
 }
 
-net::X509Certificate* CertLibrary::GetCertificateAt(CertType type,
-                                                    int index) const {
-  const net::CertificateList& cert_list = GetCertificateListForType(type);
+CERTCertificate* CertLibrary::GetCertificateAt(CertType type, int index) const {
+  const net::ScopedCERTCertificateList& cert_list =
+      GetCertificateListForType(type);
   DCHECK_GE(index, 0);
   DCHECK_LT(index, static_cast<int>(cert_list.size()));
   return cert_list[index].get();
 }
 
-const net::CertificateList& CertLibrary::GetCertificateListForType(
+const net::ScopedCERTCertificateList& CertLibrary::GetCertificateListForType(
     CertType type) const {
   if (type == CERT_TYPE_USER)
     return user_certs_;
diff --git a/chrome/browser/chromeos/options/cert_library.h b/chrome/browser/chromeos/options/cert_library.h
index 49b8e1a3..a17dd04 100644
--- a/chrome/browser/chromeos/options/cert_library.h
+++ b/chrome/browser/chromeos/options/cert_library.h
@@ -11,7 +11,7 @@
 #include "base/strings/string16.h"
 #include "base/threading/thread_checker.h"
 #include "chromeos/cert_loader.h"
-#include "net/cert/x509_certificate.h"
+#include "net/cert/scoped_nss_types.h"
 
 namespace chromeos {
 
@@ -79,23 +79,24 @@
   int GetUserCertIndexByPkcs11Id(const std::string& pkcs11_id) const;
 
   // CertLoader::Observer
-  void OnCertificatesLoaded(const net::CertificateList&,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList&,
                             bool initial_load) override;
 
  private:
   CertLibrary();
   ~CertLibrary() override;
 
-  net::X509Certificate* GetCertificateAt(CertType type, int index) const;
-  const net::CertificateList& GetCertificateListForType(CertType type) const;
+  CERTCertificate* GetCertificateAt(CertType type, int index) const;
+  const net::ScopedCERTCertificateList& GetCertificateListForType(
+      CertType type) const;
 
   base::ObserverList<CertLibrary::Observer> observer_list_;
 
   // Sorted certificate lists
-  net::CertificateList certs_;
-  net::CertificateList user_certs_;
-  net::CertificateList server_certs_;
-  net::CertificateList server_ca_certs_;
+  net::ScopedCERTCertificateList certs_;
+  net::ScopedCERTCertificateList user_certs_;
+  net::ScopedCERTCertificateList server_certs_;
+  net::ScopedCERTCertificateList server_ca_certs_;
 
   THREAD_CHECKER(thread_checker_);
 
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
index ec306f0..81c8c05 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -36,13 +36,19 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "crypto/nss_key_util.h"
+#include "crypto/openssl_util.h"
 #include "crypto/scoped_nss_types.h"
 #include "net/base/net_errors.h"
+#include "net/cert/asn1_util.h"
 #include "net/cert/cert_database.h"
 #include "net/cert/nss_cert_database.h"
 #include "net/cert/x509_util_nss.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
 
 using content::BrowserContext;
 using content::BrowserThread;
@@ -268,7 +274,7 @@
         from, base::Bind(callback_, base::Passed(&certs), error_message));
   }
 
-  std::unique_ptr<net::CertificateList> certs_;
+  net::ScopedCERTCertificateList certs_;
 
  private:
   // Must be called on origin thread, therefore use CallBack().
@@ -581,10 +587,10 @@
 void FilterCertificatesOnWorkerThread(
     std::unique_ptr<GetCertificatesState> state) {
   std::unique_ptr<net::CertificateList> client_certs(new net::CertificateList);
-  for (net::CertificateList::const_iterator it = state->certs_->begin();
-       it != state->certs_->end();
-       ++it) {
-    net::X509Certificate::OSCertHandle cert_handle = (*it)->os_cert_handle();
+  for (net::ScopedCERTCertificateList::const_iterator it =
+           state->certs_.begin();
+       it != state->certs_.end(); ++it) {
+    CERTCertificate* cert_handle = it->get();
     crypto::ScopedPK11Slot cert_slot(PK11_KeyForCertExists(cert_handle,
                                                            NULL,    // keyPtr
                                                            NULL));  // wincx
@@ -594,7 +600,12 @@
     if (cert_slot != state->slot_)
       continue;
 
-    client_certs->push_back(*it);
+    scoped_refptr<net::X509Certificate> cert =
+        net::x509_util::CreateX509CertificateFromCERTCertificate(cert_handle);
+    if (!cert)
+      continue;
+
+    client_certs->push_back(std::move(cert));
   }
 
   state->CallBack(FROM_HERE, std::move(client_certs),
@@ -604,7 +615,7 @@
 // Passes the obtained certificates to the worker thread for filtering. Used by
 // GetCertificatesWithDB().
 void DidGetCertificates(std::unique_ptr<GetCertificatesState> state,
-                        std::unique_ptr<net::CertificateList> all_certs) {
+                        net::ScopedCERTCertificateList all_certs) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   state->certs_ = std::move(all_certs);
   // This task interacts with the TPM, hence MayBlock().
@@ -641,16 +652,24 @@
     return;
   }
 
+  net::ScopedCERTCertificate nss_cert =
+      net::x509_util::CreateCERTCertificateFromX509Certificate(
+          state->certificate_.get());
+  if (!nss_cert) {
+    state->OnError(FROM_HERE, net::ErrorToString(net::ERR_CERT_INVALID));
+    return;
+  }
+
   // Check that the private key is in the correct slot.
   crypto::ScopedPK11Slot slot(
-      PK11_KeyForCertExists(state->certificate_->os_cert_handle(), NULL, NULL));
+      PK11_KeyForCertExists(nss_cert.get(), NULL, NULL));
   if (slot.get() != state->slot_.get()) {
     state->OnError(FROM_HERE, kErrorKeyNotFound);
     return;
   }
 
-  const net::Error import_status = static_cast<net::Error>(
-      cert_db->ImportUserCert(state->certificate_.get()));
+  const net::Error import_status =
+      static_cast<net::Error>(cert_db->ImportUserCert(nss_cert.get()));
   if (import_status != net::OK) {
     LOG(ERROR) << "Could not import certificate.";
     state->OnError(FROM_HERE, net::ErrorToString(import_status));
@@ -683,13 +702,19 @@
 void RemoveCertificateWithDB(std::unique_ptr<RemoveCertificateState> state,
                              net::NSSCertDatabase* cert_db) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  // Get the pointer before base::Passed clears |state|.
-  scoped_refptr<net::X509Certificate> certificate = state->certificate_;
-  bool certificate_found = certificate->os_cert_handle()->isperm;
+
+  net::ScopedCERTCertificate nss_cert =
+      net::x509_util::CreateCERTCertificateFromX509Certificate(
+          state->certificate_.get());
+  if (!nss_cert) {
+    state->OnError(FROM_HERE, net::ErrorToString(net::ERR_CERT_INVALID));
+    return;
+  }
+
+  bool certificate_found = nss_cert->isperm;
   cert_db->DeleteCertAndKeyAsync(
-      certificate,
-      base::Bind(
-          &DidRemoveCertificate, base::Passed(&state), certificate_found));
+      std::move(nss_cert), base::Bind(&DidRemoveCertificate,
+                                      base::Passed(&state), certificate_found));
 }
 
 // Does the actual work to determine which tokens are available.
@@ -807,8 +832,15 @@
 
 std::string GetSubjectPublicKeyInfo(
     const scoped_refptr<net::X509Certificate>& certificate) {
-  const SECItem& spki_der = certificate->os_cert_handle()->derPublicKey;
-  return std::string(spki_der.data, spki_der.data + spki_der.len);
+  std::string der_bytes;
+  if (!net::X509Certificate::GetDEREncoded(certificate->os_cert_handle(),
+                                           &der_bytes))
+    return {};
+
+  base::StringPiece spki_bytes;
+  if (!net::asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
+    return {};
+  return spki_bytes.as_string();
 }
 
 bool GetPublicKey(const scoped_refptr<net::X509Certificate>& certificate,
@@ -829,14 +861,24 @@
     return false;
   }
 
-  crypto::ScopedSECKEYPublicKey public_key(
-      CERT_ExtractPublicKey(certificate->os_cert_handle()));
-  if (!public_key) {
+  std::string spki = GetSubjectPublicKeyInfo(certificate);
+  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+  CBS cbs;
+  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs));
+  if (!pkey) {
     LOG(WARNING) << "Could not extract public key of certificate.";
     return false;
   }
-  long public_exponent = DER_GetInteger(&public_key->u.rsa.publicExponent);
-  if (public_exponent != 65537L) {
+  RSA* rsa = EVP_PKEY_get0_RSA(pkey.get());
+  if (!rsa) {
+    LOG(WARNING) << "Could not get RSA from PKEY.";
+    return false;
+  }
+
+  const BIGNUM* public_exponent;
+  RSA_get0_key(rsa, nullptr /* out_n */, &public_exponent, nullptr /* out_d */);
+  if (BN_get_word(public_exponent) != 65537L) {
     LOG(ERROR) << "Rejecting RSA public exponent that is unequal 65537.";
     return false;
   }
diff --git a/chrome/browser/download/download_commands.cc b/chrome/browser/download/download_commands.cc
index bb08939..d8990d2f 100644
--- a/chrome/browser/download/download_commands.cc
+++ b/chrome/browser/download/download_commands.cc
@@ -145,7 +145,7 @@
     case CANCEL:
       return IDR_DOWNLOAD_NOTIFICATION_MENU_CANCEL;
     case LEARN_MORE_SCANNING:
-      return IDR_NOTIFICATION_WELCOME_LEARN_MORE;
+      return IDR_DOWNLOAD_NOTIFICATION_MENU_LEARN_MORE;
     case COPY_TO_CLIPBOARD:
       return IDR_DOWNLOAD_NOTIFICATION_MENU_COPY_TO_CLIPBOARD;
     case ANNOTATE:
diff --git a/chrome/browser/download/notification/download_item_notification.cc b/chrome/browser/download/notification/download_item_notification.cc
index 57660da..7ec6086 100644
--- a/chrome/browser/download/notification/download_item_notification.cc
+++ b/chrome/browser/download/notification/download_item_notification.cc
@@ -446,23 +446,6 @@
              // If the notification is already visible as popup or in the
              // notification center, doesn't pop it up.
              (type == UPDATE_AND_POPUP && IsNotificationVisible())) {
-    // Shows a notifiation as progress type once so the visible content will be
-    // updated. Only progress-type notification's content will be updated
-    // immediately when the message center is visible.
-    // See the comment in MessageCenterImpl::UpdateNotification() for detail.
-    if (type == UPDATE_AND_POPUP &&
-        message_center_->IsMessageCenterVisible() &&
-        (item_->GetState() == content::DownloadItem::COMPLETE ||
-         item_->GetState() == content::DownloadItem::INTERRUPTED)) {
-      DCHECK_EQ(notification_->type(),
-                message_center::NOTIFICATION_TYPE_BASE_FORMAT);
-
-      notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
-      g_browser_process->notification_ui_manager()->
-          Update(*notification_, profile());
-      notification_->set_type(message_center::NOTIFICATION_TYPE_BASE_FORMAT);
-    }
-
     g_browser_process->notification_ui_manager()->
         Update(*notification_, profile());
   } else if (type == UPDATE_AND_POPUP) {
diff --git a/chrome/browser/download/notification/download_notification.cc b/chrome/browser/download/notification/download_notification.cc
index e82ea57..7976c927 100644
--- a/chrome/browser/download/notification/download_notification.cc
+++ b/chrome/browser/download/notification/download_notification.cc
@@ -69,9 +69,3 @@
 NotificationDelegate* DownloadNotification::watcher() const {
   return watcher_.get();
 }
-
-void DownloadNotification::InvokeUnsafeForceNotificationFlush(
-    message_center::MessageCenter* message_center, const std::string& id) {
-  DCHECK(message_center);
-  message_center->ForceNotificationFlush(id);
-}
diff --git a/chrome/browser/download/notification/download_notification.h b/chrome/browser/download/notification/download_notification.h
index 2a04055..a2caba1d 100644
--- a/chrome/browser/download/notification/download_notification.h
+++ b/chrome/browser/download/notification/download_notification.h
@@ -31,11 +31,6 @@
   virtual void OnNotificationButtonClick(int button_index) {}
   virtual std::string GetNotificationId() const = 0;
 
-  // This method may break a layout of notification center. See the comment in
-  // message_center::MessageCenter::ForceNotificationFlush() for detail.
-  void InvokeUnsafeForceNotificationFlush(
-      message_center::MessageCenter* message_center, const std::string& id);
-
  protected:
   NotificationDelegate* watcher() const;
 
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
index f348fda5d..8e38eda 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -59,20 +59,23 @@
 // |script| is NULL, uses prefs::kWebKitCommonScript.
 std::string GetFontNamePrefPath(fonts::GenericFamily generic_family_enum,
                                 fonts::ScriptCode script_enum) {
-  std::string script = fonts::ToString(script_enum);
-  if (script.empty())
-    script = prefs::kWebKitCommonScript;
-  std::string generic_family = fonts::ToString(generic_family_enum);
-
-  size_t prefix_len = strlen(pref_names_util::kWebKitFontPrefPrefix);
-
   // Format is <prefix-(includes-dot)><family>.<script>
   std::string result;
-  result.reserve(prefix_len + generic_family.size() + script.size() + 1);
+  size_t prefix_len = strlen(pref_names_util::kWebKitFontPrefPrefix);
+  std::string generic_family = fonts::ToString(generic_family_enum);
+
+  // Script codes are 4, dot adds one more for 5.
+  result.reserve(prefix_len + generic_family.size() + 5);
+
   result.append(pref_names_util::kWebKitFontPrefPrefix, prefix_len);
-  result.append(generic_family);
+  result.append(fonts::ToString(generic_family_enum));
   result.push_back('.');
-  result.append(script);
+
+  const char* script = fonts::ToString(script_enum);
+  if (script[0] == 0)  // Empty string.
+    result.append(prefs::kWebKitCommonScript);
+  else
+    result.append(script);
   return result;
 }
 
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
index e499306..b62c6f5f 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -494,14 +494,12 @@
   }
 
   bool SetupCertificates() {
-    scoped_refptr<net::X509Certificate> system_ca_cert =
-        net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                                "client_1_ca.pem");
-    if (!system_ca_cert)
+    net::ScopedCERTCertificateList cert_list =
+        net::CreateCERTCertificateListFromFile(
+            net::GetTestCertsDirectory(), "client_1_ca.pem",
+            net::X509Certificate::FORMAT_AUTO);
+    if (cert_list.empty())
       return false;
-
-    net::CertificateList cert_list;
-    cert_list.push_back(std::move(system_ca_cert));
     // TODO(stevenjb): Figure out a simple way to import a test user cert.
 
     chromeos::NetworkHandler::Get()
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
index 4c3132c..53918c6 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -12,6 +12,7 @@
 #include "chrome/common/media_router/media_sink.h"
 #include "components/cast_channel/cast_socket_service.h"
 #include "components/net_log/chrome_net_log.h"
+#include "net/base/backoff_entry.h"
 
 namespace {
 
@@ -47,7 +48,38 @@
 }  // namespace
 
 // static
-const int CastMediaSinkServiceImpl::kCastControlPort = 8009;
+const net::BackoffEntry::Policy CastMediaSinkServiceImpl::kBackoffPolicy = {
+    // Number of initial errors (in sequence) to ignore before going into
+    // exponential backoff.
+    0,
+
+    // Initial delay (in ms) once backoff starts. It should be longer than
+    // Cast
+    // socket's liveness timeout |kConnectLivenessTimeoutSecs| (10 seconds).
+    kDelayInSeconds * 1000,  // 15 seconds
+
+    // Factor by which the delay will be multiplied on each subsequent
+    // failure.
+    1.0,
+
+    // Fuzzing percentage: 50% will spread delays randomly between 50%--100%
+    // of
+    // the nominal time.
+    0.5,  // 50%
+
+    // Maximum delay (in ms) during exponential backoff.
+    30 * 1000,  // 30 seconds
+
+    // Time to keep an entry from being discarded even when it has no
+    // significant state, -1 to never discard. (Not applicable.)
+    -1,
+
+    // False means that initial_delay_ms is the first delay once we start
+    // exponential backoff, i.e., there is no delay after subsequent
+    // successful
+    // requests.
+    false,
+};
 
 CastMediaSinkServiceImpl::CastMediaSinkServiceImpl(
     const OnSinksDiscoveredCallback& callback,
@@ -55,7 +87,10 @@
     DiscoveryNetworkMonitor* network_monitor)
     : MediaSinkServiceBase(callback),
       cast_socket_service_(cast_socket_service),
-      network_monitor_(network_monitor) {
+      network_monitor_(network_monitor),
+      backoff_policy_(&kBackoffPolicy),
+      task_runner_(content::BrowserThread::GetTaskRunnerForThread(
+          content::BrowserThread::IO)) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
   DCHECK(cast_socket_service_);
   DCHECK(network_monitor_);
@@ -68,6 +103,11 @@
   network_monitor_->RemoveObserver(this);
 }
 
+void CastMediaSinkServiceImpl::SetTaskRunnerForTest(
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+  task_runner_ = task_runner;
+}
+
 // MediaSinkService implementation
 void CastMediaSinkServiceImpl::Start() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -99,19 +139,20 @@
 
 void CastMediaSinkServiceImpl::RecordDeviceCounts() {
   metrics_.RecordDeviceCountsIfNeeded(current_sinks_.size(),
-                                      current_service_ip_endpoints_.size());
+                                      known_ip_endpoints_.size());
 }
 
 void CastMediaSinkServiceImpl::OpenChannels(
     std::vector<MediaSinkInternal> cast_sinks) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  current_service_ip_endpoints_.clear();
+  known_ip_endpoints_.clear();
 
   for (const auto& cast_sink : cast_sinks) {
     const net::IPEndPoint& ip_endpoint = cast_sink.cast_data().ip_endpoint;
-    current_service_ip_endpoints_.insert(ip_endpoint);
-    OpenChannel(ip_endpoint, cast_sink);
+    known_ip_endpoints_.insert(ip_endpoint);
+    OpenChannel(ip_endpoint, cast_sink,
+                base::MakeUnique<net::BackoffEntry>(backoff_policy_));
   }
 
   MediaSinkServiceBase::RestartTimer();
@@ -121,29 +162,48 @@
                                        cast_channel::ChannelError error_state) {
   DVLOG(1) << "OnError [ip_endpoint]: " << socket.ip_endpoint().ToString()
            << " [error_state]: "
-           << cast_channel::ChannelErrorToString(error_state);
-  auto& ip_address = socket.ip_endpoint().address();
-  current_sinks_map_.erase(ip_address);
-  MediaSinkServiceBase::RestartTimer();
+           << cast_channel::ChannelErrorToString(error_state)
+           << " [channel_id]: " << socket.id();
+
+  net::IPEndPoint ip_endpoint = socket.ip_endpoint();
+
+  // Need a PostTask() here because RemoveSocket() will release the memory of
+  // |socket|. Need to make sure all tasks on |socket| finish before deleting
+  // the object.
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(
+          base::IgnoreResult(&cast_channel::CastSocketService::RemoveSocket),
+          base::Unretained(cast_socket_service_), socket.id()));
+
+  // No op if socket is not opened yet. OnChannelOpened will handle this error.
+  if (socket.ready_state() == cast_channel::ReadyState::CONNECTING) {
+    DVLOG(2) << "Opening socket is pending, no-op... "
+             << ip_endpoint.ToString();
+    return;
+  }
+
+  std::unique_ptr<net::BackoffEntry> backoff_entry(
+      new net::BackoffEntry(backoff_policy_));
+
+  DVLOG(2) << "OnError starts reopening cast channel: "
+           << ip_endpoint.ToString();
+  // Find existing cast sink from |current_sinks_map_|.
+  auto cast_sink_it = current_sinks_map_.find(ip_endpoint.address());
+  if (cast_sink_it != current_sinks_map_.end()) {
+    OnChannelErrorMayRetry(cast_sink_it->second, std::move(backoff_entry),
+                           error_state);
+    return;
+  }
+
+  DVLOG(2) << "Cannot find existing cast sink. Skip reopen cast channel: "
+           << ip_endpoint.ToString();
 }
 
 void CastMediaSinkServiceImpl::OnMessage(
     const cast_channel::CastSocket& socket,
     const cast_channel::CastMessage& message) {}
 
-void CastMediaSinkServiceImpl::OpenChannel(const net::IPEndPoint& ip_endpoint,
-                                           MediaSinkInternal cast_sink) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DVLOG(2) << "OpenChannel " << ip_endpoint.ToString()
-           << " name: " << cast_sink.sink().name();
-
-  cast_socket_service_->OpenSocket(
-      ip_endpoint, g_browser_process->net_log(),
-      base::BindOnce(&CastMediaSinkServiceImpl::OnChannelOpened, AsWeakPtr(),
-                     std::move(cast_sink)),
-      this);
-}
-
 void CastMediaSinkServiceImpl::OnNetworksChanged(
     const std::string& network_id) {
   std::string last_network_id = current_network_id_;
@@ -170,38 +230,110 @@
   OpenChannels(cache_entry->second);
 }
 
+void CastMediaSinkServiceImpl::OpenChannel(
+    const net::IPEndPoint& ip_endpoint,
+    const MediaSinkInternal& cast_sink,
+    std::unique_ptr<net::BackoffEntry> backoff_entry) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!pending_for_open_ip_endpoints_.insert(ip_endpoint).second) {
+    DVLOG(2) << "Pending opening request for " << ip_endpoint.ToString()
+             << " name: " << cast_sink.sink().name();
+    return;
+  }
+
+  DVLOG(2) << "Start OpenChannel " << ip_endpoint.ToString()
+           << " name: " << cast_sink.sink().name();
+
+  cast_socket_service_->OpenSocket(
+      ip_endpoint, g_browser_process->net_log(),
+      base::BindOnce(&CastMediaSinkServiceImpl::OnChannelOpened, AsWeakPtr(),
+                     cast_sink, std::move(backoff_entry)),
+      this);
+}
+
 void CastMediaSinkServiceImpl::OnChannelOpened(
+    const MediaSinkInternal& cast_sink,
+    std::unique_ptr<net::BackoffEntry> backoff_entry,
+    cast_channel::CastSocket* socket) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(socket);
+
+  pending_for_open_ip_endpoints_.erase(cast_sink.cast_data().ip_endpoint);
+  bool succeeded = socket->error_state() == cast_channel::ChannelError::NONE;
+  if (backoff_entry)
+    backoff_entry->InformOfRequest(succeeded);
+
+  if (succeeded) {
+    OnChannelOpenSucceeded(cast_sink, socket);
+  } else {
+    OnChannelErrorMayRetry(cast_sink, std::move(backoff_entry),
+                           socket->error_state());
+  }
+}
+
+void CastMediaSinkServiceImpl::OnChannelErrorMayRetry(
+    MediaSinkInternal cast_sink,
+    std::unique_ptr<net::BackoffEntry> backoff_entry,
+    cast_channel::ChannelError error_state) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const net::IPEndPoint& ip_endpoint = cast_sink.cast_data().ip_endpoint;
+  OnChannelOpenFailed(ip_endpoint);
+
+  if (!backoff_entry || backoff_entry->failure_count() > kMaxAttempts) {
+    DVLOG(1) << "Fail to open channel after all retry attempts: "
+             << ip_endpoint.ToString() << " [error_state]: "
+             << cast_channel::ChannelErrorToString(error_state);
+    return;
+  }
+
+  const base::TimeDelta delay = backoff_entry->GetTimeUntilRelease();
+  DVLOG(2) << "Try to reopen: " << ip_endpoint.ToString() << " in ["
+           << delay.InSeconds() << "] seconds"
+           << " [Attempt]: " << backoff_entry->failure_count();
+
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&CastMediaSinkServiceImpl::OpenChannel, AsWeakPtr(),
+                     ip_endpoint, std::move(cast_sink),
+                     std::move(backoff_entry)),
+      delay);
+}
+
+void CastMediaSinkServiceImpl::OnChannelOpenSucceeded(
     MediaSinkInternal cast_sink,
     cast_channel::CastSocket* socket) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(socket);
-  if (socket->error_state() != cast_channel::ChannelError::NONE) {
-    DVLOG(2) << "Fail to open channel "
-             << cast_sink.cast_data().ip_endpoint.ToString()
-             << " [name]: " << cast_sink.sink().name();
-    return;
-  }
 
   media_router::CastSinkExtraData extra_data = cast_sink.cast_data();
   extra_data.capabilities = cast_channel::CastDeviceCapability::AUDIO_OUT;
   if (!socket->audio_only())
     extra_data.capabilities |= cast_channel::CastDeviceCapability::VIDEO_OUT;
   extra_data.cast_channel_id = socket->id();
-  MediaSinkInternal updated_sink(cast_sink.sink(), extra_data);
+  cast_sink.set_cast_data(extra_data);
   DVLOG(2) << "Ading sink to current_sinks_ [name]: "
-           << updated_sink.sink().name();
+           << cast_sink.sink().name();
 
+  // Add or update existing cast sink.
   auto& ip_address = cast_sink.cast_data().ip_endpoint.address();
-  current_sinks_map_[ip_address] = updated_sink;
+  current_sinks_map_[ip_address] = cast_sink;
 
   MediaSinkServiceBase::RestartTimer();
 }
 
+void CastMediaSinkServiceImpl::OnChannelOpenFailed(
+    const net::IPEndPoint& ip_endpoint) {
+  auto& ip_address = ip_endpoint.address();
+  current_sinks_map_.erase(ip_address);
+  MediaSinkServiceBase::RestartTimer();
+}
+
 void CastMediaSinkServiceImpl::OnDialSinkAdded(const MediaSinkInternal& sink) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   net::IPEndPoint ip_endpoint(sink.dial_data().ip_address, kCastControlPort);
 
-  if (base::ContainsKey(current_service_ip_endpoints_, ip_endpoint)) {
+  if (base::ContainsKey(current_sinks_map_, ip_endpoint.address())) {
     DVLOG(2) << "Sink discovered by mDNS, skip adding [name]: "
              << sink.sink().name();
     return;
@@ -209,7 +341,8 @@
 
   // TODO(crbug.com/753175): Dual discovery should not try to open cast channel
   // for non-Cast device.
-  OpenChannel(ip_endpoint, CreateCastSinkFromDialSink(sink));
+  OpenChannel(ip_endpoint, CreateCastSinkFromDialSink(sink),
+              base::MakeUnique<net::BackoffEntry>(backoff_policy_));
 }
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
index 26bc8f8..34fe2bcf 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/media/router/discovery/media_sink_service_base.h"
 #include "components/cast_channel/cast_channel_enum.h"
 #include "components/cast_channel/cast_socket.h"
+#include "net/base/backoff_entry.h"
 
 namespace cast_channel {
 class CastSocketService;
@@ -32,13 +33,21 @@
       public DiscoveryNetworkMonitor::Observer {
  public:
   // Default Cast control port to open Cast Socket from DIAL sink.
-  static const int kCastControlPort;
+  static constexpr int kCastControlPort = 8009;
+  // TODO(zhaobin): Remove this when we switch to use max delay instead of max
+  // number of retry attempts to decide when to stop retry.
+  static constexpr int kMaxAttempts = 3;
+  // Initial delay (in seconds) used by backoff policy.
+  static constexpr int kDelayInSeconds = 15;
 
   CastMediaSinkServiceImpl(const OnSinksDiscoveredCallback& callback,
                            cast_channel::CastSocketService* cast_socket_service,
                            DiscoveryNetworkMonitor* network_monitor);
   ~CastMediaSinkServiceImpl() override;
 
+  void SetTaskRunnerForTest(
+      scoped_refptr<base::SequencedTaskRunner> task_runner);
+
   // MediaSinkService implementation
   void Start() override;
   void Stop() override;
@@ -55,15 +64,41 @@
 
  private:
   friend class CastMediaSinkServiceImplTest;
-  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnChannelOpened);
   FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
-                           TestMultipleOnChannelOpened);
+                           TestOnChannelOpenSucceeded);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestMultipleOnChannelOpenSucceeded);
   FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestTimer);
   FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOpenChannelNoRetry);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOpenChannelRetryOnce);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOpenChannelFails);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
                            TestMultipleOpenChannels);
-  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnChannelError);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOnChannelOpenFailed);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOnChannelErrorMayRetryForConnectingChannel);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOnChannelErrorMayRetryForCastSink);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           TestOnChannelErrorNoRetryForMissingSink);
   FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnDialSinkAdded);
   FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnFetchCompleted);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           CacheSinksForKnownNetwork);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           CacheContainsOnlyResolvedSinks);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           CacheUpdatedOnChannelOpenFailed);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, UnknownNetworkNoCache);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           CacheUpdatedForKnownNetwork);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           CacheDialDiscoveredSinks);
+  FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
+                           DualDiscoveryDoesntDuplicateCacheItems);
 
   // CastSocket::Observer implementation.
   void OnError(const cast_channel::CastSocket& socket,
@@ -77,18 +112,51 @@
   // Opens cast channel.
   // |ip_endpoint|: cast channel's target IP endpoint.
   // |cast_sink|: Cast sink created from mDNS service description or DIAL sink.
+  // |backoff_entry|: backoff entry passed to |OnChannelOpened| callback.
   void OpenChannel(const net::IPEndPoint& ip_endpoint,
-                   MediaSinkInternal cast_sink);
+                   const MediaSinkInternal& cast_sink,
+                   std::unique_ptr<net::BackoffEntry> backoff_entry);
 
   // Invoked when opening cast channel on IO thread completes.
   // |cast_sink|: Cast sink created from mDNS service description or DIAL sink.
+  // |backoff_entry|: backoff entry passed to |OnChannelErrorMayRetry| callback
+  // if open channel fails.
   // |socket|: raw pointer of newly created cast channel. Does not take
   // ownership of |socket|.
-  void OnChannelOpened(MediaSinkInternal cast_sink,
+  void OnChannelOpened(const MediaSinkInternal& cast_sink,
+                       std::unique_ptr<net::BackoffEntry> backoff_entry,
                        cast_channel::CastSocket* socket);
 
-  // Set of mDNS service IP endpoints from current round of discovery.
-  std::set<net::IPEndPoint> current_service_ip_endpoints_;
+  // Invoked by |OnChannelOpened| if opening cast channel failed. It will retry
+  // opening channel in a delay specified by |backoff_entry| if current failure
+  // count is less than max retry attempts. Or invoke |OnChannelError| if retry
+  // is not allowed.
+  // |cast_sink|: Cast sink created from mDNS service description or DIAL sink.
+  // |backoff_entry|: backoff entry holds failure count and calculates back-off
+  // for next retry.
+  // |error_state|: erorr encountered when opending cast channel.
+  void OnChannelErrorMayRetry(MediaSinkInternal cast_sink,
+                              std::unique_ptr<net::BackoffEntry> backoff_entry,
+                              cast_channel::ChannelError error_state);
+
+  // Invoked when opening cast channel on IO thread succeeds.
+  // |cast_sink|: Cast sink created from mDNS service description or DIAL sink.
+  // |socket|: raw pointer of newly created cast channel. Does not take
+  // ownership of |socket|.
+  void OnChannelOpenSucceeded(MediaSinkInternal cast_sink,
+                              cast_channel::CastSocket* socket);
+
+  // Invoked when opening cast channel on IO thread fails after all retry
+  // attempts.
+  // |ip_endpoint|: ip endpoint of cast channel failing to connect to.
+  void OnChannelOpenFailed(const net::IPEndPoint& ip_endpoint);
+
+  // Set of IP endpoints pending to be connected to.
+  std::set<net::IPEndPoint> pending_for_open_ip_endpoints_;
+
+  // Set of IP endpoints found in current round of mDNS service. Used by
+  // RecordDeviceCounts().
+  std::set<net::IPEndPoint> known_ip_endpoints_;
 
   using MediaSinkInternalMap = std::map<net::IPAddress, MediaSinkInternal>;
 
@@ -110,6 +178,14 @@
 
   CastDeviceCountMetrics metrics_;
 
+  // Default backoff policy to reopen Cast Socket when channel error occurs.
+  static const net::BackoffEntry::Policy kBackoffPolicy;
+
+  // Does not take ownership of |backoff_policy_|.
+  const net::BackoffEntry::Policy* backoff_policy_;
+
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(CastMediaSinkServiceImpl);
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
index cbe2c91a..5a05acf9 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/mock_callback.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/timer/mock_timer.h"
 #include "chrome/browser/media/router/test_helper.h"
 #include "components/cast_channel/cast_socket.h"
@@ -73,7 +74,8 @@
         mock_cast_socket_service_(new cast_channel::MockCastSocketService()),
         media_sink_service_impl_(mock_sink_discovered_cb_.Get(),
                                  mock_cast_socket_service_.get(),
-                                 discovery_network_monitor_.get()) {}
+                                 discovery_network_monitor_.get()),
+        mock_time_task_runner_(new base::TestMockTimeTaskRunner()) {}
 
   void SetUp() override {
     fake_network_info_.clear();
@@ -127,6 +129,7 @@
       mock_cast_socket_service_;
   CastMediaSinkServiceImpl media_sink_service_impl_;
   base::MockTimer* mock_timer_;
+  scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(CastMediaSinkServiceImplTest);
 };
@@ -135,14 +138,13 @@
 std::vector<DiscoveryNetworkInfo>
     CastMediaSinkServiceImplTest::fake_network_info_;
 
-TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpened) {
+TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
   auto cast_sink = CreateCastSink(1);
   net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
   cast_channel::MockCastSocket socket;
   socket.set_id(1);
 
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint1);
-  media_sink_service_impl_.OnChannelOpened(cast_sink, &socket);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink, &socket);
 
   // Verify sink content
   EXPECT_CALL(mock_sink_discovered_cb_,
@@ -150,7 +152,7 @@
   media_sink_service_impl_.OnFetchCompleted();
 }
 
-TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpened) {
+TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpenSucceeded) {
   auto cast_sink1 = CreateCastSink(1);
   auto cast_sink2 = CreateCastSink(2);
   auto cast_sink3 = CreateCastSink(3);
@@ -164,11 +166,9 @@
   socket3.set_id(3);
 
   // Current round of Dns discovery finds service1 and service 2.
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint1);
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint2);
   // Fail to open channel 1.
-  media_sink_service_impl_.OnChannelOpened(cast_sink2, &socket2);
-  media_sink_service_impl_.OnChannelOpened(cast_sink3, &socket3);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink2, &socket2);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink3, &socket3);
 
   // Verify sink content
   EXPECT_CALL(mock_sink_discovered_cb_,
@@ -190,8 +190,7 @@
   cast_channel::MockCastSocket socket2;
   socket2.set_id(2);
 
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint2);
-  media_sink_service_impl_.OnChannelOpened(cast_sink2, &socket2);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink2, &socket2);
 
   std::vector<MediaSinkInternal> sinks;
   EXPECT_CALL(mock_sink_discovered_cb_, Run(_)).WillOnce(SaveArg<0>(&sinks));
@@ -205,11 +204,93 @@
   cast_channel::MockCastSocket socket1;
   socket1.set_id(1);
 
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint1);
-  media_sink_service_impl_.OnChannelOpened(cast_sink1, &socket1);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink1, &socket1);
   EXPECT_TRUE(mock_timer_->IsRunning());
 }
 
+TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelNoRetry) {
+  MediaSinkInternal cast_sink = CreateCastSink(1);
+  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint);
+  socket.SetErrorState(cast_channel::ChannelError::NONE);
+
+  // No pending sink
+  EXPECT_CALL(*mock_cast_socket_service_,
+              OpenSocketInternal(ip_endpoint, _, _, _))
+      .Times(1);
+  media_sink_service_impl_.OpenChannel(ip_endpoint, cast_sink, nullptr);
+
+  // One pending sink, the same as |cast_sink|
+  EXPECT_CALL(*mock_cast_socket_service_,
+              OpenSocketInternal(ip_endpoint, _, _, _))
+      .Times(0);
+  media_sink_service_impl_.OpenChannel(ip_endpoint, cast_sink, nullptr);
+}
+
+TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelRetryOnce) {
+  MediaSinkInternal cast_sink = CreateCastSink(1);
+  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint);
+  socket.SetErrorState(cast_channel::ChannelError::NONE);
+  socket.SetErrorState(cast_channel::ChannelError::CAST_SOCKET_ERROR);
+
+  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
+  std::unique_ptr<net::BackoffEntry> backoff_entry(
+      new net::BackoffEntry(&CastMediaSinkServiceImpl::kBackoffPolicy));
+  ExpectOpenSocketInternal(&socket);
+  media_sink_service_impl_.OpenChannel(ip_endpoint, cast_sink,
+                                       std::move(backoff_entry));
+
+  socket.SetErrorState(cast_channel::ChannelError::NONE);
+  ExpectOpenSocketInternal(&socket);
+  // Wait for 16 seconds.
+  mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(16));
+}
+
+TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelFails) {
+  MediaSinkInternal cast_sink = CreateCastSink(1);
+  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint);
+  socket.SetErrorState(cast_channel::ChannelError::CAST_SOCKET_ERROR);
+
+  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
+
+  ExpectOpenSocketInternal(&socket);
+  net::BackoffEntry::Policy policy = CastMediaSinkServiceImpl::kBackoffPolicy;
+  std::unique_ptr<net::BackoffEntry> backoff_entry(
+      new net::BackoffEntry(&policy));
+  auto* backoff_entry_ptr = backoff_entry.get();
+  media_sink_service_impl_.OpenChannel(ip_endpoint, cast_sink,
+                                       std::move(backoff_entry));
+
+  // 1st retry attempt
+  ExpectOpenSocketInternal(&socket);
+  base::TimeDelta delay = backoff_entry_ptr->GetTimeUntilRelease() +
+                          base::TimeDelta::FromSeconds(1);
+  mock_time_task_runner_->FastForwardBy(delay);
+  // 2nd retry attempt
+  ExpectOpenSocketInternal(&socket);
+  delay = backoff_entry_ptr->GetTimeUntilRelease() +
+          base::TimeDelta::FromSeconds(1);
+  mock_time_task_runner_->FastForwardBy(delay);
+  // 3rd retry attempt
+  ExpectOpenSocketInternal(&socket);
+  delay = backoff_entry_ptr->GetTimeUntilRelease() +
+          base::TimeDelta::FromSeconds(1);
+  mock_time_task_runner_->FastForwardBy(delay);
+  // No more retry.
+  EXPECT_CALL(*mock_cast_socket_service_,
+              OpenSocketInternal(ip_endpoint, _, _, _))
+      .Times(0);
+  mock_time_task_runner_->FastForwardBy(delay);
+}
+
 TEST_F(CastMediaSinkServiceImplTest, TestMultipleOpenChannels) {
   auto cast_sink1 = CreateCastSink(1);
   auto cast_sink2 = CreateCastSink(2);
@@ -230,7 +311,8 @@
   // Channel 2 opened.
   cast_channel::MockCastSocket socket2;
   socket2.set_id(2);
-  media_sink_service_impl_.OnChannelOpened(cast_sink2, &socket2);
+  socket2.SetErrorState(cast_channel::ChannelError::NONE);
+  media_sink_service_impl_.OnChannelOpened(cast_sink2, nullptr, &socket2);
 
   EXPECT_CALL(*mock_cast_socket_service_,
               OpenSocketInternal(ip_endpoint2, _, _, _));
@@ -246,8 +328,10 @@
   cast_channel::MockCastSocket socket3;
   socket1.set_id(1);
   socket3.set_id(3);
-  media_sink_service_impl_.OnChannelOpened(cast_sink1, &socket1);
-  media_sink_service_impl_.OnChannelOpened(cast_sink3, &socket3);
+  socket1.SetErrorState(cast_channel::ChannelError::NONE);
+  socket3.SetErrorState(cast_channel::ChannelError::NONE);
+  media_sink_service_impl_.OnChannelOpened(cast_sink1, nullptr, &socket1);
+  media_sink_service_impl_.OnChannelOpened(cast_sink3, nullptr, &socket3);
 
   EXPECT_CALL(mock_sink_discovered_cb_,
               Run(std::vector<MediaSinkInternal>(
@@ -255,23 +339,87 @@
   media_sink_service_impl_.OnFetchCompleted();
 }
 
-TEST_F(CastMediaSinkServiceImplTest, TestOnChannelError) {
+TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) {
   auto cast_sink = CreateCastSink(1);
   net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
   cast_channel::MockCastSocket socket;
   socket.set_id(1);
 
-  media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint1);
-  media_sink_service_impl_.OnChannelOpened(cast_sink, &socket);
+  media_sink_service_impl_.OnChannelOpenSucceeded(cast_sink, &socket);
 
   EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_map_.size());
 
   socket.SetIPEndpoint(ip_endpoint1);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
+  EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty());
+}
+
+TEST_F(CastMediaSinkServiceImplTest,
+       TestOnChannelErrorMayRetryForConnectingChannel) {
+  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint1);
+
+  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
+
+  // No op for CONNECTING cast channel.
+  EXPECT_CALL(socket, ready_state())
+      .WillOnce(Return(cast_channel::ReadyState::CONNECTING));
+  EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _, _))
+      .Times(0);
+
   media_sink_service_impl_.OnError(
       socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);
+  mock_time_task_runner_->RunUntilIdle();
+}
+
+TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorMayRetryForCastSink) {
+  auto cast_sink = CreateCastSink(1);
+  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint1);
+
+  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
+
+  // There is an existing cast sink in |current_sinks_map_|.
+  media_sink_service_impl_.current_sinks_map_[ip_endpoint1.address()] =
+      cast_sink;
+  EXPECT_CALL(socket, ready_state())
+      .WillRepeatedly(Return(cast_channel::ReadyState::CLOSED));
+  media_sink_service_impl_.OnError(
+      socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);
+
+  EXPECT_CALL(*mock_cast_socket_service_,
+              OpenSocketInternal(ip_endpoint1, _, _, _));
+  mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(16));
   EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty());
 }
 
+TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorNoRetryForMissingSink) {
+  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
+  cast_channel::MockCastSocket socket;
+  socket.set_id(1);
+  socket.SetIPEndpoint(ip_endpoint1);
+  EXPECT_CALL(socket, ready_state())
+      .WillOnce(Return(cast_channel::ReadyState::CLOSED));
+
+  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
+
+  // There is no existing cast sink.
+  media_sink_service_impl_.pending_for_open_ip_endpoints_.clear();
+  media_sink_service_impl_.current_sinks_map_.clear();
+
+  media_sink_service_impl_.OnError(
+      socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);
+
+  EXPECT_CALL(*mock_cast_socket_service_,
+              OpenSocketInternal(ip_endpoint1, _, _, _))
+      .Times(0);
+  mock_time_task_runner_->RunUntilIdle();
+}
+
 TEST_F(CastMediaSinkServiceImplTest, TestOnDialSinkAdded) {
   MediaSinkInternal dial_sink1 = CreateDialSink(1);
   MediaSinkInternal dial_sink2 = CreateDialSink(2);
@@ -373,8 +521,8 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_WIFI);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
-  observer().OnError(socket2, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
 
   MediaSinkInternal sink3 = CreateCastSink(3);
   net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
@@ -437,7 +585,7 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_WIFI);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
 
   MediaSinkInternal sink3 = CreateCastSink(3);
   net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
@@ -467,7 +615,7 @@
   content::RunAllBlockingPoolTasksUntilIdle();
 }
 
-TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelError) {
+TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
   fake_network_info_ = fake_ethernet_info_;
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_ETHERNET);
@@ -484,7 +632,7 @@
   socket1.set_id(1);
   ExpectOpenSocketInternal(&socket1);
   media_sink_service_impl_.OpenChannels(sink_list1);
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
 
   // Connect to a new network with different sinks.
   fake_network_info_.clear();
@@ -548,8 +696,8 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_NONE);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
-  observer().OnError(socket2, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
 
   MediaSinkInternal sink3 = CreateCastSink(3);
   net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
@@ -610,8 +758,8 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_WIFI);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
-  observer().OnError(socket2, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
 
   MediaSinkInternal sink3 = CreateCastSink(3);
   net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
@@ -630,7 +778,7 @@
       net::NetworkChangeNotifier::CONNECTION_NONE);
   content::RunAllBlockingPoolTasksUntilIdle();
 
-  observer().OnError(socket3, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3);
 
   // Resolution will fail for cached sinks.
   socket1.SetErrorState(cast_channel::ChannelError::CONNECT_ERROR);
@@ -658,7 +806,7 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_NONE);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket4, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4);
 
   // Reconnect and expect only |sink4| to be cached.
   EXPECT_CALL(*mock_cast_socket_service_,
@@ -704,8 +852,8 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_WIFI);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1, cast_channel::ChannelError::CAST_SOCKET_ERROR);
-  observer().OnError(socket2, cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
 
   MediaSinkInternal sink3_cast = CreateCastSink(3);
   MediaSinkInternal sink4_dial = CreateDialSink(4);
@@ -780,10 +928,8 @@
   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
       net::NetworkChangeNotifier::CONNECTION_WIFI);
   content::RunAllBlockingPoolTasksUntilIdle();
-  observer().OnError(socket1_cast,
-                     cast_channel::ChannelError::CAST_SOCKET_ERROR);
-  observer().OnError(socket1_dial,
-                     cast_channel::ChannelError::CAST_SOCKET_ERROR);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast);
+  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial);
 
   MediaSinkInternal sink2_cast = CreateCastSink(2);
   net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
diff --git a/chrome/browser/notifications/extension_welcome_notification.cc b/chrome/browser/notifications/extension_welcome_notification.cc
deleted file mode 100644
index dd6f377..0000000
--- a/chrome/browser/notifications/extension_welcome_notification.cc
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/notifications/extension_welcome_notification.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/guid.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/notifications/notification.h"
-#include "chrome/browser/prefs/pref_service_syncable_util.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_navigator_params.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "chrome/grit/theme_resources.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/prefs/pref_service.h"
-#include "components/sync_preferences/pref_service_syncable.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_delegate.h"
-#include "ui/message_center/notification_types.h"
-
-const int ExtensionWelcomeNotification::kRequestedShowTimeDays = 14;
-const char ExtensionWelcomeNotification::kChromeNowExtensionID[] =
-    "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
-
-namespace {
-
-class NotificationCallbacks
-    : public message_center::NotificationDelegate {
- public:
-  NotificationCallbacks(
-      Profile* profile,
-      const message_center::NotifierId notifier_id,
-      const std::string& welcome_notification_id,
-      ExtensionWelcomeNotification::Delegate* delegate)
-      : profile_(profile),
-        notifier_id_(notifier_id.type, notifier_id.id),
-        welcome_notification_id_(welcome_notification_id),
-        delegate_(delegate) {
-  }
-
-  // Overridden from NotificationDelegate:
-  void Close(bool by_user) override {
-    if (by_user) {
-      // Setting the preference here may cause the notification erasing
-      // to reenter. Posting a task avoids this issue.
-      delegate_->PostTask(
-          FROM_HERE,
-          base::Bind(&NotificationCallbacks::MarkAsDismissed, this));
-    }
-  }
-
-  void ButtonClick(int index) override {
-    if (index == 0) {
-      OpenNotificationLearnMoreTab();
-    } else if (index == 1) {
-      DisableNotificationProvider();
-      Close(true);
-    } else {
-      NOTREACHED();
-    }
-  }
-
- private:
-  void MarkAsDismissed() {
-    profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissedLocal,
-                                     true);
-  }
-
-  void OpenNotificationLearnMoreTab() {
-    chrome::NavigateParams params(
-        profile_,
-        GURL(chrome::kNotificationWelcomeLearnMoreURL),
-        ui::PAGE_TRANSITION_LINK);
-    params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
-    params.window_action = chrome::NavigateParams::SHOW_WINDOW;
-    chrome::Navigate(&params);
-  }
-
-  void DisableNotificationProvider() {
-    message_center::Notifier notifier(notifier_id_, base::string16(), true);
-    message_center::MessageCenter* message_center =
-        delegate_->GetMessageCenter();
-    message_center->DisableNotificationsByNotifier(notifier_id_);
-    message_center->RemoveNotification(welcome_notification_id_, false);
-    message_center->GetNotifierSettingsProvider()->SetNotifierEnabled(
-        notifier, false);
-  }
-
-  ~NotificationCallbacks() override {}
-
-  Profile* const profile_;
-
-  const message_center::NotifierId notifier_id_;
-
-  std::string welcome_notification_id_;
-
-  // Weak ref owned by ExtensionWelcomeNotification.
-  ExtensionWelcomeNotification::Delegate* const delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationCallbacks);
-};
-
-class DefaultDelegate : public ExtensionWelcomeNotification::Delegate {
- public:
-  DefaultDelegate() {}
-
-  message_center::MessageCenter* GetMessageCenter() override {
-    return g_browser_process->message_center();
-  }
-
-  base::Time GetCurrentTime() override { return base::Time::Now(); }
-
-  void PostTask(const tracked_objects::Location& from_here,
-                const base::Closure& task) override {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, task);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
-};
-
-}  // namespace
-
-ExtensionWelcomeNotification::ExtensionWelcomeNotification(
-    Profile* const profile,
-    ExtensionWelcomeNotification::Delegate* const delegate)
-    : notifier_id_(message_center::NotifierId::APPLICATION,
-          kChromeNowExtensionID),
-      profile_(profile),
-      delegate_(delegate) {
-  welcome_notification_dismissed_pref_.Init(
-      prefs::kWelcomeNotificationDismissed,
-      profile_->GetPrefs(),
-      base::Bind(
-          &ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged,
-          base::Unretained(this)));
-  welcome_notification_dismissed_local_pref_.Init(
-      prefs::kWelcomeNotificationDismissedLocal,
-      profile_->GetPrefs());
-}
-
-// static
-ExtensionWelcomeNotification* ExtensionWelcomeNotification::Create(
-    Profile* const profile) {
-  return Create(profile, new DefaultDelegate());
-}
-
-// static
-ExtensionWelcomeNotification* ExtensionWelcomeNotification::Create(
-    Profile* const profile, Delegate* const delegate) {
-  return new ExtensionWelcomeNotification(profile, delegate);
-}
-
-ExtensionWelcomeNotification::~ExtensionWelcomeNotification() {
-  if (delayed_notification_) {
-    delayed_notification_.reset();
-    PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this);
-  } else {
-    HideWelcomeNotification();
-  }
-}
-
-void ExtensionWelcomeNotification::OnIsSyncingChanged() {
-  DCHECK(delayed_notification_);
-  sync_preferences::PrefServiceSyncable* const pref_service_syncable =
-      PrefServiceSyncableFromProfile(profile_);
-  if (pref_service_syncable->IsSyncing()) {
-    pref_service_syncable->RemoveObserver(this);
-    std::unique_ptr<Notification> previous_notification(
-        delayed_notification_.release());
-    ShowWelcomeNotificationIfNecessary(*(previous_notification.get()));
-  }
-}
-
-void ExtensionWelcomeNotification::ShowWelcomeNotificationIfNecessary(
-    const Notification& notification) {
-  if ((notification.notifier_id() == notifier_id_) && !delayed_notification_) {
-    sync_preferences::PrefServiceSyncable* const pref_service_syncable =
-        PrefServiceSyncableFromProfile(profile_);
-    if (pref_service_syncable->IsSyncing()) {
-      PrefService* const pref_service = profile_->GetPrefs();
-      if (!UserHasDismissedWelcomeNotification()) {
-        const PopUpRequest pop_up_request =
-            pref_service->GetBoolean(
-                prefs::kWelcomeNotificationPreviouslyPoppedUp)
-                ? POP_UP_HIDDEN
-                : POP_UP_SHOWN;
-        if (pop_up_request == POP_UP_SHOWN) {
-          pref_service->SetBoolean(
-              prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
-        }
-
-        if (IsWelcomeNotificationExpired()) {
-          ExpireWelcomeNotification();
-        } else {
-          ShowWelcomeNotification(
-              notification.display_source(), pop_up_request);
-        }
-      }
-    } else {
-      delayed_notification_.reset(new Notification(notification));
-      pref_service_syncable->AddObserver(this);
-    }
-  }
-}
-
-// static
-void ExtensionWelcomeNotification::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* prefs) {
-  prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissed,
-                             false,
-                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-  prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissedLocal, false);
-  prefs->RegisterBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp,
-                             false);
-  prefs->RegisterInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp, 0);
-}
-
-message_center::MessageCenter*
-ExtensionWelcomeNotification::GetMessageCenter() const {
-  return delegate_->GetMessageCenter();
-}
-
-void ExtensionWelcomeNotification::ShowWelcomeNotification(
-    const base::string16& display_source,
-    const PopUpRequest pop_up_request) {
-  message_center::ButtonInfo learn_more(
-      l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE));
-  learn_more.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-      IDR_NOTIFICATION_WELCOME_LEARN_MORE);
-  message_center::ButtonInfo disable(
-      l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BUTTON));
-  disable.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-      IDR_NOTIFIER_BLOCK_BUTTON);
-
-  message_center::RichNotificationData rich_notification_data;
-  rich_notification_data.priority = 2;
-  rich_notification_data.buttons.push_back(learn_more);
-  rich_notification_data.buttons.push_back(disable);
-
-  if (welcome_notification_id_.empty())
-    welcome_notification_id_ = base::GenerateGUID();
-
-  if (!welcome_notification_id_.empty()) {
-    std::unique_ptr<message_center::Notification> message_center_notification(
-        new message_center::Notification(
-            message_center::NOTIFICATION_TYPE_BASE_FORMAT,
-            welcome_notification_id_,
-            l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_TITLE),
-            l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BODY),
-            ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-                IDR_NOTIFICATION_WELCOME_ICON),
-            display_source, GURL(), notifier_id_, rich_notification_data,
-            new NotificationCallbacks(profile_, notifier_id_,
-                                      welcome_notification_id_,
-                                      delegate_.get())));
-
-    if (pop_up_request == POP_UP_HIDDEN)
-      message_center_notification->set_shown_as_popup(true);
-
-    GetMessageCenter()->AddNotification(std::move(message_center_notification));
-    StartExpirationTimer();
-  }
-}
-
-void ExtensionWelcomeNotification::HideWelcomeNotification() {
-  if (!welcome_notification_id_.empty() &&
-      GetMessageCenter()->FindVisibleNotificationById(
-          welcome_notification_id_) != NULL) {
-    GetMessageCenter()->RemoveNotification(welcome_notification_id_, false);
-    StopExpirationTimer();
-  }
-}
-
-bool ExtensionWelcomeNotification::UserHasDismissedWelcomeNotification() const {
-  // This was previously a syncable preference; now it's per-machine.
-  // Only the local pref will be written moving forward, but check for both so
-  // users won't be double-toasted.
-  bool shown_synced = profile_->GetPrefs()->GetBoolean(
-      prefs::kWelcomeNotificationDismissed);
-  bool shown_local = profile_->GetPrefs()->GetBoolean(
-      prefs::kWelcomeNotificationDismissedLocal);
-  return (shown_synced || shown_local);
-}
-
-void ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged() {
-  if (UserHasDismissedWelcomeNotification()) {
-    HideWelcomeNotification();
-  }
-}
-
-void ExtensionWelcomeNotification::StartExpirationTimer() {
-  if (!expiration_timer_ && !IsWelcomeNotificationExpired()) {
-    base::Time expiration_timestamp = GetExpirationTimestamp();
-    if (expiration_timestamp.is_null()) {
-      SetExpirationTimestampFromNow();
-      expiration_timestamp = GetExpirationTimestamp();
-      DCHECK(!expiration_timestamp.is_null());
-    }
-    expiration_timer_.reset(new base::OneShotTimer());
-    expiration_timer_->Start(
-        FROM_HERE,
-        expiration_timestamp - delegate_->GetCurrentTime(),
-        this,
-        &ExtensionWelcomeNotification::ExpireWelcomeNotification);
-  }
-}
-
-void ExtensionWelcomeNotification::StopExpirationTimer() {
-  if (expiration_timer_) {
-    expiration_timer_->Stop();
-    expiration_timer_.reset();
-  }
-}
-
-void ExtensionWelcomeNotification::ExpireWelcomeNotification() {
-  DCHECK(IsWelcomeNotificationExpired());
-  profile_->GetPrefs()->SetBoolean(
-      prefs::kWelcomeNotificationDismissedLocal, true);
-  HideWelcomeNotification();
-}
-
-base::Time ExtensionWelcomeNotification::GetExpirationTimestamp() const {
-  PrefService* const pref_service = profile_->GetPrefs();
-  const int64_t expiration_timestamp =
-      pref_service->GetInt64(prefs::kWelcomeNotificationExpirationTimestamp);
-  return (expiration_timestamp == 0)
-      ? base::Time()
-      : base::Time::FromInternalValue(expiration_timestamp);
-}
-
-void ExtensionWelcomeNotification::SetExpirationTimestampFromNow() {
-  PrefService* const pref_service = profile_->GetPrefs();
-  pref_service->SetInt64(
-      prefs::kWelcomeNotificationExpirationTimestamp,
-      (delegate_->GetCurrentTime() +
-          base::TimeDelta::FromDays(kRequestedShowTimeDays)).ToInternalValue());
-}
-
-bool ExtensionWelcomeNotification::IsWelcomeNotificationExpired() const {
-  const base::Time expiration_timestamp = GetExpirationTimestamp();
-  return !expiration_timestamp.is_null() &&
-         (expiration_timestamp <= delegate_->GetCurrentTime());
-}
diff --git a/chrome/browser/notifications/extension_welcome_notification.h b/chrome/browser/notifications/extension_welcome_notification.h
deleted file mode 100644
index 8cec180..0000000
--- a/chrome/browser/notifications/extension_welcome_notification.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_
-#define CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/timer/timer.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/prefs/pref_member.h"
-#include "components/sync_preferences/pref_service_syncable_observer.h"
-#include "ui/message_center/notifier_settings.h"
-
-namespace base {
-typedef Callback<void(void)> Closure;
-}
-
-namespace message_center {
-class MessageCenter;
-}
-
-namespace tracked_objects {
-class Location;
-}
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
-class Notification;
-class Profile;
-
-// ExtensionWelcomeNotification is a keyed service which manages showing and
-// hiding a welcome notification for built-in components that show
-// notifications. The Welcome Notification presumes network connectivity since
-// it relies on synced preferences to work. This is generally fine since the
-// current consumers on the welcome notification also presume network
-// connectivity.
-//
-// This class expects to be created and called from the UI thread.
-class ExtensionWelcomeNotification
-    : public KeyedService,
-      public sync_preferences::PrefServiceSyncableObserver {
- public:
-  // Allows for overriding global calls.
-  class Delegate {
-   public:
-    Delegate() {}
-    virtual ~Delegate() {}
-    virtual message_center::MessageCenter* GetMessageCenter() = 0;
-    virtual base::Time GetCurrentTime() = 0;
-    virtual void PostTask(
-        const tracked_objects::Location& from_here,
-        const base::Closure& task) = 0;
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Delegate);
-  };
-
-  // Requested time from showing the welcome notification to expiration.
-  static const int kRequestedShowTimeDays;
-
-  // The extension Id associated with the Google Now extension.
-  static const char kChromeNowExtensionID[];
-
-  ~ExtensionWelcomeNotification() override;
-
-  // To workaround the lack of delegating constructors prior to C++11, we use
-  // static Create methods.
-  // Creates an ExtensionWelcomeNotification with the default delegate.
-  static ExtensionWelcomeNotification* Create(Profile* const profile);
-
-  // Creates an ExtensionWelcomeNotification with the specified delegate.
-  static ExtensionWelcomeNotification* Create(Profile* const profile,
-                                              Delegate* const delegate);
-
-  // sync_preferences::PrefServiceSyncableObserver
-  void OnIsSyncingChanged() override;
-
-  // Adds in the welcome notification if required for components built
-  // into Chrome that show notifications like Chrome Now.
-  void ShowWelcomeNotificationIfNecessary(const Notification& notification);
-
-  // Handles Preference Registration for the Welcome Notification.
-  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);
-
- private:
-  enum PopUpRequest { POP_UP_HIDDEN = 0, POP_UP_SHOWN = 1, };
-
-  ExtensionWelcomeNotification(
-      Profile* const profile,
-      ExtensionWelcomeNotification::Delegate* const delegate);
-
-  // Gets the message center from the delegate.
-  message_center::MessageCenter* GetMessageCenter() const;
-
-  // Unconditionally shows the welcome notification.
-  void ShowWelcomeNotification(const base::string16& display_source,
-                               const PopUpRequest pop_up_request);
-
-  // Hides the welcome notification.
-  void HideWelcomeNotification();
-
-  // Whether the notification has been dismissed.
-  bool UserHasDismissedWelcomeNotification() const;
-
-  // Called when the Welcome Notification Dismissed pref has been changed.
-  void OnWelcomeNotificationDismissedChanged();
-
-  // Starts the welcome notification expiration timer.
-  void StartExpirationTimer();
-
-  // Stops the welcome notification expiration timer.
-  void StopExpirationTimer();
-
-  // Expires the welcome notification by hiding it and marking it dismissed.
-  void ExpireWelcomeNotification();
-
-  // Gets the expiration timestamp or a null time is there is none.
-  base::Time GetExpirationTimestamp() const;
-
-  // Sets the expiration timestamp from now.
-  void SetExpirationTimestampFromNow();
-
-  // True if the welcome notification has expired, false otherwise.
-  bool IsWelcomeNotificationExpired() const;
-
-  // Prefs listener for welcome_notification_dismissed.
-  BooleanPrefMember welcome_notification_dismissed_pref_;
-
-  // Prefs listener for welcome_notification_dismissed_local.
-  // Dismissal flag migrated from a synced pref to a local one.
-  BooleanPrefMember welcome_notification_dismissed_local_pref_;
-
-  // The notifier for the extension that we're listening for.
-  message_center::NotifierId notifier_id_;
-
-  // The profile which owns this object.
-  Profile* profile_;
-
-  // Notification ID of the Welcome Notification.
-  std::string welcome_notification_id_;
-
-  // If the preferences are still syncing, store the last notification here
-  // so we can replay ShowWelcomeNotificationIfNecessary once the sync finishes.
-  // Simplifying Assumption: The delayed notification has passed the
-  // extension ID check. This means we do not need to store all of the
-  // notifications that may also show a welcome notification.
-  std::unique_ptr<Notification> delayed_notification_;
-
-  // If the welcome notification is shown, this timer tracks when to hide the
-  // welcome notification.
-  std::unique_ptr<base::OneShotTimer> expiration_timer_;
-
-  // Delegate for Chrome global calls like base::Time::GetTime() for
-  // testability.
-  std::unique_ptr<Delegate> delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionWelcomeNotification);
-};
-
-#endif  // CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_
diff --git a/chrome/browser/notifications/extension_welcome_notification_factory.cc b/chrome/browser/notifications/extension_welcome_notification_factory.cc
deleted file mode 100644
index 0402eb6..0000000
--- a/chrome/browser/notifications/extension_welcome_notification_factory.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/notifications/extension_welcome_notification_factory.h"
-
-#include "chrome/browser/notifications/extension_welcome_notification.h"
-#include "chrome/browser/notifications/notifier_state_tracker_factory.h"
-#include "chrome/browser/profiles/incognito_helpers.h"
-#include "chrome/browser/profiles/profile.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "content/public/browser/browser_thread.h"
-
-// static
-ExtensionWelcomeNotification*
-ExtensionWelcomeNotificationFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  return static_cast<ExtensionWelcomeNotification*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-// static
-ExtensionWelcomeNotificationFactory*
-ExtensionWelcomeNotificationFactory::GetInstance() {
-  return base::Singleton<ExtensionWelcomeNotificationFactory>::get();
-}
-
-ExtensionWelcomeNotificationFactory::ExtensionWelcomeNotificationFactory()
-    : BrowserContextKeyedServiceFactory(
-        "ExtensionWelcomeNotification",
-        BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(NotifierStateTrackerFactory::GetInstance());
-}
-
-ExtensionWelcomeNotificationFactory::~ExtensionWelcomeNotificationFactory() {}
-
-KeyedService* ExtensionWelcomeNotificationFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  return ExtensionWelcomeNotification::Create(static_cast<Profile*>(context));
-}
-
-content::BrowserContext*
-ExtensionWelcomeNotificationFactory::GetBrowserContextToUse(
-    content::BrowserContext* context) const {
-  return chrome::GetBrowserContextOwnInstanceInIncognito(context);
-}
diff --git a/chrome/browser/notifications/extension_welcome_notification_factory.h b/chrome/browser/notifications/extension_welcome_notification_factory.h
deleted file mode 100644
index 723bbb3..0000000
--- a/chrome/browser/notifications/extension_welcome_notification_factory.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_FACTORY_H_
-#define CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_FACTORY_H_
-
-#include "base/memory/singleton.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-class ExtensionWelcomeNotification;
-
-// Singleton owning the extension welcome notification objects and associates
-// them with the browser context for which they may have to be shown.
-class ExtensionWelcomeNotificationFactory
-    : public BrowserContextKeyedServiceFactory {
- public:
-  // Returns the ExtensionWelcomeNotification instance to be used for |context|.
-  static ExtensionWelcomeNotification* GetForBrowserContext(
-      content::BrowserContext* context);
-
-  static ExtensionWelcomeNotificationFactory* GetInstance();
-
- private:
-  friend struct base::DefaultSingletonTraits<
-      ExtensionWelcomeNotificationFactory>;
-
-  ExtensionWelcomeNotificationFactory();
-  ~ExtensionWelcomeNotificationFactory() override;
-
-  // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const override;
-  content::BrowserContext* GetBrowserContextToUse(
-      content::BrowserContext* context) const override;
-};
-
-#endif  // CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_FACTORY_H_
diff --git a/chrome/browser/notifications/extension_welcome_notification_unittest.cc b/chrome/browser/notifications/extension_welcome_notification_unittest.cc
deleted file mode 100644
index acaf8e8..0000000
--- a/chrome/browser/notifications/extension_welcome_notification_unittest.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/notifications/extension_welcome_notification.h"
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/notifications/notification.h"
-#include "chrome/browser/prefs/pref_service_syncable_util.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/prefs/pref_service.h"
-#include "components/sync/model/fake_sync_change_processor.h"
-#include "components/sync/model/sync_error_factory_mock.h"
-#include "components/sync_preferences/testing_pref_service_syncable.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "extensions/browser/quota_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/message_center/fake_message_center.h"
-#include "ui/message_center/notification.h"
-
-class MockMessageCenter : public message_center::FakeMessageCenter {
- public:
-  MockMessageCenter()
-      : add_notification_calls_(0),
-        remove_notification_calls_(0),
-        notifications_with_shown_as_popup_(0) {
-  }
-
-  int add_notification_calls() { return add_notification_calls_; }
-  int remove_notification_calls() { return remove_notification_calls_; }
-  int notifications_with_shown_as_popup() {
-    return notifications_with_shown_as_popup_;
-  }
-
-  // message_center::FakeMessageCenter Overrides
-  message_center::Notification* FindVisibleNotificationById(
-      const std::string& id) override {
-    if (last_notification.get() && last_notification->id() == id)
-      return last_notification.get();
-    return NULL;
-  }
-
-  void AddNotification(
-      std::unique_ptr<message_center::Notification> notification) override {
-    EXPECT_FALSE(last_notification.get());
-    last_notification.swap(notification);
-    add_notification_calls_++;
-    if (last_notification->shown_as_popup())
-      notifications_with_shown_as_popup_++;
-  }
-
-  void RemoveNotification(const std::string& id, bool by_user) override {
-    EXPECT_TRUE(last_notification.get());
-    last_notification.reset();
-    remove_notification_calls_++;
-  }
-
-  void CloseCurrentNotification() {
-    EXPECT_TRUE(last_notification.get());
-    last_notification->delegate()->Close(true);
-    RemoveNotification(last_notification->id(), true);
-  }
-
- private:
-  std::unique_ptr<message_center::Notification> last_notification;
-  int add_notification_calls_;
-  int remove_notification_calls_;
-  int notifications_with_shown_as_popup_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
-};
-
-class WelcomeNotificationDelegate
-    : public ExtensionWelcomeNotification::Delegate {
-public:
-  WelcomeNotificationDelegate()
-      : start_time_(base::Time::Now()),
-        message_center_(new MockMessageCenter()) {
-  }
-
-  // ExtensionWelcomeNotification::Delegate
-  message_center::MessageCenter* GetMessageCenter() override {
-    return message_center_.get();
-  }
-
-  base::Time GetCurrentTime() override { return start_time_ + elapsed_time_; }
-
-  void PostTask(const tracked_objects::Location& from_here,
-                const base::Closure& task) override {
-    EXPECT_TRUE(pending_task_.is_null());
-    pending_task_ = task;
-  }
-
-  // WelcomeNotificationDelegate
-  MockMessageCenter* message_center() const { return message_center_.get(); }
-
-  base::Time GetStartTime() const { return start_time_; }
-
-  void SetElapsedTime(base::TimeDelta elapsed_time) {
-    elapsed_time_ = elapsed_time;
-  }
-
-  void RunPendingTask() {
-    base::Closure task_to_run = pending_task_;
-    pending_task_.Reset();
-    task_to_run.Run();
-  }
-
- private:
-  const base::Time start_time_;
-  base::TimeDelta elapsed_time_;
-  std::unique_ptr<MockMessageCenter> message_center_;
-  base::Closure pending_task_;
-
-  DISALLOW_COPY_AND_ASSIGN(WelcomeNotificationDelegate);
-};
-
-class ExtensionWelcomeNotificationTest : public testing::Test {
- protected:
-  ExtensionWelcomeNotificationTest() {
-    scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry(
-        new user_prefs::PrefRegistrySyncable());
-    ExtensionWelcomeNotification::RegisterProfilePrefs(pref_registry.get());
-  }
-
-  void SetUp() override {
-    task_runner_ = new base::TestSimpleTaskRunner();
-    base::MessageLoop::current()->SetTaskRunner(task_runner_);
-    profile_.reset(new TestingProfile());
-    task_runner()->RunUntilIdle();
-    delegate_ = new WelcomeNotificationDelegate();
-    welcome_notification_.reset(
-        ExtensionWelcomeNotification::Create(profile_.get(), delegate_));
-  }
-
-  void TearDown() override {
-    delegate_ = NULL;
-    welcome_notification_.reset();
-    profile_.reset();
-    TestingBrowserProcess::DeleteInstance();
-    task_runner_ = NULL;
-  }
-
-  void StartPreferenceSyncing() const {
-    PrefServiceSyncableFromProfile(profile_.get())
-        ->GetSyncableService(syncer::PREFERENCES)
-        ->MergeDataAndStartSyncing(syncer::PREFERENCES, syncer::SyncDataList(),
-                                   std::unique_ptr<syncer::SyncChangeProcessor>(
-                                       new syncer::FakeSyncChangeProcessor),
-                                   std::unique_ptr<syncer::SyncErrorFactory>(
-                                       new syncer::SyncErrorFactoryMock()));
-  }
-
-  void ShowChromeNowNotification() const {
-    ShowNotification(
-        "ChromeNowNotification",
-        message_center::NotifierId(
-            message_center::NotifierId::APPLICATION,
-            ExtensionWelcomeNotification::kChromeNowExtensionID));
-  }
-
-  void ShowRegularNotification() const {
-    ShowNotification(
-        "RegularNotification",
-        message_center::NotifierId(message_center::NotifierId::APPLICATION,
-                                   "aaaabbbbccccddddeeeeffffggghhhhi"));
-  }
-
-  void FlushMessageLoop() { delegate_->RunPendingTask(); }
-
-  MockMessageCenter* message_center() const {
-    return delegate_->message_center();
-  }
-  base::TestSimpleTaskRunner* task_runner() const {
-    return task_runner_.get();
-  }
-  base::Time GetStartTime() const {
-    return delegate_->GetStartTime();
-  }
-  void SetElapsedTime(base::TimeDelta elapsed_time) const {
-    delegate_->SetElapsedTime(elapsed_time);
-  }
-  bool GetBooleanPref(const char* path) const {
-    return profile_->GetPrefs()->GetBoolean(path);
-  }
-  void SetBooleanPref(const char* path, bool value) const {
-    profile_->GetPrefs()->SetBoolean(path, value);
-  }
-  int64_t GetInt64Pref(const char* path) const {
-    return profile_->GetPrefs()->GetInt64(path);
-  }
-  void SetInt64Pref(const char* path, int64_t value) const {
-    profile_->GetPrefs()->SetInt64(path, value);
-  }
-
- private:
-  class TestNotificationDelegate : public NotificationDelegate {
-   public:
-    explicit TestNotificationDelegate(const std::string& id) : id_(id) {}
-
-    // Overridden from NotificationDelegate:
-    std::string id() const override { return id_; }
-
-   private:
-    ~TestNotificationDelegate() override {}
-
-    const std::string id_;
-
-    DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate);
-  };
-
-  void ShowNotification(std::string notification_id,
-                        const message_center::NotifierId& notifier_id) const {
-    message_center::RichNotificationData rich_notification_data;
-    rich_notification_data.priority = 0;
-    Notification notification(
-        message_center::NOTIFICATION_TYPE_BASE_FORMAT,
-        base::UTF8ToUTF16("Title"), base::UTF8ToUTF16("Body"), gfx::Image(),
-        notifier_id, base::UTF8ToUTF16("Source"), GURL("http://tests.url"),
-        notification_id, rich_notification_data,
-        new TestNotificationDelegate("TestNotification"));
-    welcome_notification_->ShowWelcomeNotificationIfNecessary(notification);
-  }
-
-  content::TestBrowserThreadBundle thread_bundle_;
-  extensions::QuotaService::ScopedDisablePurgeForTesting
-      disable_purge_for_testing_;
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  std::unique_ptr<TestingProfile> profile_;
-  // Weak Ref owned by welcome_notification_
-  WelcomeNotificationDelegate* delegate_;
-  std::unique_ptr<ExtensionWelcomeNotification> welcome_notification_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionWelcomeNotificationTest);
-};
-
-// Show a regular notification. Expect that WelcomeNotification will
-// not show a welcome notification.
-TEST_F(ExtensionWelcomeNotificationTest, FirstRunShowRegularNotification) {
-  StartPreferenceSyncing();
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowRegularNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Show a Chrome Now notification. Expect that WelcomeNotification will
-// show a welcome notification.
-TEST_F(ExtensionWelcomeNotificationTest, FirstRunChromeNowNotification) {
-  StartPreferenceSyncing();
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Show a Chrome Now notification that was already shown before.
-TEST_F(ExtensionWelcomeNotificationTest, ShowWelcomeNotificationAgain) {
-  StartPreferenceSyncing();
-  SetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 1);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Don't show a welcome notification if it was previously dismissed on another
-// machine that wrote the synced flag.
-TEST_F(ExtensionWelcomeNotificationTest,
-       WelcomeNotificationPreviouslyDismissed) {
-  StartPreferenceSyncing();
-  SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Don't show a welcome notification if it was previously dismissed on this
-// machine.
-TEST_F(ExtensionWelcomeNotificationTest,
-       WelcomeNotificationPreviouslyDismissedLocal) {
-  StartPreferenceSyncing();
-  SetBooleanPref(prefs::kWelcomeNotificationDismissedLocal, true);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Don't show a welcome notification if it was previously dismissed with the
-// local flag and synced flag. This case is possible but rare.
-TEST_F(ExtensionWelcomeNotificationTest,
-       WelcomeNotificationPreviouslyDismissedSyncedAndLocal) {
-  StartPreferenceSyncing();
-  SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
-  SetBooleanPref(prefs::kWelcomeNotificationDismissedLocal, true);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Show a Chrome Now notification and dismiss it.
-// Expect welcome toast dismissed to be true.
-TEST_F(ExtensionWelcomeNotificationTest, DismissWelcomeNotification) {
-  StartPreferenceSyncing();
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-  message_center()->CloseCurrentNotification();
-  FlushMessageLoop();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 1);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Show a Chrome Now notification and dismiss it via a synced preference change.
-// Expect welcome toast dismissed to be true.
-TEST_F(ExtensionWelcomeNotificationTest, SyncedDismissalWelcomeNotification) {
-  StartPreferenceSyncing();
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-  SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 1);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Simulate a delayed preference sync when the welcome notification was
-// previously dismissed.
-TEST_F(ExtensionWelcomeNotificationTest,
-       DelayedPreferenceSyncPreviouslyDismissed) {
-  // Show a notification while the preference system is not syncing.
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  // Now start the preference syncing with a previously dismissed welcome.
-  SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  StartPreferenceSyncing();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Simulate a delayed preference sync when the welcome notification was
-// never shown.
-TEST_F(ExtensionWelcomeNotificationTest, DelayedPreferenceSyncNeverShown) {
-  // Show a notification while the preference system is not syncing.
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  ShowChromeNowNotification();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  // Now start the preference syncing with the default preference values.
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-
-  StartPreferenceSyncing();
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-}
-
-// Simulate the passage of time when the welcome notification
-// automatically dismisses.
-TEST_F(ExtensionWelcomeNotificationTest, TimeExpiredNotification) {
-  StartPreferenceSyncing();
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-  EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 0);
-  EXPECT_FALSE(task_runner()->HasPendingTask());
-
-  ShowChromeNowNotification();
-
-  base::TimeDelta requested_show_time =
-      base::TimeDelta::FromDays(
-          ExtensionWelcomeNotification::kRequestedShowTimeDays);
-
-  EXPECT_EQ(task_runner()->NumPendingTasks(), 1U);
-  EXPECT_EQ(task_runner()->NextPendingTaskDelay(), requested_show_time);
-
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-  EXPECT_EQ(
-      GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp),
-      (GetStartTime() + requested_show_time).ToInternalValue());
-
-  SetElapsedTime(requested_show_time);
-  task_runner()->RunPendingTasks();
-
-  EXPECT_FALSE(task_runner()->HasPendingTask());
-  EXPECT_EQ(message_center()->add_notification_calls(), 1);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 1);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-  EXPECT_EQ(
-      GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp),
-      (GetStartTime() + requested_show_time).ToInternalValue());
-}
-
-// Simulate the passage of time after Chrome is closed and the welcome
-// notification expiration elapses.
-TEST_F(ExtensionWelcomeNotificationTest, NotificationPreviouslyExpired) {
-  StartPreferenceSyncing();
-  SetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
-  SetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp, 1);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-  EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 1);
-  EXPECT_FALSE(task_runner()->HasPendingTask());
-
-  const base::TimeDelta requested_show_time =
-      base::TimeDelta::FromDays(
-          ExtensionWelcomeNotification::kRequestedShowTimeDays);
-  SetElapsedTime(requested_show_time);
-  ShowChromeNowNotification();
-
-  EXPECT_FALSE(task_runner()->HasPendingTask());
-  EXPECT_EQ(message_center()->add_notification_calls(), 0);
-  EXPECT_EQ(message_center()->remove_notification_calls(), 0);
-  EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
-  EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissedLocal));
-  EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
-  EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 1);
-}
diff --git a/chrome/browser/notifications/message_center_notification_manager.cc b/chrome/browser/notifications/message_center_notification_manager.cc
index fe5d373..d1d080d 100644
--- a/chrome/browser/notifications/message_center_notification_manager.cc
+++ b/chrome/browser/notifications/message_center_notification_manager.cc
@@ -10,8 +10,6 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "build/build_config.h"
-#include "chrome/browser/notifications/extension_welcome_notification.h"
-#include "chrome/browser/notifications/extension_welcome_notification_factory.h"
 #include "chrome/browser/notifications/message_center_settings_controller.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/profile_notification.h"
@@ -83,9 +81,6 @@
       base::MakeUnique<ProfileNotification>(profile, notification);
   ProfileNotification* profile_notification = profile_notification_ptr.get();
 
-  ExtensionWelcomeNotificationFactory::GetForBrowserContext(profile)->
-      ShowWelcomeNotificationIfNecessary(profile_notification->notification());
-
   // WARNING: You MUST use AddProfileNotification or update the message center
   // via the notification within a ProfileNotification object or the profile ID
   // will not be correctly set for ChromeOS.
diff --git a/chrome/browser/notifications/message_center_notifications_browsertest.cc b/chrome/browser/notifications/message_center_notifications_browsertest.cc
index 47976104..af7d86b 100644
--- a/chrome/browser/notifications/message_center_notifications_browsertest.cc
+++ b/chrome/browser/notifications/message_center_notifications_browsertest.cc
@@ -290,30 +290,8 @@
   delegate->Release();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// MessageCenterNotificationsTestWithoutChangeQueue
-
-// TODO(yoshiki): Merge this to NessageCenterNotificationsTest after the
-// feature gets stable.
-class MessageCenterNotificationsTestWithoutChangeQueue
-    : public MessageCenterNotificationsTest {
- public:
-  MessageCenterNotificationsTestWithoutChangeQueue() {}
-  ~MessageCenterNotificationsTestWithoutChangeQueue() override {}
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    MessageCenterNotificationsTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitchASCII(switches::kMessageCenterChangesWhileOpen,
-                                    "enabled");
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageCenterNotificationsTestWithoutChangeQueue);
-};
-
-IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTestWithoutChangeQueue,
+IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
                        UpdateNonProgressNotificationWhenCenterVisible) {
-
   TestAddObserver observer(message_center());
 
   TestDelegate* delegate;
@@ -341,9 +319,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(
-    MessageCenterNotificationsTestWithoutChangeQueue,
+    MessageCenterNotificationsTest,
     UpdateNonProgressToProgressNotificationWhenCenterVisible) {
-
   TestAddObserver observer(message_center());
 
   TestDelegate* delegate;
@@ -370,83 +347,4 @@
   delegate->Release();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// MessageCenterNotificationsTestWithoutRealtimeChange
-
-// TODO(yoshiki): Remove this after the feature gets stable.
-class MessageCenterNotificationsTestWithChangeQueue
-    : public MessageCenterNotificationsTest {
- public:
-  MessageCenterNotificationsTestWithChangeQueue() {}
-  ~MessageCenterNotificationsTestWithChangeQueue() override {}
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    MessageCenterNotificationsTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitchASCII(switches::kMessageCenterChangesWhileOpen,
-                                    "disabled");
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageCenterNotificationsTestWithChangeQueue);
-};
-
-IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTestWithChangeQueue,
-                       UpdateNonProgressNotificationWhenCenterVisible) {
-
-  TestAddObserver observer(message_center());
-
-  TestDelegate* delegate;
-
-  // Add a non-progress notification and update it while the message center
-  // is visible.
-  Notification notification = CreateTestNotification("n", &delegate);
-  manager()->Add(notification, profile());
-  const std::string notification_id =
-      manager()->GetMessageCenterNotificationIdForTest("n", profile());
-  message_center()->ClickOnNotification(notification_id);
-  message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
-  observer.reset_logs();
-  notification.set_title(base::ASCIIToUTF16("title2"));
-  manager()->Update(notification, profile());
-
-  // Expect that the notification update is not done.
-  EXPECT_EQ("", observer.log(notification_id));
-
-  message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT);
-  EXPECT_EQ(base::StringPrintf("update-%s", notification_id.c_str()),
-            observer.log(notification_id));
-
-  delegate->Release();
-}
-
-IN_PROC_BROWSER_TEST_F(
-    MessageCenterNotificationsTestWithChangeQueue,
-    UpdateNonProgressToProgressNotificationWhenCenterVisible) {
-
-  TestAddObserver observer(message_center());
-
-  TestDelegate* delegate;
-
-  // Add a non-progress notification and change the type to progress while the
-  // message center is visible.
-  Notification notification = CreateTestNotification("n", &delegate);
-  manager()->Add(notification, profile());
-  const std::string notification_id =
-      manager()->GetMessageCenterNotificationIdForTest("n", profile());
-  message_center()->ClickOnNotification(notification_id);
-  message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
-  observer.reset_logs();
-  notification.set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
-  manager()->Update(notification, profile());
-
-  // Expect that the notification update is not done.
-  EXPECT_EQ("", observer.log(notification_id));
-
-  message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT);
-  EXPECT_EQ(base::StringPrintf("update-%s", notification_id.c_str()),
-            observer.log(notification_id));
-
-  delegate->Release();
-}
-
 #endif  // defined(OS_CHROMEOS)
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index d9c36bc..c590e891 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -63,6 +63,7 @@
 #include "ui/gfx/geometry/point.h"
 
 using testing::_;
+using testing::UnorderedElementsAre;
 
 namespace {
 
@@ -2388,6 +2389,62 @@
                              base::ASCIIToUTF16("pw"));
 }
 
+// This is a subclass to enable kEnablePasswordSelection feature.
+class PasswordManagerBrowserTestForPasswordSelection
+    : public PasswordManagerBrowserTestBase {
+ public:
+  PasswordManagerBrowserTestForPasswordSelection() = default;
+  ~PasswordManagerBrowserTestForPasswordSelection() override = default;
+
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        password_manager::features::kEnablePasswordSelection);
+    PasswordManagerBrowserTestBase::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestForPasswordSelection,
+                       MultiplePasswordsWithPasswordSelectionEnabled) {
+  NavigateToFile("/password/password_form.html");
+  NavigationObserver observer(WebContents());
+  // It is important that these 3 passwords are different. Because if two of
+  // them are the same, it is going to be treated as a password update and the
+  // dropdown will not be shown.
+  std::string fill_and_submit =
+      "document.getElementById('chg_password_wo_username_field').value = "
+      "'pass1';"
+      "document.getElementById('chg_new_password_wo_username_1').value = "
+      "'pass2';"
+      "document.getElementById('chg_new_password_wo_username_2').value = "
+      "'pass3';"
+      "document.getElementById('chg_submit_wo_username_button').click()";
+  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
+  observer.Wait();
+  // 3 possible passwords are going to be shown in a dropdown when the password
+  // selection feature is enabled. The first one will be selected as the main
+  // password by default, and the other two will be in the
+  // other_possible_passwords list.
+  // The save password prompt is expected.
+  BubbleObserver bubble_observer(WebContents());
+  EXPECT_TRUE(bubble_observer.IsSavePromptShownAutomatically());
+  EXPECT_EQ(base::ASCIIToUTF16("pass1"),
+            ManagePasswordsUIController::FromWebContents(WebContents())
+                ->GetPendingPassword()
+                .password_value);
+  EXPECT_THAT(ManagePasswordsUIController::FromWebContents(WebContents())
+                  ->GetPendingPassword()
+                  .other_possible_passwords,
+              UnorderedElementsAre(base::ASCIIToUTF16("pass2"),
+                                   base::ASCIIToUTF16("pass3")));
+  bubble_observer.AcceptSavePrompt();
+  WaitForPasswordStore();
+  CheckThatCredentialsStored(base::ASCIIToUTF16(""),
+                             base::ASCIIToUTF16("pass1"));
+}
+
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
                        ChangePwdWhenTheFormContainNotUsernameTextfield) {
   // At first let us save credentials to the PasswordManager.
diff --git a/chrome/browser/password_manager/password_manager_util_win.cc b/chrome/browser/password_manager/password_manager_util_win.cc
index d01d2b7..5d21741 100644
--- a/chrome/browser/password_manager/password_manager_util_win.cc
+++ b/chrome/browser/password_manager/password_manager_util_win.cc
@@ -131,6 +131,13 @@
 
 bool CheckBlankPasswordWithPrefs(const WCHAR* username,
                                  PasswordCheckPrefs* prefs) {
+  // If the user name has a backslash, then it is of the form DOMAIN\username.
+  // NetUserGetInfo() (called from GetPasswordLastChanged()) as well as
+  // LogonUser() below only wants the username portion.
+  LPCWSTR backslash = wcschr(username, L'\\');
+  if (backslash)
+    username = backslash + 1;
+
   int64_t last_changed = GetPasswordLastChanged(username);
 
   // If we cannot determine when the password was last changed
@@ -453,8 +460,9 @@
       CloseHandle(handle);
     } else {
       err = GetLastError();
-      if (err == ERROR_ACCOUNT_RESTRICTION && cred_password_length == 0) {
-        // Password is blank, so permit.
+      if (err == ERROR_ACCOUNT_RESTRICTION) {
+        // Password is blank, or there is some other restriction imposed on the
+        // account.  However, the password has been validated, so permit.
         retval = true;
       } else {
         DLOG(ERROR) << "Unable to authenticate " << GetLastError();
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 99d8a54..0fc2542 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -37,7 +37,6 @@
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/net/predictor.h"
 #include "chrome/browser/net/profile_network_context_service.h"
-#include "chrome/browser/notifications/extension_welcome_notification.h"
 #include "chrome/browser/notifications/notification_channels_provider_android.h"
 #include "chrome/browser/notifications/notifier_state_tracker.h"
 #include "chrome/browser/pepper_flash_settings_manager.h"
@@ -525,12 +524,6 @@
   extensions::RuntimeAPI::RegisterPrefs(registry);
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-#if BUILDFLAG(ENABLE_EXTENSIONS) && !defined(OS_ANDROID)
-  // The extension welcome notification requires a build that enables extensions
-  // and notifications, and uses the UI message center.
-  ExtensionWelcomeNotification::RegisterProfilePrefs(registry);
-#endif
-
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   printing::StickySettings::RegisterProfilePrefs(registry);
 #endif
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 27d85f7b..dcbd6d3 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -35,7 +35,6 @@
 #include "chrome/browser/media/router/media_router_factory.h"
 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h"
 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h"
-#include "chrome/browser/notifications/extension_welcome_notification_factory.h"
 #include "chrome/browser/notifications/notifier_state_tracker_factory.h"
 #include "chrome/browser/ntp_snippets/content_suggestions_service_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
@@ -220,9 +219,6 @@
   CloudPrintProxyServiceFactory::GetInstance();
 #endif
   CookieSettingsFactory::GetInstance();
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-  ExtensionWelcomeNotificationFactory::GetInstance();
-#endif
   NotifierStateTrackerFactory::GetInstance();
   data_use_measurement::ChromeDataUseAscriberServiceFactory::GetInstance();
 #if defined(OS_WIN)
diff --git a/chrome/browser/resources/media_router/elements/route_controls/route_controls.js b/chrome/browser/resources/media_router/elements/route_controls/route_controls.js
index 9a5eb64..00ec83a 100644
--- a/chrome/browser/resources/media_router/elements/route_controls/route_controls.js
+++ b/chrome/browser/resources/media_router/elements/route_controls/route_controls.js
@@ -80,7 +80,7 @@
 
     /**
      * The timestamp for when the controller last submitted a seek request.
-     * @private {boolean}
+     * @private {number}
      */
     lastSeekByUser_: {
       type: Number,
@@ -88,6 +88,15 @@
     },
 
     /**
+     * The timestamp for when |routeStatus| was last updated.
+     * @private {number}
+     */
+    lastStatusUpdate_: {
+      type: Number,
+      value: 0,
+    },
+
+    /**
      * The timestamp for when the controller last submitted a volume change
      * request.
      * @private {boolean}
@@ -156,9 +165,10 @@
    * @private
    */
   canIncrementCurrentTime_: function() {
-    return this.routeStatus.playState === media_router.PlayState.PLAYING &&
+    return !this.isSeeking_ &&
+        this.routeStatus.playState === media_router.PlayState.PLAYING &&
         (this.routeStatus.duration === 0 ||
-         this.routeStatus.currentTime < this.routeStatus.duration);
+         this.displayedCurrentTime_ < this.routeStatus.duration);
   },
 
   /**
@@ -277,10 +287,13 @@
    */
   maybeIncrementCurrentTime_: function() {
     if (this.canIncrementCurrentTime_()) {
-      this.routeStatus.currentTime++;
-      this.displayedCurrentTime_ = this.routeStatus.currentTime;
+      var updatedCurrentTime = this.routeStatus.currentTime +
+          Math.floor((Date.now() - this.lastStatusUpdate_) / 1000);
+      this.displayedCurrentTime_ = this.routeStatus.duration === 0 ?
+          updatedCurrentTime :
+          Math.min(updatedCurrentTime, this.routeStatus.duration);
       if (this.routeStatus.duration === 0 ||
-          this.routeStatus.currentTime < this.routeStatus.duration) {
+          this.displayedCurrentTime_ < this.routeStatus.duration) {
         this.timeIncrementsTimeoutId_ =
             setTimeout(() => this.maybeIncrementCurrentTime_(), 1000);
       }
@@ -327,6 +340,7 @@
    * @private
    */
   onRouteStatusChange_: function(newRouteStatus) {
+    this.lastStatusUpdate_ = Date.now();
     if (this.shouldAcceptCurrentTimeUpdates_()) {
       this.displayedCurrentTime_ = newRouteStatus.currentTime;
     }
@@ -341,13 +355,10 @@
       media_router.browserApi.reportWebUIRouteControllerLoaded(
           this.initialLoadTime_ - this.routeDetailsOpenTime);
     }
+    this.stopIncrementingCurrentTime_();
     if (this.canIncrementCurrentTime_()) {
-      if (!this.timeIncrementsTimeoutId_) {
-        this.timeIncrementsTimeoutId_ =
-            setTimeout(() => this.maybeIncrementCurrentTime_(), 1000);
-      }
-    } else {
-      this.stopIncrementingCurrentTime_();
+      this.timeIncrementsTimeoutId_ =
+          setTimeout(() => this.maybeIncrementCurrentTime_(), 1000);
     }
     this.hangoutsLocalPresent_ = !!newRouteStatus.hangoutsExtraData &&
         newRouteStatus.hangoutsExtraData.localPresent;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index 9a13f0d..1a7e16a 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -355,7 +355,8 @@
 
   // Exit immersive mode if the feature is enabled and the widget is not in
   // fullscreen mode.
-  if (!frame()->IsFullscreen() && !browser_view()->IsBrowserTypeNormal()) {
+  if (!frame()->IsFullscreen() && !browser_view()->IsBrowserTypeNormal() &&
+      ash::Shell::Get()->tablet_mode_controller()->auto_hide_title_bars()) {
     browser_view()->immersive_mode_controller()->SetEnabled(false);
     return;
   }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
index 204af6e..c88fae4 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -83,6 +83,9 @@
                            ToggleTabletModeRelayout);
   FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest,
                            AvatarDisplayOnTeleportedWindow);
+  FRIEND_TEST_ALL_PREFIXES(ImmersiveModeControllerAshTestTabletMode,
+                           FrameLayout);
+
   friend class BrowserHeaderPainterAsh;
 
   // Distance between the left edge of the NonClientFrameView and the tab strip.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 445da4d..4ab0d87 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -347,9 +347,9 @@
   // Disable immersive fullscreen when the user exits fullscreen without going
   // through FullscreenController::ToggleBrowserFullscreenMode(). This is the
   // case if the user exits fullscreen via the restore button.
-  if (controller_->IsEnabled() &&
-      !window_state->IsFullscreen() &&
-      !window_state->IsMinimized()) {
+  if (controller_->IsEnabled() && !window_state->IsFullscreen() &&
+      !window_state->IsMinimized() &&
+      old_type == ash::wm::WINDOW_STATE_TYPE_FULLSCREEN) {
     browser_view_->FullscreenStateChanged();
   }
 }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
index 9424224..2755d61 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
 
+#include "ash/frame/caption_buttons/frame_caption_button.h"
+#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
 #include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/root_window_controller.h"
@@ -18,6 +20,8 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
+#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
+#include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
@@ -409,3 +413,37 @@
       false);
   EXPECT_FALSE(controller()->IsEnabled());
 }
+
+// Verify that the frame layout is as expected when using immersive mode in
+// tablet mode.
+TEST_F(ImmersiveModeControllerAshTestTabletMode, FrameLayout) {
+  ASSERT_FALSE(controller()->IsEnabled());
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  // We know we're using Ash, so static cast.
+  BrowserNonClientFrameViewAsh* frame_view =
+      static_cast<BrowserNonClientFrameViewAsh*>(
+          browser_view->GetWidget()->non_client_view()->frame_view());
+  ash::FrameCaptionButtonContainerView* caption_button_container =
+      frame_view->caption_button_container_;
+  ash::FrameCaptionButtonContainerView::TestApi frame_test_api(
+      caption_button_container);
+
+  EXPECT_TRUE(frame_test_api.size_button()->visible());
+  ash::Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(
+      true);
+  frame_test_api.EndAnimations();
+
+  // Verify the size button is hidden in tablet mode.
+  EXPECT_FALSE(frame_test_api.size_button()->visible());
+  ash::Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(
+      false);
+  frame_test_api.EndAnimations();
+
+  // Verify the size button is visible in clamshell mode, and that it does not
+  // cover the other two buttons.
+  EXPECT_TRUE(frame_test_api.size_button()->visible());
+  EXPECT_FALSE(frame_test_api.size_button()->GetBoundsInScreen().Intersects(
+      frame_test_api.close_button()->GetBoundsInScreen()));
+  EXPECT_FALSE(frame_test_api.size_button()->GetBoundsInScreen().Intersects(
+      frame_test_api.minimize_button()->GetBoundsInScreen()));
+}
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 6c3c047f..6a01da04 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1269,26 +1269,6 @@
 const char kMessageCenterDisabledSystemComponentIds[] =
     "message_center.disabled_system_component_ids";
 
-// Boolean pref indicating the Chrome Now welcome notification was dismissed
-// by the user. Syncable.
-// Note: This is now read-only. The welcome notification writes the _local
-// version, below.
-const char kWelcomeNotificationDismissed[] =
-    "message_center.welcome_notification_dismissed";
-
-// Boolean pref indicating the Chrome Now welcome notification was dismissed
-// by the user on this machine.
-const char kWelcomeNotificationDismissedLocal[] =
-    "message_center.welcome_notification_dismissed_local";
-
-// Boolean pref indicating the welcome notification was previously popped up.
-const char kWelcomeNotificationPreviouslyPoppedUp[] =
-    "message_center.welcome_notification_previously_popped_up";
-
-// Integer pref containing the expiration timestamp of the welcome notification.
-const char kWelcomeNotificationExpirationTimestamp[] =
-    "message_center.welcome_notification_expiration_timestamp";
-
 // Boolean pref that determines whether the user can enter fullscreen mode.
 // Disabling fullscreen mode also makes kiosk mode unavailable on desktop
 // platforms.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 6640179c8..46aeb8f 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -434,10 +434,6 @@
 
 extern const char kMessageCenterDisabledExtensionIds[];
 extern const char kMessageCenterDisabledSystemComponentIds[];
-extern const char kWelcomeNotificationDismissed[];
-extern const char kWelcomeNotificationDismissedLocal[];
-extern const char kWelcomeNotificationPreviouslyPoppedUp[];
-extern const char kWelcomeNotificationExpirationTimestamp[];
 
 extern const char kFullscreenAllowed[];
 
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 7e9f895..4330678 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -633,9 +633,6 @@
     "https://support.google.com/chrome/?p=chrome_cleanup_tool";
 #endif
 
-const char kNotificationWelcomeLearnMoreURL[] =
-    "https://support.google.com/chrome/?p=ib_google_now_welcome";
-
 // Add hosts here to be included in chrome://chrome-urls (about:about).
 // These hosts will also be suggested by BuiltinProvider.
 const char* const kChromeHostURLs[] = {
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index a5237a7..1481f1e9 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -527,9 +527,6 @@
 extern const char kChromeCleanerLearnMoreURL[];
 #endif
 
-// The Welcome Notification More Info URL.
-extern const char kNotificationWelcomeLearnMoreURL[];
-
 // Gets the hosts/domains that are shown in chrome://chrome-urls.
 extern const char* const kChromeHostURLs[];
 extern const size_t kNumberOfChromeHostURLs;
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
index 655dfb79..42b314d 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -811,18 +811,23 @@
   v8::Isolate* isolate = GetIsolate();
 
   gin::DataObjectBuilder name_from_type(isolate);
-  for (int i = ui::AX_NAME_FROM_NONE; i <= ui::AX_NAME_FROM_LAST; ++i)
-    name_from_type.Set(i, ui::ToString(static_cast<ui::AXNameFrom>(i)));
+  for (int i = ui::AX_NAME_FROM_NONE; i <= ui::AX_NAME_FROM_LAST; ++i) {
+    name_from_type.Set(
+        i, base::StringPiece(ui::ToString(static_cast<ui::AXNameFrom>(i))));
+  }
 
   gin::DataObjectBuilder restriction(isolate);
-  for (int i = ui::AX_RESTRICTION_NONE; i <= ui::AX_RESTRICTION_LAST; ++i)
-    restriction.Set(i, ui::ToString(static_cast<ui::AXRestriction>(i)));
+  for (int i = ui::AX_RESTRICTION_NONE; i <= ui::AX_RESTRICTION_LAST; ++i) {
+    restriction.Set(
+        i, base::StringPiece(ui::ToString(static_cast<ui::AXRestriction>(i))));
+  }
 
   gin::DataObjectBuilder description_from_type(isolate);
   for (int i = ui::AX_DESCRIPTION_FROM_NONE; i <= ui::AX_DESCRIPTION_FROM_LAST;
        ++i) {
     description_from_type.Set(
-        i, ui::ToString(static_cast<ui::AXDescriptionFrom>(i)));
+        i,
+        base::StringPiece(ui::ToString(static_cast<ui::AXDescriptionFrom>(i))));
   }
 
   args.GetReturnValue().Set(
diff --git a/chrome/renderer/resources/extensions/searchbox_api.js b/chrome/renderer/resources/extensions/searchbox_api.js
index 2f7b291..c7378ef0 100644
--- a/chrome/renderer/resources/extensions/searchbox_api.js
+++ b/chrome/renderer/resources/extensions/searchbox_api.js
@@ -14,8 +14,6 @@
       //                            Private functions
       // =======================================================================
       native function GetRightToLeft();
-      native function GetSearchRequestParams();
-      native function GetSuggestionToPrefetch();
       native function IsFocused();
       native function IsKeyCaptureEnabled();
       native function Paste();
@@ -28,9 +26,6 @@
       Object.defineProperty(this, 'rtl', { get: GetRightToLeft });
       this.__defineGetter__('isFocused', IsFocused);
       this.__defineGetter__('isKeyCaptureEnabled', IsKeyCaptureEnabled);
-      this.__defineGetter__('suggestion', GetSuggestionToPrefetch);
-      Object.defineProperty(this, 'requestParams',
-                            { get: GetSearchRequestParams });
 
       this.paste = function(value) {
         Paste(value);
@@ -46,8 +41,6 @@
 
       this.onfocuschange = null;
       this.onkeycapturechange = null;
-      this.onsubmit = null;
-      this.onsuggestionchange = null;
     };
 
     this.newTabPage = new function() {
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index 623eb12c..79690cd 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -357,14 +357,6 @@
   // Returns true if the Chrome UI is rendered right-to-left.
   static void GetRightToLeft(const v8::FunctionCallbackInfo<v8::Value>& args);
 
-  // Gets the Embedded Search request params. Used for logging purposes.
-  static void GetSearchRequestParams(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Gets the current top suggestion to prefetch search results.
-  static void GetSuggestionToPrefetch(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
   // Gets the background info of the theme currently adopted by browser.
   // Call only when overlay is showing NTP page.
   static void GetThemeBackgroundInfo(
@@ -499,10 +491,6 @@
     return v8::FunctionTemplate::New(isolate, GetMostVisitedItemData);
   if (name_str == "GetRightToLeft")
     return v8::FunctionTemplate::New(isolate, GetRightToLeft);
-  if (name_str == "GetSearchRequestParams")
-    return v8::FunctionTemplate::New(isolate, GetSearchRequestParams);
-  if (name_str == "GetSuggestionToPrefetch")
-    return v8::FunctionTemplate::New(isolate, GetSuggestionToPrefetch);
   if (name_str == "GetThemeBackgroundInfo")
     return v8::FunctionTemplate::New(isolate, GetThemeBackgroundInfo);
   if (name_str == "IsFocused")
@@ -648,37 +636,6 @@
   args.GetReturnValue().Set(base::i18n::IsRTL());
 }
 
-// static
-void SearchBoxExtensionWrapper::GetSearchRequestParams(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // TODO(treib): Remove this method.
-  content::RenderFrame* render_frame = GetRenderFrame();
-  if (!render_frame)
-    return;
-
-  v8::Isolate* isolate = args.GetIsolate();
-  v8::Local<v8::Object> data = v8::Object::New(isolate);
-  args.GetReturnValue().Set(data);
-}
-
-// static
-void SearchBoxExtensionWrapper::GetSuggestionToPrefetch(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // TODO(treib): Remove this method.
-  content::RenderFrame* render_frame = GetRenderFrame();
-  if (!render_frame)
-    return;
-
-  v8::Isolate* isolate = args.GetIsolate();
-  v8::Local<v8::Object> data = v8::Object::New(isolate);
-  data->Set(v8::String::NewFromUtf8(isolate, "text"),
-            v8::String::NewFromUtf8(isolate, ""));
-  data->Set(v8::String::NewFromUtf8(isolate, "metadata"),
-            v8::String::NewFromUtf8(isolate, ""));
-  args.GetReturnValue().Set(data);
-}
-
-// static
 void SearchBoxExtensionWrapper::GetThemeBackgroundInfo(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   content::RenderFrame* render_frame = GetRenderFrame();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6fdc489..b95cf978 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4124,7 +4124,6 @@
       "../browser/media/cast_transport_host_filter_unittest.cc",
       "../browser/media_galleries/chromeos/mtp_device_object_enumerator_unittest.cc",
       "../browser/metrics/extensions_metrics_provider_unittest.cc",
-      "../browser/notifications/extension_welcome_notification_unittest.cc",
       "../browser/notifications/notification_system_observer_unittest.cc",
       "../browser/renderer_context_menu/context_menu_content_type_unittest.cc",
       "../browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_config_unittest.cc",
diff --git a/chrome/test/data/webui/media_router/route_controls_tests.js b/chrome/test/data/webui/media_router/route_controls_tests.js
index fe047cf..aee94ec1 100644
--- a/chrome/test/data/webui/media_router/route_controls_tests.js
+++ b/chrome/test/data/webui/media_router/route_controls_tests.js
@@ -266,13 +266,13 @@
         // Check that the current time has been incremented after a second.
         setTimeout(function() {
           controls.routeStatus.playState = media_router.PlayState.PAUSED;
-          var pausedTime = controls.routeStatus.currentTime;
+          var pausedTime = controls.displayedCurrentTime_;
           assertTrue(pausedTime > initialTime);
 
           // Check that the current time stayed the same after a second, now
           // that the media is paused.
           setTimeout(function() {
-            assertEquals(pausedTime, controls.routeStatus.currentTime);
+            assertEquals(pausedTime, controls.displayedCurrentTime_);
             done();
           }, 1000);
         }, 1000);
diff --git a/chromecast/tools/trace.py b/chromecast/tools/trace.py
index dfbe995..4d66321 100755
--- a/chromecast/tools/trace.py
+++ b/chromecast/tools/trace.py
@@ -9,24 +9,29 @@
 
 import contextlib
 import json
+import logging
 import optparse
 import os
 import sys
 import websocket
 
-from tracinglib import TracingBackend, TracingClient
+from tracinglib import TracingBackend, TracingBackendAndroid, TracingClient
 
 @contextlib.contextmanager
-def Connect(device_ip, devtools_port):
-  backend = TracingBackend()
+def Connect(options):
+  if options.adb_device:
+    backend = TracingBackendAndroid(options.adb_device)
+  else:
+    backend = TracingBackend(options.device, options.port, 10, 0)
+
   try:
-    backend.Connect(device_ip, devtools_port)
+    backend.Connect()
     yield backend
   finally:
     backend.Disconnect()
 
 
-def DumpTrace(trace, options):
+def GetOutputFilePath(options):
   filepath = os.path.expanduser(options.output) if options.output \
       else os.path.join(os.getcwd(), 'trace.json')
 
@@ -37,8 +42,6 @@
   else:
     filepath = os.path.join(os.getcwd(), filepath)
 
-  with open(filepath, 'w') as f:
-    json.dump(trace, f)
   return filepath
 
 
@@ -52,12 +55,15 @@
   parser.add_option(
       '-d', '--device', help='Device ip address.', type='string',
       default='127.0.0.1')
+  parser.add_option(
+      '-s', '--adb-device', help='Device serial for adb.', type='string')
 
   tracing_opts = optparse.OptionGroup(parser, 'Tracing options')
   tracing_opts.add_option(
       '-c', '--category-filter',
       help='Apply filter to control what category groups should be traced.',
-      type='string')
+      type='string',
+      default='"*"')
   tracing_opts.add_option(
       '--record-continuously',
       help='Keep recording until stopped. The trace buffer is of fixed size '
@@ -84,14 +90,13 @@
   options, _args = parser.parse_args()
   _ProcessOptions(options)
 
-  with Connect(options.device, options.port) as tracing_backend:
-    tracing_backend.StartTracing(TracingClient(),
-                                 options.category_filter,
+  with Connect(options) as tracing_backend:
+    tracing_backend.StartTracing(options.category_filter,
                                  options.record_continuously)
     raw_input('Capturing trace. Press Enter to stop...')
-    trace = tracing_backend.StopTracing()
+    filepath = GetOutputFilePath(options)
+    tracing_backend.StopTracing(filepath)
 
-  filepath = DumpTrace(trace, options)
   print('Done')
   print('Trace written to file://%s' % filepath)
 
diff --git a/chromecast/tools/tracinglib.py b/chromecast/tools/tracinglib.py
index 675046e6..ed5b686b 100644
--- a/chromecast/tools/tracinglib.py
+++ b/chromecast/tools/tracinglib.py
@@ -8,6 +8,8 @@
 import json
 import logging
 import math
+import subprocess
+import time
 import websocket
 
 
@@ -21,24 +23,30 @@
 class TracingBackend(object):
   """Class for starting a tracing session with cast_shell."""
 
-  def __init__(self):
+  def __init__(self, device_ip, devtools_port, timeout,
+               buffer_usage_reporting_interval):
+    """
+    Args:
+      device_ip: IP of device to connect to.
+      devtools_port: Remote dev tool port to connect to. Defaults to 9222.
+      timeout: Time to wait to start tracing in seconds. Default 10s.
+      buffer_usage_reporting_interval: How often to report buffer usage.
+    """
     self._socket = None
     self._next_request_id = 0
     self._tracing_client = None
     self._tracing_data = []
+    self._device_ip = device_ip
+    self._devtools_port = devtools_port
+    self._timeout = timeout
+    self._buffer_usage_reporting_interval = buffer_usage_reporting_interval
 
-  def Connect(self, device_ip, devtools_port=9222, timeout=10):
-    """Connect to cast_shell on given device and port.
-
-    Args:
-      device_ip: IP of device to connect to.
-      devtools_port: Remote dev tool port to connect to. Defaults to 9222.
-      timeout: Amount of time to wait for connection in seconds. Default 10s.
-    """
+  def Connect(self):
+    """Connect to cast_shell."""
     assert not self._socket
-    url = 'ws://%s:%i/devtools/browser' % (device_ip, devtools_port)
+    url = 'ws://%s:%i/devtools/browser' % (self._device_ip, self._devtools_port)
     print('Connect to %s ...' % url)
-    self._socket = websocket.create_connection(url, timeout=timeout)
+    self._socket = websocket.create_connection(url, timeout=self._timeout)
     self._next_request_id = 0
 
   def Disconnect(self):
@@ -48,44 +56,35 @@
       self._socket = None
 
   def StartTracing(self,
-                   tracing_client=None,
                    custom_categories=None,
-                   record_continuously=False,
-                   buffer_usage_reporting_interval=0,
-                   timeout=10):
+                   record_continuously=False):
     """Begin a tracing session on device.
 
     Args:
-      tracing_client: client for this tracing session.
       custom_categories: Categories to filter for. None records all categories.
       record_continuously: Keep tracing until stopped. If false, will exit when
                            buffer is full.
-      buffer_usage_reporting_interval: How often to report buffer usage.
-      timeout: Time to wait to start tracing in seconds. Default 10s.
     """
-    self._tracing_client = tracing_client
-    self._socket.settimeout(timeout)
+    self._tracing_client = TracingClient()
+    self._socket.settimeout(self._timeout)
     req = {
       'method': 'Tracing.start',
       'params': {
         'categories': custom_categories,
-        'bufferUsageReportingInterval': buffer_usage_reporting_interval,
+        'bufferUsageReportingInterval': self._buffer_usage_reporting_interval,
         'options': 'record-continuously' if record_continuously else
                    'record-until-full'
       }
     }
     self._SendRequest(req)
 
-  def StopTracing(self, timeout=30):
+  def StopTracing(self, output_file):
     """End a tracing session on device.
 
     Args:
-      timeout: Time to wait to stop tracing in seconds. Default 30s.
-
-    Returns:
-      Trace file for the stopped session.
+      output_file: Path to the file to store the trace.
     """
-    self._socket.settimeout(timeout)
+    self._socket.settimeout(self._timeout)
     req = {'method': 'Tracing.end'}
     self._SendRequest(req)
     while self._socket:
@@ -97,7 +96,10 @@
         self._tracing_client = None
         result = self._tracing_data
         self._tracing_data = []
-        return result
+
+        with open(output_file, 'w') as f:
+          json.dump(result, f)
+        return
 
   def _SendRequest(self, req):
     """Sends request to remote devtools.
@@ -140,3 +142,63 @@
       self._tracing_client.BufferUsage(value)
     elif 'Tracing.tracingComplete' == method:
       return True
+
+
+class TracingBackendAndroid(object):
+  """Android version of TracingBackend."""
+  def __init__(self, device):
+    self.device = device
+
+  def Connect(self):
+    pass
+
+
+  def Disconnect(self):
+    pass
+
+  def StartTracing(self,
+                   custom_categories=None,
+                   record_continuously=False):
+    """Begin a tracing session on device.
+
+    Args:
+      custom_categories: Categories to filter for. None records all categories.
+      record_continuously: Keep tracing until stopped. If false, will exit when
+                           buffer is full.
+    """
+    categories = (custom_categories if custom_categories else
+                  '_DEFAULT_CHROME_CATEGORIES')
+    self._file = '/sdcard/Download/trace-py-{0}'.format(int(time.time()))
+    command = ['shell', 'am', 'broadcast',
+        '-a', 'com.google.android.apps.mediashell.GPU_PROFILER_START',
+        '-e', 'categories', categories,
+        '-e', 'file', self._file]
+    if record_continuously:
+      command += ['-e', 'continuous']
+
+    self._AdbCommand(command)
+
+  def StopTracing(self, output_file):
+    """End a tracing session on device.
+
+    Args:
+      output_file: Path to the file to store the trace.
+    """
+    stop_profiling_command = ['shell', 'am', 'broadcast',
+        '-a', 'com.google.android.apps.mediashell.GPU_PROFILER_STOP']
+    self._AdbCommand(stop_profiling_command)
+
+    # Wait for trace file to be written
+    while True:
+      result = self._AdbCommand(['logcat', '-d'])
+      if 'Results are in %s' % self._file in result:
+        break
+
+    self._AdbCommand(['pull', self._file, output_file])
+
+  def _AdbCommand(self, command):
+    args = ['adb', '-s', self.device]
+    logging.debug(' '.join(args + command))
+    result = subprocess.check_output(args + command)
+    logging.debug(result)
+    return result
diff --git a/chromeos/cert_loader.cc b/chromeos/cert_loader.cc
index 55e4598..2faf12d 100644
--- a/chromeos/cert_loader.cc
+++ b/chromeos/cert_loader.cc
@@ -18,7 +18,7 @@
 #include "net/cert/cert_database.h"
 #include "net/cert/nss_cert_database.h"
 #include "net/cert/nss_cert_database_chromeos.h"
-#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
 
 namespace chromeos {
 
@@ -60,7 +60,7 @@
     LoadCertificates();
   }
 
-  const net::CertificateList& cert_list() const { return cert_list_; }
+  const net::ScopedCERTCertificateList& cert_list() const { return cert_list_; }
 
   bool initial_load_running() const {
     return nss_database_ && !initial_load_finished_;
@@ -96,13 +96,13 @@
   }
 
   // Called if a certificate load task is finished.
-  void UpdateCertificates(std::unique_ptr<net::CertificateList> cert_list) {
+  void UpdateCertificates(net::ScopedCERTCertificateList cert_list) {
     CHECK(thread_checker_.CalledOnValidThread());
     DCHECK(certificates_update_running_);
-    VLOG(1) << "UpdateCertificates: " << cert_list->size();
+    VLOG(1) << "UpdateCertificates: " << cert_list.size();
 
     // Ignore any existing certificates.
-    cert_list_ = std::move(*cert_list);
+    cert_list_ = std::move(cert_list);
 
     initial_load_finished_ = true;
     certificates_updated_callback_.Run();
@@ -130,7 +130,7 @@
   net::NSSCertDatabase* nss_database_ = nullptr;
 
   // Cached Certificates loaded from the database.
-  net::CertificateList cert_list_;
+  net::ScopedCERTCertificateList cert_list_;
 
   base::ThreadChecker thread_checker_;
 
@@ -142,10 +142,9 @@
 namespace {
 
 // Checks if |certificate| is on the given |slot|.
-bool IsCertificateOnSlot(const net::X509Certificate* certificate,
-                         PK11SlotInfo* slot) {
+bool IsCertificateOnSlot(CERTCertificate* certificate, PK11SlotInfo* slot) {
   crypto::ScopedPK11SlotList slots_for_cert(
-      PK11_GetAllSlotsForCert(certificate->os_cert_handle(), nullptr));
+      PK11_GetAllSlotsForCert(certificate, nullptr));
   if (!slots_for_cert)
     return false;
 
@@ -167,21 +166,20 @@
 
 // Goes through all certificates in |all_certs| and copies those certificates
 // which are on |system_slot| to a new list.
-net::CertificateList FilterSystemTokenCertificates(
-    net::CertificateList certs,
+net::ScopedCERTCertificateList FilterSystemTokenCertificates(
+    net::ScopedCERTCertificateList certs,
     crypto::ScopedPK11Slot system_slot) {
   VLOG(1) << "FilterSystemTokenCertificates";
   if (!system_slot)
-    return net::CertificateList();
+    return net::ScopedCERTCertificateList();
 
-  // Only keep certificates which are on the |system_slot|.
   PK11SlotInfo* system_slot_ptr = system_slot.get();
+  // Only keep certificates which are on the |system_slot|.
   certs.erase(
-      std::remove_if(
-          certs.begin(), certs.end(),
-          [system_slot_ptr](const scoped_refptr<net::X509Certificate>& cert) {
-            return !IsCertificateOnSlot(cert.get(), system_slot_ptr);
-          }),
+      std::remove_if(certs.begin(), certs.end(),
+                     [system_slot_ptr](const net::ScopedCERTCertificate& cert) {
+                       return !IsCertificateOnSlot(cert.get(), system_slot_ptr);
+                     }),
       certs.end());
   return certs;
 }
@@ -242,10 +240,10 @@
 }
 
 // static
-bool CertLoader::IsCertificateHardwareBacked(const net::X509Certificate* cert) {
+bool CertLoader::IsCertificateHardwareBacked(CERTCertificate* cert) {
   if (g_force_hardware_backed_for_test)
     return true;
-  PK11SlotInfo* slot = cert->os_cert_handle()->slot;
+  PK11SlotInfo* slot = cert->slot;
   return slot && PK11_IsHW(slot);
 }
 
@@ -273,14 +271,11 @@
 // is shared between a certificate and its associated private and public
 // keys.  I tried to implement this with PK11_GetLowLevelKeyIDForCert(),
 // but that always returns NULL on Chrome OS for me.
-std::string CertLoader::GetPkcs11IdAndSlotForCert(
-    const net::X509Certificate& cert,
-    int* slot_id) {
+std::string CertLoader::GetPkcs11IdAndSlotForCert(CERTCertificate* cert,
+                                                  int* slot_id) {
   DCHECK(slot_id);
 
-  CERTCertificateStr* cert_handle = cert.os_cert_handle();
-  SECKEYPrivateKey* priv_key =
-      PK11_FindKeyByAnyCert(cert_handle, nullptr /* wincx */);
+  SECKEYPrivateKey* priv_key = PK11_FindKeyByAnyCert(cert, nullptr /* wincx */);
   if (!priv_key)
     return std::string();
 
@@ -314,21 +309,29 @@
         FROM_HERE,
         {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
         base::BindOnce(&FilterSystemTokenCertificates,
-                       user_cert_cache_->cert_list(), std::move(system_slot)),
+                       net::x509_util::DupCERTCertificateList(
+                           user_cert_cache_->cert_list()),
+                       std::move(system_slot)),
         base::BindOnce(&CertLoader::UpdateCertificates,
                        weak_factory_.GetWeakPtr(),
-                       user_cert_cache_->cert_list()));
+                       net::x509_util::DupCERTCertificateList(
+                           user_cert_cache_->cert_list())));
   } else {
     // The user's cert cache does not contain system certificates.
-    net::CertificateList system_certs = system_cert_cache_->cert_list();
-    net::CertificateList all_certs = user_cert_cache_->cert_list();
-    all_certs.insert(all_certs.end(), system_certs.begin(), system_certs.end());
+    net::ScopedCERTCertificateList system_certs =
+        net::x509_util::DupCERTCertificateList(system_cert_cache_->cert_list());
+    net::ScopedCERTCertificateList all_certs =
+        net::x509_util::DupCERTCertificateList(user_cert_cache_->cert_list());
+    all_certs.reserve(all_certs.size() + system_certs.size());
+    for (const net::ScopedCERTCertificate& cert : system_certs)
+      all_certs.push_back(net::x509_util::DupCERTCertificate(cert.get()));
     UpdateCertificates(std::move(all_certs), std::move(system_certs));
   }
 }
 
-void CertLoader::UpdateCertificates(net::CertificateList all_certs,
-                                    net::CertificateList system_certs) {
+void CertLoader::UpdateCertificates(
+    net::ScopedCERTCertificateList all_certs,
+    net::ScopedCERTCertificateList system_certs) {
   CHECK(thread_checker_.CalledOnValidThread());
   bool initial_load = pending_initial_load_;
   pending_initial_load_ = false;
diff --git a/chromeos/cert_loader.h b/chromeos/cert_loader.h
index a3704ce..d54158720 100644
--- a/chromeos/cert_loader.h
+++ b/chromeos/cert_loader.h
@@ -15,11 +15,10 @@
 #include "base/observer_list.h"
 #include "base/threading/thread_checker.h"
 #include "chromeos/chromeos_export.h"
-#include "net/cert/x509_certificate.h"
+#include "net/cert/scoped_nss_types.h"
 
 namespace net {
 class NSSCertDatabase;
-typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
 }
 
 namespace chromeos {
@@ -43,8 +42,9 @@
     // have completed loading. |initial_load| is true the first time this
     // is called. It will be false if this is called because another slot has
     // been added to CertLoader's data sources.
-    virtual void OnCertificatesLoaded(const net::CertificateList& all_certs,
-                                      bool initial_load) = 0;
+    virtual void OnCertificatesLoaded(
+        const net::ScopedCERTCertificateList& all_certs,
+        bool initial_load) = 0;
 
    protected:
     virtual ~Observer() {}
@@ -66,7 +66,7 @@
   // hex string and sets |slot_id| to the id of the containing slot, or returns
   // an empty string and doesn't modify |slot_id| if the PKCS#11 id could not be
   // determined.
-  static std::string GetPkcs11IdAndSlotForCert(const net::X509Certificate& cert,
+  static std::string GetPkcs11IdAndSlotForCert(CERTCertificate* cert,
                                                int* slot_id);
 
   // Sets the NSS cert database which CertLoader should use to access system
@@ -90,7 +90,7 @@
 
   // Returns true if |cert| is hardware backed. See also
   // ForceHardwareBackedForTesting().
-  static bool IsCertificateHardwareBacked(const net::X509Certificate* cert);
+  static bool IsCertificateHardwareBacked(CERTCertificate* cert);
 
   // Returns true when the certificate list has been requested but not loaded.
   // When two databases are in use (SetSystemNSSDB and SetUserNSSDB have both
@@ -110,14 +110,14 @@
 
   // Returns all certificates. This will be empty until certificates_loaded() is
   // true.
-  const net::CertificateList& all_certs() const {
+  const net::ScopedCERTCertificateList& all_certs() const {
     DCHECK(thread_checker_.CalledOnValidThread());
     return all_certs_;
   }
 
   // Returns certificates from the system token. This will be empty until
   // certificates_loaded() is true.
-  const net::CertificateList& system_certs() const {
+  const net::ScopedCERTCertificateList& system_certs() const {
     DCHECK(thread_checker_.CalledOnValidThread());
     return system_certs_;
   }
@@ -137,8 +137,8 @@
   void CacheUpdated();
 
   // Called if a certificate load task is finished.
-  void UpdateCertificates(net::CertificateList all_certs,
-                          net::CertificateList system_certs);
+  void UpdateCertificates(net::ScopedCERTCertificateList all_certs,
+                          net::ScopedCERTCertificateList system_certs);
 
   void NotifyCertificatesLoaded(bool initial_load);
 
@@ -154,10 +154,10 @@
   std::unique_ptr<CertCache> user_cert_cache_;
 
   // Cached certificates loaded from the database(s).
-  net::CertificateList all_certs_;
+  net::ScopedCERTCertificateList all_certs_;
 
   // Cached certificates from system token.
-  net::CertificateList system_certs_;
+  net::ScopedCERTCertificateList system_certs_;
 
   base::ThreadChecker thread_checker_;
 
diff --git a/chromeos/cert_loader_unittest.cc b/chromeos/cert_loader_unittest.cc
index 1e8280b..1136c62 100644
--- a/chromeos/cert_loader_unittest.cc
+++ b/chromeos/cert_loader_unittest.cc
@@ -17,6 +17,7 @@
 #include "crypto/scoped_test_nss_db.h"
 #include "net/cert/nss_cert_database_chromeos.h"
 #include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,29 +25,24 @@
 namespace chromeos {
 namespace {
 
-bool IsCertInCertificateList(const net::X509Certificate* cert,
-                             const net::CertificateList& cert_list) {
-  for (net::CertificateList::const_iterator it = cert_list.begin();
-       it != cert_list.end();
-       ++it) {
-    if (net::X509Certificate::IsSameOSCert((*it)->os_cert_handle(),
-                                            cert->os_cert_handle())) {
+bool IsCertInCertificateList(CERTCertificate* cert,
+                             const net::ScopedCERTCertificateList& cert_list) {
+  for (net::ScopedCERTCertificateList::const_iterator it = cert_list.begin();
+       it != cert_list.end(); ++it) {
+    if (net::x509_util::IsSameCertificate(it->get(), cert))
       return true;
-    }
   }
   return false;
 }
 
 size_t CountCertOccurencesInCertificateList(
-    const net::X509Certificate* cert,
-    const net::CertificateList& cert_list) {
+    CERTCertificate* cert,
+    const net::ScopedCERTCertificateList& cert_list) {
   size_t count = 0;
-  for (net::CertificateList::const_iterator it = cert_list.begin();
+  for (net::ScopedCERTCertificateList::const_iterator it = cert_list.begin();
        it != cert_list.end(); ++it) {
-    if (net::X509Certificate::IsSameOSCert((*it)->os_cert_handle(),
-                                           cert->os_cert_handle())) {
+    if (net::x509_util::IsSameCertificate(it->get(), cert))
       ++count;
-    }
   }
   return count;
 }
@@ -121,7 +117,7 @@
 
   // CertLoader::Observer:
   // The test keeps count of times the observer method was called.
-  void OnCertificatesLoaded(const net::CertificateList& cert_list,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList& cert_list,
                             bool initial_load) override {
     EXPECT_TRUE(certificates_loaded_events_count_ == 0 || !initial_load);
     certificates_loaded_events_count_++;
@@ -147,13 +143,12 @@
 
   void ImportCACert(const std::string& cert_file,
                     net::NSSCertDatabase* database,
-                    net::CertificateList* imported_certs) {
+                    net::ScopedCERTCertificateList* imported_certs) {
     ASSERT_TRUE(database);
     ASSERT_TRUE(imported_certs);
 
-    *imported_certs = net::CreateCertificateListFromFile(
-        net::GetTestCertsDirectory(),
-        cert_file,
+    *imported_certs = net::CreateCERTCertificateListFromFile(
+        net::GetTestCertsDirectory(), cert_file,
         net::X509Certificate::FORMAT_AUTO);
     ASSERT_EQ(1U, imported_certs->size());
 
@@ -167,15 +162,15 @@
   // Import a client cert described by |test_cert| and key into a PKCS11 slot.
   // Then notify |database_to_notify| (which is presumably using that slot) that
   // new certificates are available.
-  scoped_refptr<net::X509Certificate> ImportClientCertAndKey(
+  net::ScopedCERTCertificate ImportClientCertAndKey(
       TestNSSCertDatabase* database_to_notify,
       PK11SlotInfo* slot_to_use,
       const TestClientCertWithKey& test_cert) {
     // Import a client cert signed by that CA.
-    scoped_refptr<net::X509Certificate> client_cert(
-        net::ImportClientCertAndKeyFromFile(
-            net::GetTestCertsDirectory(), test_cert.cert_pem_filename,
-            test_cert.key_pk8_filename, slot_to_use));
+    net::ScopedCERTCertificate client_cert;
+    net::ImportClientCertAndKeyFromFile(
+        net::GetTestCertsDirectory(), test_cert.cert_pem_filename,
+        test_cert.key_pk8_filename, slot_to_use, &client_cert);
     database_to_notify->NotifyObserversCertDBChanged();
     return client_cert;
   }
@@ -183,7 +178,7 @@
   // Import |TEST_CLIENT_CERT_1| into a PKCS11 slot. Then notify
   // |database_to_notify| (which is presumably using that slot) that new
   // certificates are avialable.
-  scoped_refptr<net::X509Certificate> ImportClientCertAndKey(
+  net::ScopedCERTCertificate ImportClientCertAndKey(
       TestNSSCertDatabase* database_to_notify,
       PK11SlotInfo* slot_to_use) {
     return ImportClientCertAndKey(database_to_notify, slot_to_use,
@@ -191,7 +186,7 @@
   }
 
   // Import a client cert into |database|'s private slot.
-  scoped_refptr<net::X509Certificate> ImportClientCertAndKey(
+  net::ScopedCERTCertificate ImportClientCertAndKey(
       TestNSSCertDatabase* database) {
     return ImportClientCertAndKey(database, database->GetPrivateSlot().get());
   }
@@ -276,12 +271,14 @@
 // which does not have access to the system token.
 TEST_F(CertLoaderTest, SystemAndUnaffiliatedUserDB) {
   CreateCertDatabase(&system_db_, &system_certdb_);
-  scoped_refptr<net::X509Certificate> system_token_cert(ImportClientCertAndKey(
+  net::ScopedCERTCertificate system_token_cert(ImportClientCertAndKey(
       system_certdb_.get(), system_db_.slot(), TEST_CLIENT_CERT_1));
+  ASSERT_TRUE(system_token_cert);
 
   CreateCertDatabase(&primary_db_, &primary_certdb_);
-  scoped_refptr<net::X509Certificate> user_token_cert(ImportClientCertAndKey(
+  net::ScopedCERTCertificate user_token_cert(ImportClientCertAndKey(
       primary_certdb_.get(), primary_db_.slot(), TEST_CLIENT_CERT_2));
+  ASSERT_TRUE(user_token_cert);
 
   scoped_task_environment_.RunUntilIdle();
 
@@ -331,12 +328,14 @@
 // which has access to the system token.
 TEST_F(CertLoaderTest, SystemAndAffiliatedUserDB) {
   CreateCertDatabase(&system_db_, &system_certdb_);
-  scoped_refptr<net::X509Certificate> system_token_cert(ImportClientCertAndKey(
+  net::ScopedCERTCertificate system_token_cert(ImportClientCertAndKey(
       system_certdb_.get(), system_db_.slot(), TEST_CLIENT_CERT_1));
+  ASSERT_TRUE(system_token_cert);
 
   CreateCertDatabase(&primary_db_, &primary_certdb_);
-  scoped_refptr<net::X509Certificate> user_token_cert(ImportClientCertAndKey(
+  net::ScopedCERTCertificate user_token_cert(ImportClientCertAndKey(
       primary_certdb_.get(), primary_db_.slot(), TEST_CLIENT_CERT_2));
+  ASSERT_TRUE(user_token_cert);
 
   AddSystemToken(primary_certdb_.get());
   scoped_task_environment_.RunUntilIdle();
@@ -386,7 +385,7 @@
 TEST_F(CertLoaderTest, CertLoaderUpdatesCertListOnNewCert) {
   StartCertLoaderWithPrimaryDB();
 
-  net::CertificateList certs;
+  net::ScopedCERTCertificateList certs;
   ImportCACert("root_ca_cert.pem", primary_certdb_.get(), &certs);
 
   // Certs are loaded asynchronously, so the new cert should not yet be in the
@@ -412,7 +411,7 @@
   StartCertLoaderWithPrimaryDB();
   CreateCertDatabase(&secondary_db, &secondary_certdb);
 
-  net::CertificateList certs;
+  net::ScopedCERTCertificateList certs;
   ImportCACert("root_ca_cert.pem", secondary_certdb.get(), &certs);
 
   scoped_task_environment_.RunUntilIdle();
@@ -424,8 +423,9 @@
 TEST_F(CertLoaderTest, ClientLoaderUpdateOnNewClientCert) {
   StartCertLoaderWithPrimaryDB();
 
-  scoped_refptr<net::X509Certificate> cert(
+  net::ScopedCERTCertificate cert(
       ImportClientCertAndKey(primary_certdb_.get()));
+  ASSERT_TRUE(cert);
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -438,8 +438,9 @@
   StartCertLoaderWithPrimaryDBAndSystemToken();
 
   EXPECT_TRUE(cert_loader_->system_certs().empty());
-  scoped_refptr<net::X509Certificate> cert(ImportClientCertAndKey(
+  net::ScopedCERTCertificate cert(ImportClientCertAndKey(
       primary_certdb_.get(), primary_certdb_->GetSystemSlot().get()));
+  ASSERT_TRUE(cert);
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -458,8 +459,9 @@
   StartCertLoaderWithPrimaryDB();
   CreateCertDatabase(&secondary_db, &secondary_certdb);
 
-  scoped_refptr<net::X509Certificate> cert(
+  net::ScopedCERTCertificate cert(
       ImportClientCertAndKey(secondary_certdb.get()));
+  ASSERT_TRUE(cert);
 
   scoped_task_environment_.RunUntilIdle();
 
@@ -469,8 +471,9 @@
 TEST_F(CertLoaderTest, UpdatedOnCertRemoval) {
   StartCertLoaderWithPrimaryDB();
 
-  scoped_refptr<net::X509Certificate> cert(
+  net::ScopedCERTCertificate cert(
       ImportClientCertAndKey(primary_certdb_.get()));
+  ASSERT_TRUE(cert);
 
   scoped_task_environment_.RunUntilIdle();
 
@@ -489,7 +492,7 @@
 TEST_F(CertLoaderTest, UpdatedOnCACertTrustChange) {
   StartCertLoaderWithPrimaryDB();
 
-  net::CertificateList certs;
+  net::ScopedCERTCertificateList certs;
   ImportCACert("root_ca_cert.pem", primary_certdb_.get(), &certs);
 
   scoped_task_environment_.RunUntilIdle();
diff --git a/chromeos/network/auto_connect_handler_unittest.cc b/chromeos/network/auto_connect_handler_unittest.cc
index 46d3a4c..981ef93 100644
--- a/chromeos/network/auto_connect_handler_unittest.cc
+++ b/chromeos/network/auto_connect_handler_unittest.cc
@@ -186,9 +186,10 @@
   }
 
   scoped_refptr<net::X509Certificate> ImportTestClientCert() {
-    net::CertificateList ca_cert_list = net::CreateCertificateListFromFile(
-        net::GetTestCertsDirectory(), "client_1_ca.pem",
-        net::X509Certificate::FORMAT_AUTO);
+    net::ScopedCERTCertificateList ca_cert_list =
+        net::CreateCERTCertificateListFromFile(
+            net::GetTestCertsDirectory(), "client_1_ca.pem",
+            net::X509Certificate::FORMAT_AUTO);
     if (ca_cert_list.empty()) {
       LOG(ERROR) << "No CA cert loaded.";
       return nullptr;
diff --git a/chromeos/network/certificate_helper.cc b/chromeos/network/certificate_helper.cc
index 8444faf3..b72cb86 100644
--- a/chromeos/network/certificate_helper.cc
+++ b/chromeos/network/certificate_helper.cc
@@ -13,6 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/url_formatter/url_formatter.h"
 #include "net/cert/nss_cert_database_chromeos.h"
+#include "net/cert/x509_util_nss.h"
 
 namespace chromeos {
 namespace certificate {
@@ -71,9 +72,8 @@
   return token;
 }
 
-std::string GetIssuerCommonName(CERTCertificate* cert_handle,
-                                const std::string& alternative_text) {
-  return Stringize(CERT_GetCommonName(&cert_handle->issuer), alternative_text);
+std::string GetIssuerDisplayName(CERTCertificate* cert_handle) {
+  return net::x509_util::GetCERTNameDisplayName(&cert_handle->issuer);
 }
 
 std::string GetCertNameOrNickname(CERTCertificate* cert_handle) {
diff --git a/chromeos/network/certificate_helper.h b/chromeos/network/certificate_helper.h
index b49a2ad1..28368118 100644
--- a/chromeos/network/certificate_helper.h
+++ b/chromeos/network/certificate_helper.h
@@ -23,11 +23,10 @@
 // string.
 CHROMEOS_EXPORT std::string GetCertTokenName(CERTCertificate* cert_handle);
 
-// Returns the common name for |cert_handle|->issuer or |alternative_text| if
-// the common name is missing or empty.
-CHROMEOS_EXPORT std::string GetIssuerCommonName(
-    CERTCertificate* cert_handle,
-    const std::string& alternative_text);
+// Returns a name that can be used to represent the issuer of |cert_handle|.
+// It tries in this order: CN, O and OU and returns the first non-empty one
+// found.
+CHROMEOS_EXPORT std::string GetIssuerDisplayName(CERTCertificate* cert_handle);
 
 // Returns the common name for |cert_handle|->subject converted to unicode,
 // or |cert_handle|->nickname if the subject name is unavailable or empty.
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index 3ae11c14..0c15109 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -73,9 +73,8 @@
 }
 
 // Returns true if a private key for certificate |cert| is installed.
-bool HasPrivateKey(const net::X509Certificate& cert) {
-  PK11SlotInfo* slot =
-      PK11_KeyForCertExists(cert.os_cert_handle(), nullptr, nullptr);
+bool HasPrivateKey(CERTCertificate* cert) {
+  PK11SlotInfo* slot = PK11_KeyForCertExists(cert, nullptr, nullptr);
   if (!slot)
     return false;
 
@@ -86,18 +85,20 @@
 // Describes a certificate which is issued by |issuer| (encoded as PEM).
 // |issuer| can be empty if no issuer certificate is found in the database.
 struct CertAndIssuer {
-  CertAndIssuer(const scoped_refptr<net::X509Certificate>& certificate,
+  CertAndIssuer(net::ScopedCERTCertificate certificate,
                 const std::string& issuer)
-      : cert(certificate),
-        pem_encoded_issuer(issuer) {}
+      : cert(std::move(certificate)), pem_encoded_issuer(issuer) {}
 
-  scoped_refptr<net::X509Certificate> cert;
+  net::ScopedCERTCertificate cert;
   std::string pem_encoded_issuer;
 };
 
-bool CompareCertExpiration(const CertAndIssuer& a,
-                           const CertAndIssuer& b) {
-  return (a.cert->valid_expiry() > b.cert->valid_expiry());
+bool CompareCertExpiration(const CertAndIssuer& a, const CertAndIssuer& b) {
+  base::Time a_not_after;
+  base::Time b_not_after;
+  net::x509_util::GetValidityTimes(a.cert.get(), nullptr, &a_not_after);
+  net::x509_util::GetValidityTimes(b.cert.get(), nullptr, &b_not_after);
+  return a_not_after > b_not_after;
 }
 
 // Describes a network that is configured with the certificate pattern
@@ -119,15 +120,22 @@
       : pattern(cert_pattern) {}
 
   bool operator()(const CertAndIssuer& cert_and_issuer) {
-    if (!pattern.issuer().Empty() &&
-        !client_cert::CertPrincipalMatches(pattern.issuer(),
-                                           cert_and_issuer.cert->issuer())) {
-      return false;
-    }
-    if (!pattern.subject().Empty() &&
-        !client_cert::CertPrincipalMatches(pattern.subject(),
-                                           cert_and_issuer.cert->subject())) {
-      return false;
+    if (!pattern.issuer().Empty() || !pattern.subject().Empty()) {
+      scoped_refptr<net::X509Certificate> x509_cert =
+          net::x509_util::CreateX509CertificateFromCERTCertificate(
+              cert_and_issuer.cert.get());
+      if (!x509_cert)
+        return false;
+      if (!pattern.issuer().Empty() &&
+          !client_cert::CertPrincipalMatches(pattern.issuer(),
+                                             x509_cert->issuer())) {
+        return false;
+      }
+      if (!pattern.subject().Empty() &&
+          !client_cert::CertPrincipalMatches(pattern.subject(),
+                                             x509_cert->subject())) {
+        return false;
+      }
     }
 
     const std::vector<std::string>& issuer_ca_pems = pattern.issuer_ca_pems();
@@ -143,18 +151,17 @@
 
 // Lookup the issuer certificate of |cert|. If it is available, return the PEM
 // encoding of that certificate. Otherwise return the empty string.
-std::string GetPEMEncodedIssuer(const net::X509Certificate& cert) {
+std::string GetPEMEncodedIssuer(CERTCertificate* cert) {
   net::ScopedCERTCertificate issuer_handle(
-      CERT_FindCertIssuer(cert.os_cert_handle(), PR_Now(), certUsageAnyCA));
+      CERT_FindCertIssuer(cert, PR_Now(), certUsageAnyCA));
   if (!issuer_handle) {
     VLOG(1) << "Couldn't find an issuer.";
     return std::string();
   }
 
   scoped_refptr<net::X509Certificate> issuer =
-      net::X509Certificate::CreateFromHandle(
-          issuer_handle.get(),
-          net::X509Certificate::OSCertHandles() /* no intermediate certs */);
+      net::x509_util::CreateX509CertificateFromCERTCertificate(
+          issuer_handle.get());
   if (!issuer.get()) {
     LOG(ERROR) << "Couldn't create issuer cert.";
     return std::string();
@@ -169,20 +176,22 @@
 }
 
 std::vector<CertAndIssuer> CreateSortedCertAndIssuerList(
-    const net::CertificateList& certs,
+    net::ScopedCERTCertificateList certs,
     base::Time now) {
   // Filter all client certs and determines each certificate's issuer, which is
   // required for the pattern matching.
   std::vector<CertAndIssuer> client_certs;
-  for (net::CertificateList::const_iterator it = certs.begin();
+  for (net::ScopedCERTCertificateList::iterator it = certs.begin();
        it != certs.end(); ++it) {
-    const net::X509Certificate& cert = **it;
-    if (cert.valid_expiry().is_null() || now > cert.valid_expiry() ||
-        !HasPrivateKey(cert) ||
-        !CertLoader::IsCertificateHardwareBacked(&cert)) {
+    CERTCertificate* cert = it->get();
+    base::Time not_after;
+    if (!net::x509_util::GetValidityTimes(cert, nullptr, &not_after) ||
+        now > not_after || !HasPrivateKey(cert) ||
+        !CertLoader::IsCertificateHardwareBacked(cert)) {
       continue;
     }
-    client_certs.push_back(CertAndIssuer(*it, GetPEMEncodedIssuer(cert)));
+    std::string pem_encoded_issuer = GetPEMEncodedIssuer(cert);
+    client_certs.push_back(CertAndIssuer(std::move(*it), pem_encoded_issuer));
   }
 
   std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration);
@@ -193,17 +202,17 @@
 // |matches|. Because this calls NSS functions and is potentially slow, it must
 // be run on a worker thread.
 std::unique_ptr<NetworkCertMatches> FindCertificateMatches(
-    const net::CertificateList& all_certs,
-    const net::CertificateList& system_certs,
+    net::ScopedCERTCertificateList all_certs,
+    net::ScopedCERTCertificateList system_certs,
     std::vector<NetworkAndCertPattern>* networks,
     base::Time now) {
   std::unique_ptr<NetworkCertMatches> matches =
       base::MakeUnique<NetworkCertMatches>();
 
   std::vector<CertAndIssuer> all_client_certs(
-      CreateSortedCertAndIssuerList(all_certs, now));
+      CreateSortedCertAndIssuerList(std::move(all_certs), now));
   std::vector<CertAndIssuer> system_client_certs(
-      CreateSortedCertAndIssuerList(system_certs, now));
+      CreateSortedCertAndIssuerList(std::move(system_certs), now));
 
   for (std::vector<NetworkAndCertPattern>::const_iterator it =
            networks->begin();
@@ -227,7 +236,7 @@
       // network.
     } else {
       pkcs11_id =
-          CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id);
+          CertLoader::GetPkcs11IdAndSlotForCert(cert_it->cert.get(), &slot_id);
       if (pkcs11_id.empty()) {
         LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
         // So far this error is not expected to happen. We can just continue, in
@@ -244,8 +253,7 @@
       size_t offset = identity.find(onc::substitutes::kCertSANEmail, 0);
       if (offset != std::string::npos) {
         std::vector<std::string> names;
-        net::x509_util::GetRFC822SubjectAltNames(
-            cert_it->cert->os_cert_handle(), &names);
+        net::x509_util::GetRFC822SubjectAltNames(cert_it->cert.get(), &names);
         if (!names.empty()) {
           base::ReplaceSubstringsAfterOffset(
               &identity, offset, onc::substitutes::kCertSANEmail, names[0]);
@@ -255,8 +263,7 @@
       offset = identity.find(onc::substitutes::kCertSANUPN, 0);
       if (offset != std::string::npos) {
         std::vector<std::string> names;
-        net::x509_util::GetUPNSubjectAltNames(cert_it->cert->os_cert_handle(),
-                                              &names);
+        net::x509_util::GetUPNSubjectAltNames(cert_it->cert.get(), &names);
         if (!names.empty()) {
           base::ReplaceSubstringsAfterOffset(
               &identity, offset, onc::substitutes::kCertSANUPN, names[0]);
@@ -343,11 +350,14 @@
   // system token if the source of the client cert pattern is device policy.
   std::vector<CertAndIssuer> client_certs;
   if (client_cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
-    client_certs = CreateSortedCertAndIssuerList(
-        CertLoader::Get()->system_certs(), base::Time::Now());
+    client_certs =
+        CreateSortedCertAndIssuerList(net::x509_util::DupCERTCertificateList(
+                                          CertLoader::Get()->system_certs()),
+                                      base::Time::Now());
   } else {
-    client_certs = CreateSortedCertAndIssuerList(CertLoader::Get()->all_certs(),
-                                                 base::Time::Now());
+    client_certs = CreateSortedCertAndIssuerList(
+        net::x509_util::DupCERTCertificateList(CertLoader::Get()->all_certs()),
+        base::Time::Now());
   }
 
   // Search for a certificate matching the pattern.
@@ -363,7 +373,7 @@
 
   int slot_id = -1;
   std::string pkcs11_id =
-      CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id);
+      CertLoader::GetPkcs11IdAndSlotForCert(cert_it->cert.get(), &slot_id);
   if (pkcs11_id.empty()) {
     LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
     // So far this error is not expected to happen. We can just continue, in
@@ -420,7 +430,7 @@
 }
 
 void ClientCertResolver::OnCertificatesLoaded(
-    const net::CertificateList& cert_list,
+    const net::ScopedCERTCertificateList& cert_list,
     bool initial_load) {
   VLOG(2) << "OnCertificatesLoaded.";
   if (!ClientCertificatesLoaded())
@@ -517,11 +527,14 @@
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE,
       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-      base::Bind(&FindCertificateMatches, CertLoader::Get()->all_certs(),
-                 CertLoader::Get()->system_certs(),
-                 base::Owned(networks_to_resolve.release()), Now()),
-      base::Bind(&ClientCertResolver::ConfigureCertificates,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&FindCertificateMatches,
+                     net::x509_util::DupCERTCertificateList(
+                         CertLoader::Get()->all_certs()),
+                     net::x509_util::DupCERTCertificateList(
+                         CertLoader::Get()->system_certs()),
+                     base::Owned(networks_to_resolve.release()), Now()),
+      base::BindOnce(&ClientCertResolver::ConfigureCertificates,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void ClientCertResolver::ResolvePendingNetworks() {
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h
index 669109c46..4c2f740 100644
--- a/chromeos/network/client_cert_resolver.h
+++ b/chromeos/network/client_cert_resolver.h
@@ -88,7 +88,7 @@
   void NetworkConnectionStateChanged(const NetworkState* network) override;
 
   // CertLoader::Observer overrides
-  void OnCertificatesLoaded(const net::CertificateList& cert_list,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList& cert_list,
                             bool initial_load) override;
 
   // NetworkPolicyObserver overrides
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 6f441d3b..4e3e7ea 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -33,6 +33,7 @@
 #include "net/base/net_errors.h"
 #include "net/cert/nss_cert_database_chromeos.h"
 #include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -101,8 +102,8 @@
     cert_loader_->SetUserNSSDB(test_nsscertdb_.get());
     if (test_client_cert_.get()) {
       int slot_id = 0;
-      const std::string pkcs11_id =
-          CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id);
+      const std::string pkcs11_id = CertLoader::GetPkcs11IdAndSlotForCert(
+          test_client_cert_.get(), &slot_id);
       test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str());
     }
   }
@@ -112,12 +113,12 @@
   // test_ca_cert_pem_) that issued the client certificate.
   void SetupTestCerts(const std::string& prefix, bool import_issuer) {
     // Load a CA cert.
-    net::CertificateList ca_cert_list = net::CreateCertificateListFromFile(
-        net::GetTestCertsDirectory(), prefix + "_ca.pem",
-        net::X509Certificate::FORMAT_AUTO);
+    net::ScopedCERTCertificateList ca_cert_list =
+        net::CreateCERTCertificateListFromFile(
+            net::GetTestCertsDirectory(), prefix + "_ca.pem",
+            net::X509Certificate::FORMAT_AUTO);
     ASSERT_TRUE(!ca_cert_list.empty());
-    net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(),
-                                        &test_ca_cert_pem_);
+    net::x509_util::GetPEMEncoded(ca_cert_list[0].get(), &test_ca_cert_pem_);
     ASSERT_TRUE(!test_ca_cert_pem_.empty());
 
     if (import_issuer) {
@@ -129,9 +130,9 @@
     }
 
     // Import a client cert signed by that CA.
-    test_client_cert_ = net::ImportClientCertAndKeyFromFile(
-        net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
-        test_nssdb_.slot());
+    net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
+                                        prefix + ".pem", prefix + ".pk8",
+                                        test_nssdb_.slot(), &test_client_cert_);
     ASSERT_TRUE(test_client_cert_.get());
   }
 
@@ -139,9 +140,9 @@
     test_nsscertdb_->SetSystemSlot(
         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
 
-    test_client_cert_ = net::ImportClientCertAndKeyFromFile(
+    net::ImportClientCertAndKeyFromFile(
         net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
-        test_system_nssdb_.slot());
+        test_system_nssdb_.slot(), &test_client_cert_);
     ASSERT_TRUE(test_client_cert_.get());
   }
 
@@ -327,7 +328,7 @@
   std::unique_ptr<NetworkConfigurationHandler> network_config_handler_;
   std::unique_ptr<ManagedNetworkConfigurationHandlerImpl>
       managed_config_handler_;
-  scoped_refptr<net::X509Certificate> test_client_cert_;
+  net::ScopedCERTCertificate test_client_cert_;
   std::string test_ca_cert_pem_;
   crypto::ScopedTestNSSDB test_nssdb_;
   crypto::ScopedTestNSSDB test_system_nssdb_;
diff --git a/chromeos/network/network_cert_migrator.cc b/chromeos/network/network_cert_migrator.cc
index cb9a4828..8273f1af 100644
--- a/chromeos/network/network_cert_migrator.cc
+++ b/chromeos/network/network_cert_migrator.cc
@@ -17,7 +17,7 @@
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "dbus/object_path.h"
-#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
@@ -36,11 +36,10 @@
 class NetworkCertMigrator::MigrationTask
     : public base::RefCounted<MigrationTask> {
  public:
-  MigrationTask(const net::CertificateList& certs,
+  MigrationTask(const net::ScopedCERTCertificateList& certs,
                 const base::WeakPtr<NetworkCertMigrator>& cert_migrator)
-      : certs_(certs),
-        cert_migrator_(cert_migrator) {
-  }
+      : certs_(net::x509_util::DupCERTCertificateList(certs)),
+        cert_migrator_(cert_migrator) {}
 
   void Run(const NetworkStateHandler::NetworkStateList& networks) {
     // Request properties for each network that could be configured with a
@@ -95,9 +94,9 @@
       return;
 
     int real_slot_id = -1;
-    scoped_refptr<net::X509Certificate> cert =
+    CERTCertificate* cert =
         FindCertificateWithPkcs11Id(pkcs11_id, &real_slot_id);
-    if (!cert.get()) {
+    if (!cert) {
       LOG(WARNING) << "No matching cert found, removing the certificate "
                       "configuration from network " << service_path;
       chromeos::client_cert::SetEmptyShillProperties(config_type,
@@ -109,7 +108,7 @@
       return;
     }
 
-    if (cert.get() && real_slot_id != configured_slot_id) {
+    if (cert && real_slot_id != configured_slot_id) {
       VLOG(1) << "Network " << service_path
               << " is configured with no or an incorrect slot id.";
       chromeos::client_cert::SetShillProperties(
@@ -117,16 +116,16 @@
     }
   }
 
-  scoped_refptr<net::X509Certificate> FindCertificateWithPkcs11Id(
-      const std::string& pkcs11_id, int* slot_id) {
+  CERTCertificate* FindCertificateWithPkcs11Id(const std::string& pkcs11_id,
+                                               int* slot_id) {
     *slot_id = -1;
-    for (scoped_refptr<net::X509Certificate> cert : certs_) {
+    for (const net::ScopedCERTCertificate& cert : certs_) {
       int current_slot_id = -1;
       std::string current_pkcs11_id =
-          CertLoader::GetPkcs11IdAndSlotForCert(*cert, &current_slot_id);
+          CertLoader::GetPkcs11IdAndSlotForCert(cert.get(), &current_slot_id);
       if (current_pkcs11_id == pkcs11_id) {
         *slot_id = current_slot_id;
-        return cert;
+        return cert.get();
       }
     }
     return nullptr;
@@ -155,7 +154,7 @@
   virtual ~MigrationTask() {
   }
 
-  net::CertificateList certs_;
+  net::ScopedCERTCertificateList certs_;
   base::WeakPtr<NetworkCertMigrator> cert_migrator_;
 };
 
@@ -200,7 +199,7 @@
 }
 
 void NetworkCertMigrator::OnCertificatesLoaded(
-    const net::CertificateList& cert_list,
+    const net::ScopedCERTCertificateList& cert_list,
     bool initial_load) {
   if (initial_load)
     NetworkListChanged();
diff --git a/chromeos/network/network_cert_migrator.h b/chromeos/network/network_cert_migrator.h
index d1bf51a..5bcb632 100644
--- a/chromeos/network/network_cert_migrator.h
+++ b/chromeos/network/network_cert_migrator.h
@@ -34,7 +34,7 @@
   void NetworkListChanged() override;
 
   // CertLoader::Observer overrides
-  void OnCertificatesLoaded(const net::CertificateList& cert_list,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList& cert_list,
                             bool initial_load) override;
 
   // Unowned associated NetworkStateHandler* (global or test instance).
diff --git a/chromeos/network/network_cert_migrator_unittest.cc b/chromeos/network/network_cert_migrator_unittest.cc
index 08d83af4..d466381 100644
--- a/chromeos/network/network_cert_migrator_unittest.cc
+++ b/chromeos/network/network_cert_migrator_unittest.cc
@@ -21,6 +21,7 @@
 #include "crypto/scoped_test_nss_db.h"
 #include "net/cert/nss_cert_database_chromeos.h"
 #include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -77,14 +78,14 @@
 
  protected:
   void SetupTestClientCert() {
-    test_client_cert_ = net::ImportClientCertAndKeyFromFile(
-        net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
-        test_nssdb_.slot());
+    net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
+                                        "client_1.pem", "client_1.pk8",
+                                        test_nssdb_.slot(), &test_client_cert_);
     ASSERT_TRUE(test_client_cert_.get());
 
     int slot_id = -1;
     test_client_cert_pkcs11_id_ = CertLoader::GetPkcs11IdAndSlotForCert(
-        *test_client_cert_, &slot_id);
+        test_client_cert_.get(), &slot_id);
     ASSERT_FALSE(test_client_cert_pkcs11_id_.empty());
     ASSERT_NE(-1, slot_id);
     test_client_cert_slot_id_ = base::IntToString(slot_id);
@@ -186,7 +187,7 @@
 
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   ShillServiceClient::TestInterface* service_test_;
-  scoped_refptr<net::X509Certificate> test_client_cert_;
+  net::ScopedCERTCertificate test_client_cert_;
   std::string test_client_cert_pkcs11_id_;
   std::string test_client_cert_slot_id_;
 
diff --git a/chromeos/network/network_certificate_handler.cc b/chromeos/network/network_certificate_handler.cc
index d40c566..d997f5a 100644
--- a/chromeos/network/network_certificate_handler.cc
+++ b/chromeos/network/network_certificate_handler.cc
@@ -8,6 +8,7 @@
 #include "base/strings/stringprintf.h"
 #include "chromeos/network/certificate_helper.h"
 #include "net/base/hash_value.h"
+#include "net/cert/x509_util_nss.h"
 
 namespace chromeos {
 
@@ -16,26 +17,17 @@
 // Root CA certificates that are built into Chrome use this token name.
 const char kRootCertificateTokenName[] = "Builtin Object Token";
 
-NetworkCertificateHandler::Certificate GetCertificate(
-    const net::X509Certificate& cert,
-    net::CertType type) {
+NetworkCertificateHandler::Certificate GetCertificate(CERTCertificate* cert,
+                                                      net::CertType type) {
   NetworkCertificateHandler::Certificate result;
 
-  result.hash = net::HashValue(net::X509Certificate::CalculateFingerprint256(
-                                   cert.os_cert_handle()))
-                    .ToString();
+  result.hash =
+      net::HashValue(net::x509_util::CalculateFingerprint256(cert)).ToString();
 
-  std::string alt_text;
-  if (!cert.subject().organization_names.empty())
-    alt_text = cert.subject().organization_names[0];
-  if (alt_text.empty())
-    alt_text = cert.subject().GetDisplayName();
-  result.issued_by =
-      certificate::GetIssuerCommonName(cert.os_cert_handle(), alt_text);
+  result.issued_by = certificate::GetIssuerDisplayName(cert);
 
-  result.issued_to = certificate::GetCertNameOrNickname(cert.os_cert_handle());
-  result.issued_to_ascii =
-      certificate::GetCertAsciiNameOrNickname(cert.os_cert_handle());
+  result.issued_to = certificate::GetCertNameOrNickname(cert);
+  result.issued_to_ascii = certificate::GetCertAsciiNameOrNickname(cert);
 
   if (type == net::USER_CERT) {
     int slot_id;
@@ -43,15 +35,14 @@
         CertLoader::GetPkcs11IdAndSlotForCert(cert, &slot_id);
     result.pkcs11_id = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str());
   } else if (type == net::CA_CERT) {
-    if (!net::X509Certificate::GetPEMEncoded(cert.os_cert_handle(),
-                                             &result.pem)) {
+    if (!net::x509_util::GetPEMEncoded(cert, &result.pem)) {
       LOG(ERROR) << "Unable to PEM-encode CA";
     }
   } else {
     NOTREACHED();
   }
 
-  result.hardware_backed = CertLoader::IsCertificateHardwareBacked(&cert);
+  result.hardware_backed = CertLoader::IsCertificateHardwareBacked(cert);
 
   return result;
 }
@@ -86,28 +77,27 @@
 }
 
 void NetworkCertificateHandler::OnCertificatesLoaded(
-    const net::CertificateList& cert_list,
+    const net::ScopedCERTCertificateList& cert_list,
     bool /* initial_load */) {
   ProcessCertificates(cert_list);
 }
 
 void NetworkCertificateHandler::ProcessCertificates(
-    const net::CertificateList& cert_list) {
+    const net::ScopedCERTCertificateList& cert_list) {
   user_certificates_.clear();
   server_ca_certificates_.clear();
 
   // Add certificates to the appropriate list.
   for (const auto& cert_ref : cert_list) {
-    const net::X509Certificate& cert = *cert_ref.get();
-    net::X509Certificate::OSCertHandle cert_handle = cert.os_cert_handle();
-    net::CertType type = certificate::GetCertType(cert_handle);
+    CERTCertificate* cert = cert_ref.get();
+    net::CertType type = certificate::GetCertType(cert);
     switch (type) {
       case net::USER_CERT:
         user_certificates_.push_back(GetCertificate(cert, type));
         break;
       case net::CA_CERT: {
         // Exclude root CA certificates that are built into Chrome.
-        std::string token_name = certificate::GetCertTokenName(cert_handle);
+        std::string token_name = certificate::GetCertTokenName(cert);
         if (token_name != kRootCertificateTokenName)
           server_ca_certificates_.push_back(GetCertificate(cert, type));
         else
@@ -126,7 +116,7 @@
 }
 
 void NetworkCertificateHandler::SetCertificatesForTest(
-    const net::CertificateList& cert_list) {
+    const net::ScopedCERTCertificateList& cert_list) {
   ProcessCertificates(cert_list);
 }
 
diff --git a/chromeos/network/network_certificate_handler.h b/chromeos/network/network_certificate_handler.h
index 41b107c..419a5df 100644
--- a/chromeos/network/network_certificate_handler.h
+++ b/chromeos/network/network_certificate_handler.h
@@ -72,15 +72,15 @@
     return user_certificates_;
   }
 
-  void SetCertificatesForTest(const net::CertificateList& cert_list);
+  void SetCertificatesForTest(const net::ScopedCERTCertificateList& cert_list);
   void NotifyCertificatsChangedForTest();
 
  private:
   // CertLoader::Observer
-  void OnCertificatesLoaded(const net::CertificateList& cert_list,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList& cert_list,
                             bool initial_load) override;
 
-  void ProcessCertificates(const net::CertificateList& cert_list);
+  void ProcessCertificates(const net::ScopedCERTCertificateList& cert_list);
 
   base::ObserverList<NetworkCertificateHandler::Observer> observer_list_;
 
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc
index 22bbeca9..963d209 100644
--- a/chromeos/network/network_connection_handler_impl.cc
+++ b/chromeos/network/network_connection_handler_impl.cc
@@ -175,7 +175,7 @@
 }
 
 void NetworkConnectionHandlerImpl::OnCertificatesLoaded(
-    const net::CertificateList& cert_list,
+    const net::ScopedCERTCertificateList& cert_list,
     bool initial_load) {
   certificates_loaded_ = true;
   NET_LOG_EVENT("Certificates Loaded", "");
diff --git a/chromeos/network/network_connection_handler_impl.h b/chromeos/network/network_connection_handler_impl.h
index 2027ead7..946e479 100644
--- a/chromeos/network/network_connection_handler_impl.h
+++ b/chromeos/network/network_connection_handler_impl.h
@@ -45,7 +45,7 @@
   void LoggedInStateChanged() override;
 
   // CertLoader::Observer
-  void OnCertificatesLoaded(const net::CertificateList& cert_list,
+  void OnCertificatesLoaded(const net::ScopedCERTCertificateList& cert_list,
                             bool initial_load) override;
 
  protected:
diff --git a/chromeos/network/network_connection_handler_impl_unittest.cc b/chromeos/network/network_connection_handler_impl_unittest.cc
index 1a8550b..bfa402df 100644
--- a/chromeos/network/network_connection_handler_impl_unittest.cc
+++ b/chromeos/network/network_connection_handler_impl_unittest.cc
@@ -254,9 +254,10 @@
   }
 
   scoped_refptr<net::X509Certificate> ImportTestClientCert() {
-    net::CertificateList ca_cert_list(net::CreateCertificateListFromFile(
-        net::GetTestCertsDirectory(), "client_1_ca.pem",
-        net::X509Certificate::FORMAT_AUTO));
+    net::ScopedCERTCertificateList ca_cert_list =
+        net::CreateCERTCertificateListFromFile(
+            net::GetTestCertsDirectory(), "client_1_ca.pem",
+            net::X509Certificate::FORMAT_AUTO);
     if (ca_cert_list.empty()) {
       LOG(ERROR) << "No CA cert loaded.";
       return nullptr;
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 1c3342e..d57adf4 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -436,6 +436,7 @@
       "$root_out_dir/content_shell.pak",
       "test/data/",
       "dom_distiller/core/javascript/",
+      "security_state/content/testdata/",
       "//third_party/dom_distiller_js/dist/test/data/",
     ]
 
diff --git a/components/cast_channel/cast_socket.cc b/components/cast_channel/cast_socket.cc
index 676ece01..0b9e88e 100644
--- a/components/cast_channel/cast_socket.cc
+++ b/components/cast_channel/cast_socket.cc
@@ -576,6 +576,8 @@
 
   VLOG_WITH_CONNECTION(1) << "Close ReadyState = "
                           << ReadyStateToString(ready_state_);
+  observers_.Clear();
+  delegate_.reset();
   transport_.reset();
   tcp_socket_.reset();
   socket_.reset();
diff --git a/components/omnibox/browser/contextual_suggestions_service.cc b/components/omnibox/browser/contextual_suggestions_service.cc
index 843cdae..2bc9a34 100644
--- a/components/omnibox/browser/contextual_suggestions_service.cc
+++ b/components/omnibox/browser/contextual_suggestions_service.cc
@@ -5,9 +5,11 @@
 #include "components/omnibox/browser/contextual_suggestions_service.h"
 
 #include "base/feature_list.h"
+#include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/stringprintf.h"
+#include "base/values.h"
 #include "components/data_use_measurement/core/data_use_user_data.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/search_engines/template_url_service.h"
@@ -23,7 +25,42 @@
 
 // Server address for the experimental suggestions service.
 const char kExperimentalServerAddress[] =
-    "https://cuscochromeextension-pa.googleapis.com/v1/zerosuggestions";
+    "https://cuscochromeextension-pa.googleapis.com/v1/omniboxsuggestions";
+
+void AddVariationHeaders(std::unique_ptr<net::URLFetcher>& fetcher) {
+  net::HttpRequestHeaders headers;
+  // Add Chrome experiment state to the request headers.
+  // Note: It's OK to pass |is_signed_in| false if it's unknown, as it does
+  // not affect transmission of experiments coming from the variations server.
+  //
+  // Note: It's OK to pass |is_incognito| false since we are expected to be in
+  // non-incognito state here (i.e. contextual sugestions are not served in
+  // incognito mode).
+  variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
+                                     /*incognito=*/false, /*uma_enabled=*/false,
+                                     /*is_signed_in=*/false, &headers);
+  for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
+    fetcher->AddExtraRequestHeader(it.name() + ":" + it.value());
+  }
+}
+
+std::string FormatRequestBodyExperimentalService(const std::string& url) {
+  auto request = base::MakeUnique<base::DictionaryValue>();
+  auto url_list = base::MakeUnique<base::ListValue>();
+  auto url_entry = base::MakeUnique<base::DictionaryValue>();
+  url_entry->SetString("url", url);
+  url_list->Append(std::move(url_entry));
+  request->Set("urls", std::move(url_list));
+  // stream_type = 1 corresponds to zero suggest suggestions.
+  request->SetInteger("stream_type", 1);
+  const int experiment_id =
+      OmniboxFieldTrial::GetZeroSuggestRedirectToChromeExperimentId();
+  if (experiment_id >= 0)
+    request->SetInteger("experiment_id", experiment_id);
+  std::string result;
+  base::JSONWriter::Write(*request, &result);
+  return result;
+}
 
 }  // namespace
 
@@ -44,35 +81,13 @@
     net::URLFetcherDelegate* fetcher_delegate,
     ContextualSuggestionsCallback callback) {
   const GURL experimental_suggest_url =
-      ExperimentalZeroSuggestURL(current_url, template_url_service);
-  const bool is_experimental = experimental_suggest_url.is_valid();
-  const GURL suggest_url =
-      is_experimental
-          ? experimental_suggest_url
-          : ContextualSuggestionsUrl(current_url, template_url_service);
-
-  std::unique_ptr<net::URLFetcher> fetcher =
-      CreateRequest(suggest_url, is_experimental, fetcher_delegate);
-
-  const bool should_fetch_access_token = is_experimental &&
-                                         (signin_manager_ != nullptr) &&
-                                         (token_service_ != nullptr);
-  // If authentication services are unavailable or if this request is still
-  // waiting for an oauth2 token, run the contextual service without access
-  // tokens.
-  if (!should_fetch_access_token || (token_fetcher_ != nullptr)) {
-    std::move(callback).Run(std::move(fetcher));
-    return;
-  }
-
-  // Create the oauth2 token fetcher.
-  const OAuth2TokenService::ScopeSet scopes{
-      "https://www.googleapis.com/auth/cusco-chrome-extension"};
-  token_fetcher_ = base::MakeUnique<AccessTokenFetcher>(
-      "contextual_suggestions_service", signin_manager_, token_service_, scopes,
-      base::BindOnce(&ContextualSuggestionsService::AccessTokenAvailable,
-                     base::Unretained(this), std::move(fetcher),
-                     std::move(callback)));
+      ExperimentalContextualSuggestionsUrl(current_url, template_url_service);
+  if (experimental_suggest_url.is_valid())
+    CreateExperimentalRequest(current_url, experimental_suggest_url,
+                              fetcher_delegate, std::move(callback));
+  else
+    CreateDefaultRequest(current_url, template_url_service, fetcher_delegate,
+                         std::move(callback));
 }
 
 void ContextualSuggestionsService::StopCreatingContextualSuggestionsRequest() {
@@ -107,7 +122,7 @@
                                                     search_terms_data));
 }
 
-GURL ContextualSuggestionsService::ExperimentalZeroSuggestURL(
+GURL ContextualSuggestionsService::ExperimentalContextualSuggestionsUrl(
     const std::string& current_url,
     const TemplateURLService* template_url_service) const {
   if (current_url.empty()) {
@@ -129,21 +144,7 @@
     return GURL();
   }
 
-  // Assemble the actual suggest URL.
-  const std::string server_address(kExperimentalServerAddress);
-  const int experiment_id =
-      OmniboxFieldTrial::GetZeroSuggestRedirectToChromeExperimentId();
-  // The experimental suggest endpoint does not handle URLs terminating with a
-  // slash properly, causing some urls like http://example.com/some/path/ to
-  // lose the last slash, which changes the URL. If we add an extra ampersand,
-  // as in the else case here it handles the URL properly.
-  const std::string additional_parameters =
-      (experiment_id >= 0)
-          ? base::StringPrintf("&experiment_id=%d", experiment_id)
-          : "&";
-  GURL suggest_url(server_address + "/url=" + net::EscapePath(current_url) +
-                   additional_parameters);
-
+  GURL suggest_url(kExperimentalServerAddress);
   // Check that the suggest URL for redirect to chrome field trial is valid.
   if (!suggest_url.is_valid()) {
     return GURL();
@@ -157,16 +158,19 @@
   return suggest_url;
 }
 
-std::unique_ptr<net::URLFetcher> ContextualSuggestionsService::CreateRequest(
+void ContextualSuggestionsService::CreateExperimentalRequest(
+    const std::string& current_url,
     const GURL& suggest_url,
-    bool is_experimental,
-    net::URLFetcherDelegate* fetcher_delegate) const {
+    net::URLFetcherDelegate* fetcher_delegate,
+    ContextualSuggestionsCallback callback) {
   DCHECK(suggest_url.is_valid());
 
-  net::NetworkTrafficAnnotationTag annotation_tag =
-      is_experimental
-          ? net::DefineNetworkTrafficAnnotation(
-                "omnibox_zerosuggest_experimental", R"(
+  // This traffic annotation is nearly identic to the annotation for
+  // `omnibox_zerosuggest`. The main difference is that the experimental traffic
+  // is not allowed cookies.
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("omnibox_zerosuggest_experimental",
+                                          R"(
         semantics {
           sender: "Omnibox"
           description:
@@ -192,8 +196,52 @@
                 SearchSuggestEnabled: false
             }
           }
-        })")
-          : net::DefineNetworkTrafficAnnotation("omnibox_zerosuggest", R"(
+        })");
+  const int kFetcherID = 1;
+  std::string request_body = FormatRequestBodyExperimentalService(current_url);
+  std::unique_ptr<net::URLFetcher> fetcher =
+      net::URLFetcher::Create(kFetcherID, suggest_url,
+                              /*request_type=*/net::URLFetcher::POST,
+                              fetcher_delegate, traffic_annotation);
+  fetcher->SetUploadData("application/json", request_body);
+  fetcher->SetRequestContext(request_context_);
+  data_use_measurement::DataUseUserData::AttachToFetcher(
+      fetcher.get(), data_use_measurement::DataUseUserData::OMNIBOX);
+  AddVariationHeaders(fetcher);
+  fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
+                        net::LOAD_DO_NOT_SAVE_COOKIES);
+
+  const bool should_fetch_access_token =
+      (signin_manager_ != nullptr) && (token_service_ != nullptr);
+  // If authentication services are unavailable or if this request is still
+  // waiting for an oauth2 token, run the contextual service without access
+  // tokens.
+  if (!should_fetch_access_token || (token_fetcher_ != nullptr)) {
+    std::move(callback).Run(std::move(fetcher));
+    return;
+  }
+
+  // Create the oauth2 token fetcher.
+  const OAuth2TokenService::ScopeSet scopes{
+      "https://www.googleapis.com/auth/cusco-chrome-extension"};
+  token_fetcher_ = base::MakeUnique<AccessTokenFetcher>(
+      "contextual_suggestions_service", signin_manager_, token_service_, scopes,
+      base::BindOnce(&ContextualSuggestionsService::AccessTokenAvailable,
+                     base::Unretained(this), std::move(fetcher),
+                     std::move(callback)));
+}
+
+void ContextualSuggestionsService::CreateDefaultRequest(
+    const std::string& current_url,
+    const TemplateURLService* template_url_service,
+    net::URLFetcherDelegate* fetcher_delegate,
+    ContextualSuggestionsCallback callback) {
+  const GURL suggest_url =
+      ContextualSuggestionsUrl(current_url, template_url_service);
+  DCHECK(suggest_url.is_valid());
+
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("omnibox_zerosuggest", R"(
         semantics {
           sender: "Omnibox"
           description:
@@ -221,34 +269,17 @@
             }
           }
         })");
-
   const int kFetcherID = 1;
   std::unique_ptr<net::URLFetcher> fetcher =
       net::URLFetcher::Create(kFetcherID, suggest_url, net::URLFetcher::GET,
-                              fetcher_delegate, annotation_tag);
+                              fetcher_delegate, traffic_annotation);
   fetcher->SetRequestContext(request_context_);
   data_use_measurement::DataUseUserData::AttachToFetcher(
       fetcher.get(), data_use_measurement::DataUseUserData::OMNIBOX);
+  AddVariationHeaders(fetcher);
+  fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
 
-  // Add Chrome experiment state to the request headers.
-  net::HttpRequestHeaders headers;
-  // Note: It's OK to pass |is_signed_in| false if it's unknown, as it does
-  // not affect transmission of experiments coming from the variations server.
-  variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
-                                     /*incognito=*/false, /*uma_enabled=*/false,
-                                     /*is_signed_in=*/false, &headers);
-  for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
-    fetcher->AddExtraRequestHeader(it.name() + ":" + it.value());
-  }
-
-  if (is_experimental) {
-    fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
-                          net::LOAD_DO_NOT_SAVE_COOKIES);
-  } else {
-    fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
-  }
-
-  return fetcher;
+  std::move(callback).Run(std::move(fetcher));
 }
 
 void ContextualSuggestionsService::AccessTokenAvailable(
diff --git a/components/omnibox/browser/contextual_suggestions_service.h b/components/omnibox/browser/contextual_suggestions_service.h
index 63175afc..a309204c 100644
--- a/components/omnibox/browser/contextual_suggestions_service.h
+++ b/components/omnibox/browser/contextual_suggestions_service.h
@@ -90,17 +90,31 @@
   //   URL or personal data in unencrypted network traffic.
   // Note: these checks are in addition to CanSendUrl() on the default
   // contextual suggestion URL.
-  GURL ExperimentalZeroSuggestURL(
+  GURL ExperimentalContextualSuggestionsUrl(
       const std::string& current_url,
       const TemplateURLService* template_url_service) const;
 
-  // Creates an HTTP GET request for contextual suggestions. The returned
-  // fetcher does not include a header corresponding with an authorization
-  // token.
-  std::unique_ptr<net::URLFetcher> CreateRequest(
-      const GURL& suggest_url,
-      bool is_experimental,
-      net::URLFetcherDelegate* fetcher_delegate) const;
+  // Upon succesfull creation of an HTTP GET request for default contextual
+  // suggestions, the |callback| function is run with the HTTP GET request as a
+  // parameter.
+  //
+  // This function is called by CreateContextualSuggestionsRequest. See its
+  // function definition for details on the parameters.
+  void CreateDefaultRequest(const std::string& current_url,
+                            const TemplateURLService* template_url_service,
+                            net::URLFetcherDelegate* fetcher_delegate,
+                            ContextualSuggestionsCallback callback);
+
+  // Upon succesfull creation of an HTTP POST request for default contextual
+  // suggestions, the |callback| function is run with the HTTP POST request as a
+  // parameter.
+  //
+  // This function is called by CreateContextualSuggestionsRequest. See its
+  // function definition for details on the parameters.
+  void CreateExperimentalRequest(const std::string& current_url,
+                                 const GURL& suggest_url,
+                                 net::URLFetcherDelegate* fetcher_delegate,
+                                 ContextualSuggestionsCallback callback);
 
   // Called when an access token request completes (successfully or not).
   void AccessTokenAvailable(std::unique_ptr<net::URLFetcher> fetcher,
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 00c04a4..55c695ab 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -1311,6 +1311,8 @@
   pending_credentials_.username_value = submitted_form_->username_value;
   pending_credentials_.other_possible_usernames =
       submitted_form_->other_possible_usernames;
+  pending_credentials_.other_possible_passwords =
+      submitted_form_->other_possible_passwords;
 
   // The password value will be filled in later, remove any garbage for now.
   pending_credentials_.password_value.clear();
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 53648b56..b19564d 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -1603,6 +1603,22 @@
               UnorderedElementsAre(kUsernameDuplicate, kUsernameRandom));
 }
 
+TEST_F(PasswordFormManagerTest, TestOtherPossiblePasswords) {
+  fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+
+  PasswordForm credentials(*observed_form());
+  credentials.other_possible_passwords.push_back(ASCIIToUTF16("pass1"));
+  credentials.other_possible_passwords.push_back(ASCIIToUTF16("pass2"));
+  credentials.other_possible_passwords.push_back(ASCIIToUTF16("pass3"));
+
+  form_manager()->ProvisionallySave(
+      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+
+  EXPECT_THAT(form_manager()->pending_credentials().other_possible_passwords,
+              UnorderedElementsAre(ASCIIToUTF16("pass1"), ASCIIToUTF16("pass2"),
+                                   ASCIIToUTF16("pass3")));
+}
+
 // Test that if metadata stored with a form in PasswordStore are incomplete,
 // they are updated upon the next encounter.
 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
diff --git a/components/safe_browsing/browser/base_parallel_resource_throttle.cc b/components/safe_browsing/browser/base_parallel_resource_throttle.cc
index 58399344..12396189 100644
--- a/components/safe_browsing/browser/base_parallel_resource_throttle.cc
+++ b/components/safe_browsing/browser/base_parallel_resource_throttle.cc
@@ -69,7 +69,6 @@
     const net::RedirectInfo& redirect_info,
     bool* defer) {
   url_loader_throttle_->WillRedirectRequest(redirect_info, defer);
-  DCHECK(!*defer);
 }
 
 void BaseParallelResourceThrottle::WillProcessResponse(bool* defer) {
diff --git a/components/safe_browsing/browser/browser_url_loader_throttle.cc b/components/safe_browsing/browser/browser_url_loader_throttle.cc
index de7a14e..0fd6369 100644
--- a/components/safe_browsing/browser/browser_url_loader_throttle.cc
+++ b/components/safe_browsing/browser/browser_url_loader_throttle.cc
@@ -66,9 +66,13 @@
 void BrowserURLLoaderThrottle::WillRedirectRequest(
     const net::RedirectInfo& redirect_info,
     bool* defer) {
-  // If |blocked_| is true, the resource load has been canceled and there
-  // shouldn't be such a notification.
-  DCHECK(!blocked_);
+  if (blocked_) {
+    // OnCheckUrlResult() has set |blocked_| to true and called
+    // |delegate_->CancelWithError|, but this method is called before the
+    // request is actually cancelled. In that case, simply defer the request.
+    *defer = true;
+    return;
+  }
 
   pending_checks_++;
   url_checker_->CheckUrl(
@@ -78,9 +82,13 @@
 }
 
 void BrowserURLLoaderThrottle::WillProcessResponse(bool* defer) {
-  // If |blocked_| is true, the resource load has been canceled and there
-  // shouldn't be such a notification.
-  DCHECK(!blocked_);
+  if (blocked_) {
+    // OnCheckUrlResult() has set |blocked_| to true and called
+    // |delegate_->CancelWithError|, but this method is called before the
+    // request is actually cancelled. In that case, simply defer the request.
+    *defer = true;
+    return;
+  }
 
   if (pending_checks_ == 0) {
     LogDelay(base::TimeDelta());
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
index 4e5146e..c255490 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
@@ -17,12 +17,22 @@
      * Immutable holder for profile data.
      */
     class ProfileData {
+        // TODO(bsazonov): remove @Nullable after removing ctor without this parameter.
+        private final @Nullable String mAccountName;
+
         private final @Nullable Bitmap mAvatar;
         private final @Nullable String mFullName;
         private final @Nullable String mGivenName;
 
+        @Deprecated
         public ProfileData(
                 @Nullable Bitmap avatar, @Nullable String fullName, @Nullable String givenName) {
+            this(null, avatar, fullName, givenName);
+        }
+
+        public ProfileData(String accountName, @Nullable Bitmap avatar, @Nullable String fullName,
+                @Nullable String givenName) {
+            this.mAccountName = accountName;
             this.mAvatar = avatar;
             this.mFullName = fullName;
             this.mGivenName = givenName;
diff --git a/components/viz/host/hit_test/hit_test_query.cc b/components/viz/host/hit_test/hit_test_query.cc
index 2faf20c..438c7b4 100644
--- a/components/viz/host/hit_test/hit_test_query.cc
+++ b/components/viz/host/hit_test/hit_test_query.cc
@@ -7,6 +7,15 @@
 #include "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom.h"
 
 namespace viz {
+namespace {
+
+// If we want to add new source type here, consider switching to use
+// ui::EventPointerType instead of EventSource.
+bool ShouldUseTouchBounds(EventSource event_source) {
+  return event_source == EventSource::TOUCH;
+}
+
+}  // namespace
 
 HitTestQuery::HitTestQuery() = default;
 
@@ -41,17 +50,19 @@
 }
 
 Target HitTestQuery::FindTargetForLocation(
+    EventSource event_source,
     const gfx::Point& location_in_root) const {
   Target target;
   if (!active_hit_test_list_size_)
     return target;
 
-  FindTargetInRegionForLocation(location_in_root, active_hit_test_list_,
-                                &target);
+  FindTargetInRegionForLocation(event_source, location_in_root,
+                                active_hit_test_list_, &target);
   return target;
 }
 
 bool HitTestQuery::FindTargetInRegionForLocation(
+    EventSource event_source,
     const gfx::Point& location_in_parent,
     AggregatedHitTestRegion* region,
     Target* target) const {
@@ -71,8 +82,8 @@
   gfx::Point location_in_target(location_transformed);
   location_in_target.Offset(-region->rect.x(), -region->rect.y());
   while (child_region < child_region_end) {
-    if (FindTargetInRegionForLocation(location_in_target, child_region,
-                                      target)) {
+    if (FindTargetInRegionForLocation(event_source, location_in_target,
+                                      child_region, target)) {
       return true;
     }
 
@@ -83,7 +94,11 @@
     child_region = child_region + child_region->child_count + 1;
   }
 
-  if (region->flags & mojom::kHitTestMine) {
+  bool match_touch_or_mouse_region =
+      ShouldUseTouchBounds(event_source)
+          ? (region->flags & mojom::kHitTestTouch) != 0u
+          : (region->flags & mojom::kHitTestMouse) != 0u;
+  if ((region->flags & mojom::kHitTestMine) && match_touch_or_mouse_region) {
     target->frame_sink_id = region->frame_sink_id;
     target->location_in_target = location_in_target;
     target->flags = region->flags;
diff --git a/components/viz/host/hit_test/hit_test_query.h b/components/viz/host/hit_test/hit_test_query.h
index a99f745..ee02e90d 100644
--- a/components/viz/host/hit_test/hit_test_query.h
+++ b/components/viz/host/hit_test/hit_test_query.h
@@ -24,6 +24,11 @@
   uint32_t flags = 0;
 };
 
+enum class EventSource {
+  MOUSE,
+  TOUCH,
+};
+
 // Finds the target for a given location based on the AggregatedHitTestRegion
 // list aggregated by HitTestAggregator.
 // TODO(riajiang): Handle 3d space cases correctly.
@@ -71,13 +76,15 @@
   // then we get 2 in the coordinate system of a; apply the
   // transfrom-from-e-to-c and transform-from-c-to-b then we get 3 in the
   // coordinate system of b.
-  Target FindTargetForLocation(const gfx::Point& location_in_root) const;
+  Target FindTargetForLocation(EventSource event_source,
+                               const gfx::Point& location_in_root) const;
 
  private:
   // Helper function to find |target| for |location_in_parent| in the |region|,
   // returns true if a target is found and false otherwise. |location_in_parent|
   // is in the coordinate space of |region|'s parent.
-  bool FindTargetInRegionForLocation(const gfx::Point& location_in_parent,
+  bool FindTargetInRegionForLocation(EventSource event_source,
+                                     const gfx::Point& location_in_parent,
                                      AggregatedHitTestRegion* region,
                                      Target* target) const;
 
diff --git a/components/viz/host/hit_test/hit_test_query_unittest.cc b/components/viz/host/hit_test/hit_test_query_unittest.cc
index 7b1101a..2e40e3f 100644
--- a/components/viz/host/hit_test/hit_test_query_unittest.cc
+++ b/components/viz/host/hit_test/hit_test_query_unittest.cc
@@ -59,30 +59,34 @@
   gfx::Transform transform_e_to_e;
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds, transform_e_to_e, 0);  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds, transform_e_to_e, 0);  // e
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
   gfx::Point point2(600, 600);
   gfx::Point point3(0, 0);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
   // point2 is on the bounds of e so no target found.
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target2.location_in_target, gfx::Point());
   EXPECT_FALSE(target2.flags);
 
   // There's a valid Target for point3, see Rect::Contains.
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, e_id);
   EXPECT_EQ(target3.location_in_target, point3);
-  EXPECT_EQ(target3.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // One embedder with two children.
@@ -106,12 +110,15 @@
   transform_e_to_c2.Translate(-300, -300);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 2);  // e
-  aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
-      c1_id, mojom::kHitTestMine, c1_bounds_in_e, transform_e_to_c1, 0);  // c1
-  aggregated_hit_test_region_list[2] = AggregatedHitTestRegion(
-      c2_id, mojom::kHitTestMine, c2_bounds_in_e, transform_e_to_c2, 0);  // c2
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 2);  // e
+  aggregated_hit_test_region_list[1] =
+      AggregatedHitTestRegion(c1_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c1_bounds_in_e, transform_e_to_c1, 0);  // c1
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(c2_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c2_bounds_in_e, transform_e_to_c2, 0);  // c2
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(99, 200);
@@ -119,22 +126,26 @@
   gfx::Point point3(400, 400);
   gfx::Point point4(650, 350);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, c1_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(50, 50));
-  EXPECT_EQ(target2.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, c2_id);
   EXPECT_EQ(target3.location_in_target, gfx::Point(100, 100));
-  EXPECT_EQ(target3.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target4.location_in_target, gfx::Point());
   EXPECT_FALSE(target4.flags);
@@ -152,25 +163,28 @@
   transform_e_to_c.Scale(.5f, .7f);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 1);  // e
-  aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
-      c_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c_bounds_in_e,
-      transform_e_to_c, 0);  // c
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 1);  // e
+  aggregated_hit_test_region_list[1] =
+      AggregatedHitTestRegion(c_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c_bounds_in_e, transform_e_to_c, 0);  // c
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(150, 120);  // Point(-22, -12) after transform.
   gfx::Point point2(550, 400);  // Point(185, 194) after transform.
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, c_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(185, 194));
-  EXPECT_EQ(target2.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // One embedder with a clipped child with a tab and transparent background.
@@ -199,17 +213,18 @@
   transform_c_to_b.Translate(0, -100);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3);  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 3);  // e
   aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
       c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
       transform_e_to_c, 2);  // c
-  aggregated_hit_test_region_list[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
-      transform_c_to_a, 0);  // a
-  aggregated_hit_test_region_list[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
-      transform_c_to_b, 0);  // b
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c, transform_c_to_a, 0);  // a
+  aggregated_hit_test_region_list[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c, transform_c_to_b, 0);  // b
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -217,25 +232,29 @@
   gfx::Point point3(403, 103);
   gfx::Point point4(202, 202);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, a_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target2.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, e_id);
   EXPECT_EQ(target3.location_in_target, point3);
-  EXPECT_EQ(target3.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, b_id);
   EXPECT_EQ(target4.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target4.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target4.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // One embedder with a clipped child with a tab and transparent background, and
@@ -269,20 +288,21 @@
   transform_e_to_d.Translate(-400, -50);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 4);  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 4);  // e
   aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
       c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
       transform_e_to_c, 2);  // c
-  aggregated_hit_test_region_list[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
-      transform_c_to_a, 0);  // a
-  aggregated_hit_test_region_list[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
-      transform_c_to_b, 0);  // b
-  aggregated_hit_test_region_list[4] = AggregatedHitTestRegion(
-      d_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, d_bounds_in_e,
-      transform_e_to_d, 0);  // d
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c, transform_c_to_a, 0);  // a
+  aggregated_hit_test_region_list[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c, transform_c_to_b, 0);  // b
+  aggregated_hit_test_region_list[4] =
+      AggregatedHitTestRegion(d_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              d_bounds_in_e, transform_e_to_d, 0);  // d
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -290,25 +310,29 @@
   gfx::Point point3(450, 150);
   gfx::Point point4(202, 202);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, a_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target2.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, d_id);
   EXPECT_EQ(target3.location_in_target, gfx::Point(50, 100));
-  EXPECT_EQ(target3.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, b_id);
   EXPECT_EQ(target4.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target4.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target4.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // One embedder with two clipped children with a tab and transparent background.
@@ -353,26 +377,27 @@
   transform_c2_to_h.Translate(0, -100);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 6);  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 6);  // e
   aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
       c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
       c1_bounds_in_e, transform_e_to_c1, 2);  // c1
-  aggregated_hit_test_region_list[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1,
-      transform_c1_to_a, 0);  // a
-  aggregated_hit_test_region_list[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c1,
-      transform_c1_to_b, 0);  // b
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c1, transform_c1_to_a, 0);  // a
+  aggregated_hit_test_region_list[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c1, transform_c1_to_b, 0);  // b
   aggregated_hit_test_region_list[4] = AggregatedHitTestRegion(
       c2_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
       c2_bounds_in_e, transform_e_to_c2, 2);  // c2
-  aggregated_hit_test_region_list[5] = AggregatedHitTestRegion(
-      g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_c2,
-      transform_c2_to_g, 0);  // g
-  aggregated_hit_test_region_list[6] = AggregatedHitTestRegion(
-      h_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, h_bounds_in_c2,
-      transform_c2_to_h, 0);  // h
+  aggregated_hit_test_region_list[5] =
+      AggregatedHitTestRegion(g_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              g_bounds_in_c2, transform_c2_to_g, 0);  // g
+  aggregated_hit_test_region_list[6] =
+      AggregatedHitTestRegion(h_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              h_bounds_in_c2, transform_c2_to_h, 0);  // h
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -383,40 +408,47 @@
   gfx::Point point6(450, 750);
   gfx::Point point7(350, 1100);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, a_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target2.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, e_id);
   EXPECT_EQ(target3.location_in_target, point3);
-  EXPECT_EQ(target3.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, b_id);
   EXPECT_EQ(target4.location_in_target, gfx::Point(2, 2));
-  EXPECT_EQ(target4.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target4.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target5 = hit_test_query().FindTargetForLocation(point5);
+  Target target5 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point5);
   EXPECT_EQ(target5.frame_sink_id, g_id);
   EXPECT_EQ(target5.location_in_target, gfx::Point(50, 50));
-  EXPECT_EQ(target5.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target5.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target6 = hit_test_query().FindTargetForLocation(point6);
+  Target target6 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point6);
   EXPECT_EQ(target6.frame_sink_id, e_id);
   EXPECT_EQ(target6.location_in_target, point6);
-  EXPECT_EQ(target6.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target6.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target7 = hit_test_query().FindTargetForLocation(point7);
+  Target target7 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point7);
   EXPECT_EQ(target7.frame_sink_id, h_id);
   EXPECT_EQ(target7.location_in_target, gfx::Point(150, 300));
-  EXPECT_EQ(target7.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target7.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // Children that are multiple layers deep.
@@ -455,23 +487,24 @@
   transform_e_to_c2.Translate(-400, -50);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5),  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 5),  // e
       aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
           c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
           c1_bounds_in_e, transform_e_to_c1, 3);  // c1
-  aggregated_hit_test_region_list[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1,
-      transform_c1_to_a, 2);  // a
-  aggregated_hit_test_region_list[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_a,
-      transform_a_to_b, 1);  // b
-  aggregated_hit_test_region_list[4] = AggregatedHitTestRegion(
-      g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_b,
-      transform_b_to_g, 0);  // g
-  aggregated_hit_test_region_list[5] = AggregatedHitTestRegion(
-      c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e,
-      transform_e_to_c2, 0);  // c2
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c1, transform_c1_to_a, 2);  // a
+  aggregated_hit_test_region_list[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_a, transform_a_to_b, 1);  // b
+  aggregated_hit_test_region_list[4] =
+      AggregatedHitTestRegion(g_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              g_bounds_in_b, transform_b_to_g, 0);  // g
+  aggregated_hit_test_region_list[5] =
+      AggregatedHitTestRegion(c2_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c2_bounds_in_e, transform_e_to_c2, 0);  // c2
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -479,25 +512,29 @@
   gfx::Point point3(550, 350);
   gfx::Point point4(900, 350);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
-  EXPECT_EQ(target1.flags, mojom::kHitTestMine);
+  EXPECT_EQ(target1.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, g_id);
   EXPECT_EQ(target2.location_in_target, gfx::Point(0, 20));
-  EXPECT_EQ(target2.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, b_id);
   EXPECT_EQ(target3.location_in_target, gfx::Point(400, 220));
-  EXPECT_EQ(target3.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, c2_id);
   EXPECT_EQ(target4.location_in_target, gfx::Point(500, 300));
-  EXPECT_EQ(target4.flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
+  EXPECT_EQ(target4.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
 }
 
 // Multiple layers deep of transparent children.
@@ -536,8 +573,9 @@
   transform_e_to_c2.Translate(-400, -50);
   AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5);  // e
+  aggregated_hit_test_region_list[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 5);  // e
   aggregated_hit_test_region_list[1] = AggregatedHitTestRegion(
       c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
       c1_bounds_in_e, transform_e_to_c1, 3);  // c1
@@ -550,9 +588,9 @@
   aggregated_hit_test_region_list[4] = AggregatedHitTestRegion(
       g_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, g_bounds_in_b,
       transform_b_to_g, 0);  // g
-  aggregated_hit_test_region_list[5] = AggregatedHitTestRegion(
-      c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e,
-      transform_e_to_c2, 0);  // c2
+  aggregated_hit_test_region_list[5] =
+      AggregatedHitTestRegion(c2_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c2_bounds_in_e, transform_e_to_c2, 0);  // c2
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -560,22 +598,26 @@
   gfx::Point point3(450, 350);
   gfx::Point point4(900, 350);
 
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, e_id);
   EXPECT_EQ(target1.location_in_target, point1);
   EXPECT_TRUE(target1.flags);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, e_id);
   EXPECT_EQ(target2.location_in_target, point2);
   EXPECT_TRUE(target2.flags);
 
-  Target target3 = hit_test_query().FindTargetForLocation(point3);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point3);
   EXPECT_EQ(target3.frame_sink_id, c2_id);
   EXPECT_EQ(target3.location_in_target, gfx::Point(50, 300));
   EXPECT_TRUE(target3.flags);
 
-  Target target4 = hit_test_query().FindTargetForLocation(point4);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point4);
   EXPECT_EQ(target4.frame_sink_id, c2_id);
   EXPECT_EQ(target4.location_in_target, gfx::Point(500, 300));
   EXPECT_TRUE(target4.flags);
@@ -596,17 +638,18 @@
   transform_c_to_b.Translate(0, -100);
   AggregatedHitTestRegion* aggregated_hit_test_region_list_min =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list_min[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3);  // e
+  aggregated_hit_test_region_list_min[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 3);  // e
   aggregated_hit_test_region_list_min[1] = AggregatedHitTestRegion(
       c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
       transform_e_to_c, INT32_MIN);  // c
-  aggregated_hit_test_region_list_min[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
-      transform_c_to_a, 0);  // a
-  aggregated_hit_test_region_list_min[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
-      transform_c_to_b, 0);  // b
+  aggregated_hit_test_region_list_min[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c, transform_c_to_a, 0);  // a
+  aggregated_hit_test_region_list_min[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c, transform_c_to_b, 0);  // b
 
   // All points are in e's coordinate system when we reach this case.
   gfx::Point point1(1, 1);
@@ -614,12 +657,14 @@
 
   // |child_count| is invalid, which is a security fault. For now, check to see
   // if the returned Target is invalid.
-  Target target1 = hit_test_query().FindTargetForLocation(point1);
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target1.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target1.location_in_target, gfx::Point());
   EXPECT_FALSE(target1.flags);
 
-  Target target2 = hit_test_query().FindTargetForLocation(point2);
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
   EXPECT_EQ(target2.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target2.location_in_target, gfx::Point());
   EXPECT_FALSE(target2.flags);
@@ -627,42 +672,98 @@
   AggregatedHitTestRegion* aggregated_hit_test_region_list_max =
       aggregated_hit_test_region();
   aggregated_hit_test_region_list_max[0] =
-      AggregatedHitTestRegion(e_id, mojom::kHitTestMine, e_bounds_in_e,
-                              transform_e_to_e, INT32_MAX);  // e
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, INT32_MAX);  // e
   aggregated_hit_test_region_list_max[1] = AggregatedHitTestRegion(
       c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
       transform_e_to_c, 2);  // c
-  aggregated_hit_test_region_list_max[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
-      transform_c_to_a, 0);  // a
-  aggregated_hit_test_region_list_max[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
-      transform_c_to_b, 0);  // b
+  aggregated_hit_test_region_list_max[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c, transform_c_to_a, 0);  // a
+  aggregated_hit_test_region_list_max[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c, transform_c_to_b, 0);  // b
 
-  Target target3 = hit_test_query().FindTargetForLocation(point1);
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target3.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target3.location_in_target, gfx::Point());
   EXPECT_FALSE(target3.flags);
 
   AggregatedHitTestRegion* aggregated_hit_test_region_list_bigger =
       aggregated_hit_test_region();
-  aggregated_hit_test_region_list_bigger[0] = AggregatedHitTestRegion(
-      e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3);  // e
+  aggregated_hit_test_region_list_bigger[0] =
+      AggregatedHitTestRegion(e_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              e_bounds_in_e, transform_e_to_e, 3);  // e
   aggregated_hit_test_region_list_bigger[1] = AggregatedHitTestRegion(
       c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
       transform_e_to_c, 3);  // c
-  aggregated_hit_test_region_list_bigger[2] = AggregatedHitTestRegion(
-      a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
-      transform_c_to_a, 0);  // a
-  aggregated_hit_test_region_list_bigger[3] = AggregatedHitTestRegion(
-      b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
-      transform_c_to_b, 0);  // b
+  aggregated_hit_test_region_list_bigger[2] =
+      AggregatedHitTestRegion(a_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              a_bounds_in_c, transform_c_to_a, 0);  // a
+  aggregated_hit_test_region_list_bigger[3] =
+      AggregatedHitTestRegion(b_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              b_bounds_in_c, transform_c_to_b, 0);  // b
 
-  Target target4 = hit_test_query().FindTargetForLocation(point1);
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
   EXPECT_EQ(target4.frame_sink_id, FrameSinkId());
   EXPECT_EQ(target4.location_in_target, gfx::Point());
   EXPECT_FALSE(target4.flags);
 }
 
+// Tests flags kHitTestMouse and kHitTestTouch.
+TEST_F(HitTestQueryTest, MouseTouchFlags) {
+  FrameSinkId e_id = FrameSinkId(1, 1);
+  FrameSinkId c1_id = FrameSinkId(2, 2);
+  FrameSinkId c2_id = FrameSinkId(3, 3);
+  gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+  gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 300, 200);
+  gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 350, 250);
+  gfx::Transform transform_e_to_e, transform_e_to_c1, transform_e_to_c2;
+  transform_e_to_c1.Translate(-100, -100);
+  transform_e_to_c2.Translate(-75, -75);
+  AggregatedHitTestRegion* aggregated_hit_test_region_list =
+      aggregated_hit_test_region();
+  aggregated_hit_test_region_list[0] = AggregatedHitTestRegion(
+      e_id, mojom::kHitTestMine | mojom::kHitTestMouse | mojom::kHitTestTouch,
+      e_bounds_in_e, transform_e_to_e, 2);  // e
+  aggregated_hit_test_region_list[1] =
+      AggregatedHitTestRegion(c1_id, mojom::kHitTestMine | mojom::kHitTestMouse,
+                              c1_bounds_in_e, transform_e_to_c1, 0);  // c1
+  aggregated_hit_test_region_list[2] =
+      AggregatedHitTestRegion(c2_id, mojom::kHitTestMine | mojom::kHitTestTouch,
+                              c2_bounds_in_e, transform_e_to_c2, 0);  // c2
+
+  // All points are in e's coordinate system when we reach this case.
+  gfx::Point point1(80, 80);
+  gfx::Point point2(150, 150);
+
+  Target target1 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point1);
+  EXPECT_EQ(target1.frame_sink_id, e_id);
+  EXPECT_EQ(target1.location_in_target, point1);
+  EXPECT_EQ(target1.flags,
+            mojom::kHitTestMine | mojom::kHitTestMouse | mojom::kHitTestTouch);
+
+  Target target2 =
+      hit_test_query().FindTargetForLocation(EventSource::TOUCH, point1);
+  EXPECT_EQ(target2.frame_sink_id, c2_id);
+  EXPECT_EQ(target2.location_in_target, gfx::Point(5, 5));
+  EXPECT_EQ(target2.flags, mojom::kHitTestMine | mojom::kHitTestTouch);
+
+  Target target3 =
+      hit_test_query().FindTargetForLocation(EventSource::MOUSE, point2);
+  EXPECT_EQ(target3.frame_sink_id, c1_id);
+  EXPECT_EQ(target3.location_in_target, gfx::Point(50, 50));
+  EXPECT_EQ(target3.flags, mojom::kHitTestMine | mojom::kHitTestMouse);
+
+  Target target4 =
+      hit_test_query().FindTargetForLocation(EventSource::TOUCH, point2);
+  EXPECT_EQ(target4.frame_sink_id, c2_id);
+  EXPECT_EQ(target4.location_in_target, gfx::Point(75, 75));
+  EXPECT_EQ(target4.flags, mojom::kHitTestMine | mojom::kHitTestTouch);
+}
+
 }  // namespace test
 }  // namespace viz
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
index e4fa11b..fc64639 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -288,12 +288,10 @@
     std::string string_value;
     if (!dict.GetString(ui::ToString(attr), &string_value))
       continue;
-    WriteAttribute(false,
-                   base::StringPrintf(
-                       "%s='%s'",
-                       ui::ToString(attr).c_str(),
-                       string_value.c_str()),
-                   &line);
+    WriteAttribute(
+        false,
+        base::StringPrintf("%s='%s'", ui::ToString(attr), string_value.c_str()),
+        &line);
   }
 
   for (int attr_index = ui::AX_INT_ATTRIBUTE_NONE;
@@ -303,10 +301,10 @@
     std::string string_value;
     if (!dict.GetString(ui::ToString(attr), &string_value))
       continue;
-    WriteAttribute(false,
-                   base::StringPrintf("%s=%s", ui::ToString(attr).c_str(),
-                                      string_value.c_str()),
-                   &line);
+    WriteAttribute(
+        false,
+        base::StringPrintf("%s=%s", ui::ToString(attr), string_value.c_str()),
+        &line);
   }
 
   for (int attr_index = ui::AX_BOOL_ATTRIBUTE_NONE;
@@ -317,10 +315,8 @@
     if (!dict.GetBoolean(ui::ToString(attr), &bool_value))
       continue;
     WriteAttribute(false,
-                   base::StringPrintf(
-                       "%s=%s",
-                       ui::ToString(attr).c_str(),
-                       bool_value ? "true" : "false"),
+                   base::StringPrintf("%s=%s", ui::ToString(attr),
+                                      bool_value ? "true" : "false"),
                    &line);
   }
 
@@ -331,8 +327,7 @@
     if (!dict.GetDouble(ui::ToString(attr), &float_value))
       continue;
     WriteAttribute(
-        false,
-        base::StringPrintf("%s=%.2f", ui::ToString(attr).c_str(), float_value),
+        false, base::StringPrintf("%s=%.2f", ui::ToString(attr), float_value),
         &line);
   }
 
@@ -343,7 +338,8 @@
     const base::ListValue* value;
     if (!dict.GetList(ui::ToString(attr), &value))
       continue;
-    std::string attr_string = ui::ToString(attr) + "=";
+    std::string attr_string(ui::ToString(attr));
+    attr_string.push_back('=');
     for (size_t i = 0; i < value->GetSize(); ++i) {
       if (i > 0)
         attr_string += ",";
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index dea0c41..d42962a 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -87,11 +87,12 @@
 //
 
 STDMETHODIMP BrowserAccessibilityComWin::get_attributes(BSTR* attributes) {
-  // This can be removed once the rest of the interface has been removed.
+  // This can be removed once ISimpleDOMNode is migrated
   return AXPlatformNodeWin::get_attributes(attributes);
 }
 
 STDMETHODIMP BrowserAccessibilityComWin::scrollTo(IA2ScrollType scroll_type) {
+  // This can be removed once ISimpleDOMNode is migrated
   return AXPlatformNodeWin::scrollTo(scroll_type);
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_event_win.cc b/content/browser/accessibility/browser_accessibility_event_win.cc
index ed5f2e5..540b216 100644
--- a/content/browser/accessibility/browser_accessibility_event_win.cc
+++ b/content/browser/accessibility/browser_accessibility_event_win.cc
@@ -92,8 +92,10 @@
 std::string BrowserAccessibilityEventWin::GetEventNameStr() {
   std::string result = base::UTF16ToUTF8(AccessibilityEventToString(
       win_event_type_));
-  if (event_type() != ui::AX_EVENT_NONE)
-    result += "/" + ui::ToString(event_type());
+  if (event_type() != ui::AX_EVENT_NONE) {
+    result.push_back('/');
+    result.append(ui::ToString(event_type()));
+  }
   return result;
 }
 
diff --git a/content/browser/appcache/appcache_executable_handler.h b/content/browser/appcache/appcache_executable_handler.h
index a19201f2..e1df619 100644
--- a/content/browser/appcache/appcache_executable_handler.h
+++ b/content/browser/appcache/appcache_executable_handler.h
@@ -31,7 +31,7 @@
     // TODO: blob + headers would be a good one to provide as well, as it would
     // make templating possible.
   };
-  typedef base::Callback<void(const Response&)> ResponseCallback;
+  typedef base::OnceCallback<void(const Response&)> ResponseCallback;
 
   // Deletion of the handler cancels all pending callbacks.
   virtual ~AppCacheExecutableHandler() {}
diff --git a/content/browser/host_zoom_map_impl_browsertest.cc b/content/browser/host_zoom_map_impl_browsertest.cc
index fd631fc..07e96b5 100644
--- a/content/browser/host_zoom_map_impl_browsertest.cc
+++ b/content/browser/host_zoom_map_impl_browsertest.cc
@@ -55,7 +55,7 @@
 // stored by host value, and can distinguish temporary zoom levels from
 // these.
 IN_PROC_BROWSER_TEST_F(HostZoomMapImplBrowserTest, GetZoomForView_Host) {
-  GURL url(embedded_test_server()->GetURL("abc.com", "/"));
+  GURL url(embedded_test_server()->GetURL("abc.com", "/title1.html"));
 
   // We must navigate so the WebContents has a committed entry.
   EXPECT_TRUE(NavigateToURL(shell(), url));
@@ -77,7 +77,7 @@
 // from these.
 IN_PROC_BROWSER_TEST_F(HostZoomMapImplBrowserTest,
                        GetZoomForView_HostAndScheme) {
-  GURL url(embedded_test_server()->GetURL("abc.com", "/"));
+  GURL url(embedded_test_server()->GetURL("abc.com", "/title1.html"));
 
   // We must navigate so the WebContents has a committed entry.
   EXPECT_TRUE(NavigateToURL(shell(), url));
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index cab5b64..44fdb9e 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -280,6 +280,8 @@
     version_2->set_fetch_handler_existence(
         ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
     registration_->SetWaitingVersion(version_2);
+    version_2->StartWorker(ServiceWorkerMetrics::EventType::INSTALL,
+                           base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
     version_2->SetStatus(ServiceWorkerVersion::INSTALLED);
 
     // Set it to activate when ready. The original version should still be
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index bb9f250..e7d81f8 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -347,13 +347,34 @@
 
   status_ = status;
   if (skip_waiting_) {
-    if (status == INSTALLED) {
-      RestartTick(&skip_waiting_time_);
-    } else if (status == ACTIVATED) {
-      ClearTick(&skip_waiting_time_);
-      for (int request_id : pending_skip_waiting_requests_)
-        DidSkipWaiting(request_id);
-      pending_skip_waiting_requests_.clear();
+    switch (status_) {
+      case NEW:
+        // |skip_waiting_| should not be set before the version is NEW.
+        NOTREACHED();
+        return;
+      case INSTALLING:
+        // Do nothing until INSTALLED time.
+        break;
+      case INSTALLED:
+        // Start recording the time when the version is trying to skip waiting.
+        RestartTick(&skip_waiting_time_);
+        break;
+      case ACTIVATING:
+        // Do nothing until ACTIVATED time.
+        break;
+      case ACTIVATED:
+        // Resolve skip waiting promises.
+        ClearTick(&skip_waiting_time_);
+        for (int request_id : pending_skip_waiting_requests_) {
+          embedded_worker_->SendMessage(
+              ServiceWorkerMsg_DidSkipWaiting(request_id));
+        }
+        pending_skip_waiting_requests_.clear();
+        break;
+      case REDUNDANT:
+        // Clear any pending skip waiting requests since this version is dead.
+        pending_skip_waiting_requests_.clear();
+        break;
     }
   }
 
@@ -1324,8 +1345,18 @@
 
 void ServiceWorkerVersion::OnSkipWaiting(int request_id) {
   skip_waiting_ = true;
-  if (status_ != INSTALLED)
-    return DidSkipWaiting(request_id);
+
+  // Per spec, resolve the skip waiting promise now if activation won't be
+  // triggered here. The ActivateWaitingVersionWhenReady() call below only
+  // triggers it if we're in INSTALLED state. So if we're not in INSTALLED
+  // state, resolve the promise now. Even if we're in INSTALLED state, there are
+  // still cases where ActivateWaitingVersionWhenReady() won't trigger the
+  // activation. In that case, it's a slight spec violation to not resolve now,
+  // but we'll eventually resolve the promise in SetStatus().
+  if (status_ != INSTALLED) {
+    embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id));
+    return;
+  }
 
   if (!context_)
     return;
@@ -1340,13 +1371,6 @@
     registration->ActivateWaitingVersionWhenReady();
 }
 
-void ServiceWorkerVersion::DidSkipWaiting(int request_id) {
-  if (running_status() == EmbeddedWorkerStatus::STARTING ||
-      running_status() == EmbeddedWorkerStatus::RUNNING) {
-    embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id));
-  }
-}
-
 void ServiceWorkerVersion::OnClaimClients(int request_id) {
   if (status_ != ACTIVATING && status_ != ACTIVATED) {
     embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 33cadb1e..8d42fc8 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -8302,7 +8302,7 @@
     EXPECT_TRUE(ExecuteScriptAndExtractString(
         root->child_at(0), "domAutomationController.send(document.title)",
         &frame_title));
-    EXPECT_EQ("", frame_title);
+    EXPECT_EQ("Error", frame_title);
   } else {
     // The blocked frame should stay at the old location.
     EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url());
@@ -8396,7 +8396,7 @@
     EXPECT_TRUE(ExecuteScriptAndExtractString(
         root->child_at(0), "domAutomationController.send(document.title)",
         &frame_title));
-    EXPECT_EQ("", frame_title);
+    EXPECT_EQ("Error", frame_title);
   } else {
     // The blocked frame should stay at the old location.
     EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url());
@@ -8484,7 +8484,7 @@
     EXPECT_TRUE(ExecuteScriptAndExtractString(
         navigating_frame, "domAutomationController.send(document.title)",
         &frame_title));
-    EXPECT_EQ("", frame_title);
+    EXPECT_EQ("Error", frame_title);
   } else {
     // The blocked frame should stay at the old location.
     EXPECT_EQ(old_subframe_url, navigating_frame->current_url());
diff --git a/content/browser/tracing/memory_tracing_browsertest.cc b/content/browser/tracing/memory_tracing_browsertest.cc
index edf0528..304adc9b 100644
--- a/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/content/browser/tracing/memory_tracing_browsertest.cc
@@ -155,7 +155,7 @@
   }
 
   void Navigate(Shell* shell) {
-    NavigateToURL(shell, GetTestUrl("", "title.html"));
+    NavigateToURL(shell, GetTestUrl("", "title1.html"));
   }
 
   MOCK_METHOD2(OnMemoryDumpDone, void(uint32_t request_index, bool successful));
@@ -166,9 +166,9 @@
   bool last_callback_success_;
 };
 
-// Ignore SingleProcessMemoryTracingTests for Google Chrome builds because
-// single-process is not supported on those builds.
-#if !defined(GOOGLE_CHROME_BUILD)
+// Run SingleProcessMemoryTracingTests only on Android, since these tests are
+// intended to give coverage to Android WebView.
+#if defined(OS_ANDROID)
 
 class SingleProcessMemoryTracingTest : public MemoryTracingTest {
  public:
@@ -303,7 +303,7 @@
   DisableTracing();
 }
 
-#endif  // !defined(GOOGLE_CHROME_BUILD)
+#endif  // defined(OS_ANDROID)
 
 // Non-deterministic races under TSan. crbug.com/529678
 #if defined(THREAD_SANITIZER)
diff --git a/content/browser/tracing/power_tracing_agent.cc b/content/browser/tracing/power_tracing_agent.cc
index 3bd378c0..f687a467 100644
--- a/content/browser/tracing/power_tracing_agent.cc
+++ b/content/browser/tracing/power_tracing_agent.cc
@@ -115,13 +115,14 @@
   battor_agent_->StopTracing();
 }
 
-void PowerTracingAgent::OnStopTracingComplete(const std::string& trace,
-                                              battor::BattOrError error) {
+void PowerTracingAgent::OnStopTracingComplete(
+    const battor::BattOrResults& results,
+    battor::BattOrError error) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   scoped_refptr<base::RefCountedString> result(new base::RefCountedString());
   if (error == battor::BATTOR_ERROR_NONE)
-    result->data() = trace;
+    result->data() = results.ToString();
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
diff --git a/content/browser/tracing/power_tracing_agent.h b/content/browser/tracing/power_tracing_agent.h
index 3d82fa0..cfc1a36 100644
--- a/content/browser/tracing/power_tracing_agent.h
+++ b/content/browser/tracing/power_tracing_agent.h
@@ -43,7 +43,7 @@
 
   // BattOrAgent::Listener implementation.
   void OnStartTracingComplete(battor::BattOrError error) override;
-  void OnStopTracingComplete(const std::string& trace,
+  void OnStopTracingComplete(const battor::BattOrResults& results,
                              battor::BattOrError error) override;
   void OnRecordClockSyncMarkerComplete(battor::BattOrError error) override;
   void OnGetFirmwareGitHashComplete(const std::string& version,
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 33d93604..3d59b28 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -559,7 +559,7 @@
     {"svg.css", IDR_UASTYLE_SVG_CSS, ui::SCALE_FACTOR_NONE, true},
     {"mathml.css", IDR_UASTYLE_MATHML_CSS, ui::SCALE_FACTOR_NONE, true},
     {"mediaControls.css", IDR_UASTYLE_MEDIA_CONTROLS_CSS, ui::SCALE_FACTOR_NONE,
-     true},
+     false},
     {"fullscreen.css", IDR_UASTYLE_FULLSCREEN_CSS, ui::SCALE_FACTOR_NONE, true},
     {"xhtmlmp.css", IDR_UASTYLE_XHTMLMP_CSS, ui::SCALE_FACTOR_NONE, true},
     {"viewportAndroid.css", IDR_UASTYLE_VIEWPORT_ANDROID_CSS,
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index eced3b0..bad6fc3e 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -169,7 +169,7 @@
 // TODO(mcasas): remove after https://crbug.com/736517 is closed.
 const base::Feature kMojoVideoEncodeAccelerator {
   "MojoVideoEncodeAccelerator",
-#if defined(OS_MACOSX)
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc
index 184dfa7..252ce19 100644
--- a/content/shell/renderer/shell_content_renderer_client.cc
+++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
 #include "components/cdm/renderer/external_clear_key_key_system_properties.h"
 #include "components/web_cache/renderer/web_cache_impl.h"
 #include "content/public/child/child_thread.h"
@@ -21,8 +22,10 @@
 #include "content/shell/renderer/shell_render_view_observer.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/message_pipe.h"
+#include "net/base/net_errors.h"
 #include "ppapi/features/features.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/WebKit/public/platform/WebURLError.h"
 #include "third_party/WebKit/public/web/WebTestingSupport.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "v8/include/v8.h"
@@ -121,6 +124,41 @@
   new ShellRenderViewObserver(render_view);
 }
 
+bool ShellContentRendererClient::HasErrorPage(int http_status_code) {
+  return http_status_code >= 400 && http_status_code < 600;
+}
+
+void ShellContentRendererClient::GetNavigationErrorStrings(
+    RenderFrame* render_frame,
+    const blink::WebURLRequest& failed_request,
+    const blink::WebURLError& error,
+    std::string* error_html,
+    base::string16* error_description) {
+  if (error_html) {
+    *error_html =
+        "<head><title>Error</title></head><body>Could not load the requested "
+        "resource.<br/>Error code: " +
+        base::IntToString(error.reason) +
+        (error.reason < 0 ? " (" + net::ErrorToString(error.reason) + ")"
+                          : "") +
+        "</body>";
+  }
+}
+
+void ShellContentRendererClient::GetNavigationErrorStringsForHttpStatusError(
+    content::RenderFrame* render_frame,
+    const blink::WebURLRequest& failed_request,
+    const GURL& unreachable_url,
+    int http_status,
+    std::string* error_html,
+    base::string16* error_description) {
+  if (error_html) {
+    *error_html =
+        "<head><title>Error</title></head><body>Server returned HTTP status " +
+        base::IntToString(http_status) + "</body>";
+  }
+}
+
 bool ShellContentRendererClient::IsPluginAllowedToUseCompositorAPI(
     const GURL& url) {
 #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/shell/renderer/shell_content_renderer_client.h b/content/shell/renderer/shell_content_renderer_client.h
index c7294ee..13d632d 100644
--- a/content/shell/renderer/shell_content_renderer_client.h
+++ b/content/shell/renderer/shell_content_renderer_client.h
@@ -6,6 +6,7 @@
 #define CONTENT_SHELL_RENDERER_SHELL_CONTENT_RENDERER_CLIENT_H_
 
 #include <memory>
+#include <string>
 
 #include "base/compiler_specific.h"
 #include "build/build_config.h"
@@ -26,6 +27,19 @@
   // ContentRendererClient implementation.
   void RenderThreadStarted() override;
   void RenderViewCreated(RenderView* render_view) override;
+  bool HasErrorPage(int http_status_code) override;
+  void GetNavigationErrorStrings(RenderFrame* render_frame,
+                                 const blink::WebURLRequest& failed_request,
+                                 const blink::WebURLError& error,
+                                 std::string* error_html,
+                                 base::string16* error_description) override;
+  void GetNavigationErrorStringsForHttpStatusError(
+      content::RenderFrame* render_frame,
+      const blink::WebURLRequest& failed_request,
+      const GURL& unreachable_url,
+      int http_status,
+      std::string* error_html,
+      base::string16* error_description) override;
 
   // TODO(mkwst): These toggle based on the kEnablePepperTesting flag. Do we
   // need that outside of layout tests?
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 0275d2c..30634c7d 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -1409,6 +1409,15 @@
     'desktop_args': ['--use-gpu-in-tests'],
     'linux_args': [ '--no-xvfb' ]
   },
+  'gpu_unittests': {
+    'tester_configs': [
+      {
+        # Run this on the FYI waterfall and optional tryservers.
+        'predicate': Predicates.FYI_AND_OPTIONAL,
+        'os_types': ['win', 'linux', 'mac', 'android'],
+      },
+    ],
+  },
   # The gles2_conform_tests are closed-source and deliberately only run
   # on the FYI waterfall and the optional tryservers.
   'gles2_conform_test': {
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h
index 64fa04e75..56342a4 100644
--- a/ios/chrome/browser/experimental_flags.h
+++ b/ios/chrome/browser/experimental_flags.h
@@ -39,9 +39,6 @@
 // If |WHATS_NEW_DEFAULT| is returned, no promo is force enabled.
 WhatsNewPromoStatus GetWhatsNewPromoStatus();
 
-// Whether auto-reload is enabled.
-bool IsAutoReloadEnabled();
-
 // Whether the lru snapshot cache experiment is enabled.
 bool IsLRUSnapshotCacheEnabled();
 
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm
index 344b0e2..4470865 100644
--- a/ios/chrome/browser/experimental_flags.mm
+++ b/ios/chrome/browser/experimental_flags.mm
@@ -83,11 +83,6 @@
   return static_cast<WhatsNewPromoStatus>(status);
 }
 
-bool IsAutoReloadEnabled() {
-  // TODO(crbug.com/752084): Remove this function and its associated code.
-  return false;
-}
-
 bool IsLRUSnapshotCacheEnabled() {
   // TODO(crbug.com/751553): Remove this function and its associated code.
   return NO;
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h
index 1e2a500..5e428a5 100644
--- a/ios/chrome/browser/tabs/tab.h
+++ b/ios/chrome/browser/tabs/tab.h
@@ -18,7 +18,6 @@
 
 @protocol ApplicationCommands;
 @class AutofillController;
-@class AutoReloadBridge;
 @protocol BrowserCommands;
 @protocol IOSCaptivePortalBlockingPageDelegate;
 @class CastController;
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index c4218b5..e6b854a3 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -93,7 +93,6 @@
 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h"
 #import "ios/chrome/browser/ui/prerender_delegate.h"
 #include "ios/chrome/browser/ui/ui_util.h"
-#import "ios/chrome/browser/web/auto_reload_bridge.h"
 #import "ios/chrome/browser/web/external_app_launcher.h"
 #import "ios/chrome/browser/web/navigation_manager_util.h"
 #import "ios/chrome/browser/web/passkit_dialog_provider.h"
@@ -219,9 +218,6 @@
   // Handles support for window.print JavaScript calls.
   std::unique_ptr<PrintObserver> _printObserver;
 
-  // AutoReloadBridge for this tab.
-  AutoReloadBridge* _autoReloadBridge;
-
   // WebStateImpl for this tab.
   web::WebStateImpl* _webStateImpl;
 
@@ -416,9 +412,6 @@
   _tabInfoBarObserver = base::MakeUnique<TabInfoBarObserver>(self);
   _tabInfoBarObserver->SetShouldObserveInfoBarManager(true);
 
-  if (experimental_flags::IsAutoReloadEnabled())
-    _autoReloadBridge = [[AutoReloadBridge alloc] initWithTab:self];
-
   [self setShouldObserveFaviconChanges:YES];
 }
 
@@ -1190,7 +1183,6 @@
   // |disableFullScreen| is called only from one place.
   [_fullScreenController disableFullScreen];
   GURL lastCommittedURL = webState->GetLastCommittedURL();
-  [_autoReloadBridge loadStartedForURL:lastCommittedURL];
 
   if (_parentTabModel) {
     [[NSNotificationCenter defaultCenter]
@@ -1249,10 +1241,6 @@
     wasPost = lastCommittedItem->HasPostData();
     lastCommittedURL = lastCommittedItem->GetVirtualURL();
   }
-  if (loadSuccess)
-    [_autoReloadBridge loadFinishedForURL:lastCommittedURL wasPost:wasPost];
-  else
-    [_autoReloadBridge loadFailedForURL:lastCommittedURL wasPost:wasPost];
   [_webControllerSnapshotHelper setSnapshotCoalescingEnabled:YES];
   if (!loadSuccess)
     [_fullScreenController disableFullScreen];
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.mm
index 6287765..3862902 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.mm
@@ -213,15 +213,11 @@
 
   BOOL LTRTextInRTLLayout = _alignment == NSTextAlignmentLeft && UseRTLLayout();
 
-  // Update the frame to reflect whether we have an answer or not.
-  const BOOL answerPresent = match.answer.get() != nil;
-  row.rowHeight = answerPresent ? kAnswerRowHeight : kRowHeight;
+  row.rowHeight = [self hasAnswer:match] ? kAnswerRowHeight : kRowHeight;
 
   // Fetch the answer image if specified.  Currently, no answer types specify an
   // image on the first line so for now we only look at the second line.
-  const BOOL answerImagePresent =
-      answerPresent && match.answer->second_line().image_url().is_valid();
-  if (answerImagePresent) {
+  if ([self hasImage:match]) {
     image_fetcher::IOSImageDataFetcherCallback callback =
         ^(NSData* data, const image_fetcher::RequestMetadata& metadata) {
           if (data) {
@@ -232,8 +228,7 @@
             }
           }
         };
-    imageFetcher_->FetchImageDataWebpDecoded(
-        match.answer->second_line().image_url(), callback);
+    imageFetcher_->FetchImageDataWebpDecoded([self imageURL:match], callback);
 
     // Answers in suggest do not support RTL, left align only.
     CGFloat imageLeftPadding =
@@ -257,27 +252,26 @@
   // For the detail text label, we use either the regular detail label, which
   // truncates by fading, or the answer label, which uses UILabel's standard
   // truncation by ellipse for the multi-line text sometimes shown in answers.
-  row.detailTruncatingLabel.hidden = answerPresent;
-  row.detailAnswerLabel.hidden = !answerPresent;
+  row.detailTruncatingLabel.hidden = [self hasAnswer:match];
+  row.detailAnswerLabel.hidden = ![self hasAnswer:match];
   // URLs have have special layout requirements that need to be invoked here.
-  BOOL isURL = !AutocompleteMatch::IsSearchType(match.type);
-  row.detailTruncatingLabel.displayAsURL = isURL;
+  row.detailTruncatingLabel.displayAsURL = [self isURL:match];
 
   // TODO(crbug.com/697647): The complexity of managing these two separate
   // labels could probably be encapusulated in the row class if we moved the
   // layout logic there.
-  UILabel* detailTextLabel =
-      answerPresent ? row.detailAnswerLabel : row.detailTruncatingLabel;
+  UILabel* detailTextLabel = [self hasAnswer:match] ? row.detailAnswerLabel
+                                                    : row.detailTruncatingLabel;
   [detailTextLabel setTextAlignment:_alignment];
 
   // The width must be positive for CGContextRef to be valid.
   CGFloat labelWidth =
       MAX(40, floorf(row.frame.size.width) - kTextCellLeadingPadding);
   CGFloat labelHeight =
-      answerPresent ? kAnswerLabelHeight : kTextDetailLabelHeight;
+      [self hasAnswer:match] ? kAnswerLabelHeight : kTextDetailLabelHeight;
   CGFloat answerImagePadding = kAnswerImageWidth + kAnswerImageRightPadding;
   CGFloat leadingPadding =
-      (answerImagePresent && !alignmentRight ? answerImagePadding : 0) +
+      ([self hasImage:match] && !alignmentRight ? answerImagePadding : 0) +
       kTextCellLeadingPadding;
 
   LayoutRect detailTextLabelLayout =
@@ -285,52 +279,11 @@
                      kDetailCellTopPadding, labelWidth, labelHeight);
   detailTextLabel.frame = LayoutRectGetRect(detailTextLabelLayout);
 
-  // Set the detail text.
-  // The detail text should be the URL (|match.contents|) for non-search
-  // suggestions and the entity type (|match.description|) for search entity
-  // suggestions. For all other search suggestions, |match.description| is the
-  // name of the currently selected search engine, which for mobile we suppress.
-  NSString* detailText = nil;
-  if (isURL)
-    detailText = base::SysUTF16ToNSString(match.contents);
-  else if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY)
-    detailText = base::SysUTF16ToNSString(match.description);
-
-  if (answerPresent) {
-    detailTextLabel.attributedText =
-        [self attributedStringWithAnswerLine:match.answer->second_line()];
-  } else {
-    const ACMatchClassifications* classifications =
-        isURL ? &match.contents_class : nil;
-    // The suggestion detail color should match the main text color for entity
-    // suggestions. For non-search suggestions (URLs), a highlight color is used
-    // instead.
-    UIColor* suggestionDetailTextColor = nil;
-    if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY) {
-      suggestionDetailTextColor =
-          _incognito ? SuggestionTextColorIncognito() : SuggestionTextColor();
-    } else {
-      suggestionDetailTextColor = SuggestionDetailTextColor();
-    }
-    DCHECK(suggestionDetailTextColor);
-    detailTextLabel.attributedText =
-        [self attributedStringWithString:detailText
-                         classifications:classifications
-                               smallFont:YES
-                                   color:suggestionDetailTextColor
-                                dimColor:DimColor()];
-  }
+  detailTextLabel.attributedText = [self detailText:match];
 
   // Set detail text label number of lines
-  if (answerPresent) {
-    // Answers specify their own limit on the number of lines to show but
-    // still cap this at 3 to guard against unreasonable values.
-    const SuggestionAnswer::TextField& first_text_field =
-        match.answer->second_line().text_fields()[0];
-    if (first_text_field.has_num_lines() && first_text_field.num_lines() > 1)
-      detailTextLabel.numberOfLines = MIN(3, first_text_field.num_lines());
-    else
-      detailTextLabel.numberOfLines = 1;
+  if ([self hasAnswer:match]) {
+    detailTextLabel.numberOfLines = [self numberOfLines:match];
   }
 
   [detailTextLabel setNeedsDisplay];
@@ -343,38 +296,10 @@
   textLabel.frame = LayoutRectGetRect(textLabelLayout);
 
   // Set the text.
-  // The text should be search term (|match.contents|) for searches, otherwise
-  // page title (|match.description|).
-  base::string16 textString = isURL ? match.description : match.contents;
-  NSString* text = base::SysUTF16ToNSString(textString);
-
-  // If for some reason the title is empty, copy the detailText.
-  if ([text length] == 0 && [detailText length] != 0) {
-    text = detailText;
-  }
-
-  NSAttributedString* attributedText = nil;
-
-  if (answerPresent) {
-    attributedText =
-        [self attributedStringWithAnswerLine:match.answer->first_line()];
-  } else {
-    const ACMatchClassifications* textClassifications =
-        isURL ? &match.description_class : &match.contents_class;
-    UIColor* suggestionTextColor =
-        _incognito ? SuggestionTextColorIncognito() : SuggestionTextColor();
-    UIColor* dimColor = _incognito ? DimColorIncognito() : DimColor();
-
-    attributedText = [self attributedStringWithString:text
-                                      classifications:textClassifications
-                                            smallFont:NO
-                                                color:suggestionTextColor
-                                             dimColor:dimColor];
-  }
-  textLabel.attributedText = attributedText;
+  textLabel.attributedText = [self text:match];
 
   // Center the textLabel if detailLabel is empty.
-  if (!answerPresent && [detailText length] == 0) {
+  if (![self hasAnswer:match] && [[self detailText:match] length] == 0) {
     textLabel.center = CGPointMake(textLabel.center.x, floor(kRowHeight / 2));
     textLabel.frame = AlignRectToPixel(textLabel.frame);
   } else {
@@ -388,24 +313,17 @@
   // The leading image (e.g. magnifying glass, star, clock) is only shown on
   // iPad.
   if (IsIPadIdiom()) {
-    int imageId = GetIconForAutocompleteMatchType(
-        match.type, _delegate->IsStarredMatch(match), _incognito);
-    [row updateLeadingImage:imageId];
+    [row updateLeadingImage:[self imageId:match]];
   }
 
   // Show append button for search history/search suggestions/Physical Web as
   // the right control element (aka an accessory element of a table view cell).
-  BOOL appendableMatch =
-      match.type == AutocompleteMatchType::SEARCH_HISTORY ||
-      match.type == AutocompleteMatchType::SEARCH_SUGGEST ||
-      match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY ||
-      match.type == AutocompleteMatchType::PHYSICAL_WEB;
-  row.appendButton.hidden = !appendableMatch;
+  row.appendButton.hidden = ![self isAppendable:match];
   [row.appendButton cancelTrackingWithEvent:nil];
 
   // If a right accessory element is present or the text alignment is right
   // aligned, adjust the width to align with the accessory element.
-  if (appendableMatch || alignmentRight) {
+  if ([self isAppendable:match] || alignmentRight) {
     LayoutRect layout =
         LayoutRectForRectInBoundingRect(textLabel.frame, self.view.frame);
     layout.size.width -= kAppendButtonWidth;
@@ -413,7 +331,7 @@
     layout =
         LayoutRectForRectInBoundingRect(detailTextLabel.frame, self.view.frame);
     layout.size.width -=
-        kAppendButtonWidth + (answerImagePresent ? answerImagePadding : 0);
+        kAppendButtonWidth + ([self hasImage:match] ? answerImagePadding : 0);
     detailTextLabel.frame = LayoutRectGetRect(layout);
   }
 
@@ -825,4 +743,116 @@
   }
 }
 
+- (BOOL)hasAnswer:(const AutocompleteMatch&)match {
+  return match.answer.get() != nil;
+}
+
+- (BOOL)hasImage:(const AutocompleteMatch&)match {
+  return [self hasAnswer:match] &&
+         match.answer->second_line().image_url().is_valid();
+}
+
+- (BOOL)isURL:(const AutocompleteMatch&)match {
+  return !AutocompleteMatch::IsSearchType(match.type);
+}
+
+- (NSAttributedString*)detailText:(const AutocompleteMatch&)match {
+  // The detail text should be the URL (|match.contents|) for non-search
+  // suggestions and the entity type (|match.description|) for search entity
+  // suggestions. For all other search suggestions, |match.description| is the
+  // name of the currently selected search engine, which for mobile we suppress.
+  NSString* detailText = nil;
+  if ([self isURL:match])
+    detailText = base::SysUTF16ToNSString(match.contents);
+  else if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY)
+    detailText = base::SysUTF16ToNSString(match.description);
+
+  NSAttributedString* detailAttributedText = nil;
+  if ([self hasAnswer:match]) {
+    detailAttributedText =
+        [self attributedStringWithAnswerLine:match.answer->second_line()];
+  } else {
+    const ACMatchClassifications* classifications =
+        [self isURL:match] ? &match.contents_class : nil;
+    // The suggestion detail color should match the main text color for entity
+    // suggestions. For non-search suggestions (URLs), a highlight color is used
+    // instead.
+    UIColor* suggestionDetailTextColor = nil;
+    if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY) {
+      suggestionDetailTextColor =
+          _incognito ? SuggestionTextColorIncognito() : SuggestionTextColor();
+    } else {
+      suggestionDetailTextColor = SuggestionDetailTextColor();
+    }
+    DCHECK(suggestionDetailTextColor);
+    detailAttributedText =
+        [self attributedStringWithString:detailText
+                         classifications:classifications
+                               smallFont:YES
+                                   color:suggestionDetailTextColor
+                                dimColor:DimColor()];
+  }
+  return detailAttributedText;
+}
+
+- (NSInteger)numberOfLines:(const AutocompleteMatch&)match {
+  // Answers specify their own limit on the number of lines to show but we
+  // additionally cap this at 3 to guard against unreasonable values.
+  const SuggestionAnswer::TextField& first_text_field =
+      match.answer->second_line().text_fields()[0];
+  if (first_text_field.has_num_lines() && first_text_field.num_lines() > 1)
+    return MIN(3, first_text_field.num_lines());
+  else
+    return 1;
+}
+
+- (NSAttributedString*)text:(const AutocompleteMatch&)match {
+  // The text should be search term (|match.contents|) for searches, otherwise
+  // page title (|match.description|).
+  base::string16 textString =
+      ![self isURL:match] ? match.contents : match.description;
+  NSString* text = base::SysUTF16ToNSString(textString);
+
+  // If for some reason the title is empty, copy the detailText.
+  if ([text length] == 0 && [[self detailText:match] length] != 0) {
+    text = [[self detailText:match] string];
+  }
+
+  NSAttributedString* attributedText = nil;
+
+  if ([self hasAnswer:match]) {
+    attributedText =
+        [self attributedStringWithAnswerLine:match.answer->first_line()];
+  } else {
+    const ACMatchClassifications* textClassifications =
+        ![self isURL:match] ? &match.contents_class : &match.description_class;
+    UIColor* suggestionTextColor =
+        _incognito ? SuggestionTextColorIncognito() : SuggestionTextColor();
+    UIColor* dimColor = _incognito ? DimColorIncognito() : DimColor();
+
+    attributedText = [self attributedStringWithString:text
+                                      classifications:textClassifications
+                                            smallFont:NO
+                                                color:suggestionTextColor
+                                             dimColor:dimColor];
+  }
+  return attributedText;
+}
+
+- (BOOL)isAppendable:(const AutocompleteMatch&)match {
+  return match.type == AutocompleteMatchType::SEARCH_HISTORY ||
+         match.type == AutocompleteMatchType::SEARCH_SUGGEST ||
+         match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY ||
+         match.type == AutocompleteMatchType::PHYSICAL_WEB;
+}
+
+- (GURL)imageURL:(const AutocompleteMatch&)match {
+  return match.answer->second_line().image_url();
+}
+
+- (int)imageId:(const AutocompleteMatch&)match {
+  return GetIconForAutocompleteMatchType(
+      match.type, _delegate->IsStarredMatch(match), _incognito);
+}
+
 @end
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index 3c09af9..d1ee67f3 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -136,10 +136,6 @@
 source_set("web_internal") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
-    "auto_reload_bridge.h",
-    "auto_reload_bridge.mm",
-    "auto_reload_controller.h",
-    "auto_reload_controller.mm",
     "blocked_popup_tab_helper.h",
     "blocked_popup_tab_helper.mm",
     "chrome_web_client.h",
@@ -218,7 +214,6 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
-    "auto_reload_controller_unittest.mm",
     "blocked_popup_tab_helper_unittest.mm",
     "chrome_web_client_unittest.mm",
     "error_page_generator_unittest.mm",
diff --git a/ios/chrome/browser/web/auto_reload_bridge.h b/ios/chrome/browser/web/auto_reload_bridge.h
deleted file mode 100644
index eea4124b..0000000
--- a/ios/chrome/browser/web/auto_reload_bridge.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_BRIDGE_H_
-#define IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_BRIDGE_H_
-
-#import <Foundation/Foundation.h>
-
-#include "ios/chrome/browser/web/auto_reload_controller.h"
-#include "url/gurl.h"
-
-@class Tab;
-
-// AutoReloadBridge is the interface between AutoReloadController and the
-// outside world and isolates AutoReloadController from its dependencies.
-// An AutoReloadBridge is responsible for network state tracking, for receiving
-// and passing on events from its owning Tab, and for passing reload requests
-// back to its owning Tab.
-@interface AutoReloadBridge : NSObject<AutoReloadDelegate>
-
-// Initialize an instance of this class owned by the supplied Tab, which must
-// not be nil.
-- (instancetype)initWithTab:(Tab*)tab;
-
-// Called by the owning Tab whenever a load starts.
-- (void)loadStartedForURL:(const GURL&)url;
-
-// Called by the owning Tab whenever a load finishes.
-- (void)loadFinishedForURL:(const GURL&)url wasPost:(BOOL)wasPost;
-
-// Called by the owning Tab whenever a load fails.
-- (void)loadFailedForURL:(const GURL&)url wasPost:(BOOL)wasPost;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_BRIDGE_H_
diff --git a/ios/chrome/browser/web/auto_reload_bridge.mm b/ios/chrome/browser/web/auto_reload_bridge.mm
deleted file mode 100644
index e8a48cf4..0000000
--- a/ios/chrome/browser/web/auto_reload_bridge.mm
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ios/chrome/browser/web/auto_reload_bridge.h"
-
-#include <memory>
-
-#import "ios/chrome/browser/tabs/tab.h"
-#import "ios/web/public/navigation_manager.h"
-#include "net/base/network_change_notifier.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-class NetworkChangeObserverBridge;
-}  // namespace
-
-@interface AutoReloadBridge () {
-  __weak Tab* _tab;
-  AutoReloadController* _controller;
-  std::unique_ptr<NetworkChangeObserverBridge> _networkBridge;
-}
-
-// This method is called by NetworkChangeObserverBridge to indicate that the
-// device's connected state changed to |online|.
-- (void)networkStateChangedToOnline:(BOOL)online;
-
-@end
-
-namespace {
-
-class NetworkChangeObserverBridge
-    : public net::NetworkChangeNotifier::NetworkChangeObserver {
- public:
-  explicit NetworkChangeObserverBridge(AutoReloadBridge* bridge)
-      : bridge_(bridge) {}
-  ~NetworkChangeObserverBridge() override {}
-
-  void OnNetworkChanged(
-      net::NetworkChangeNotifier::ConnectionType type) override {
-    bool online = type == net::NetworkChangeNotifier::CONNECTION_NONE;
-    [bridge_ networkStateChangedToOnline:online];
-  }
-
- private:
-  __weak AutoReloadBridge* bridge_;
-};
-
-}  // namespace
-
-@implementation AutoReloadBridge
-
-- (instancetype)initWithTab:(Tab*)tab {
-  DCHECK(tab);
-  if ((self = [super init])) {
-    BOOL online = !net::NetworkChangeNotifier::IsOffline();
-    _tab = tab;
-    _controller = [[AutoReloadController alloc] initWithDelegate:self
-                                                    onlineStatus:online];
-    _networkBridge.reset(new NetworkChangeObserverBridge(self));
-  }
-  return self;
-}
-
-- (void)loadStartedForURL:(const GURL&)url {
-  [_controller loadStartedForURL:url];
-}
-
-- (void)loadFinishedForURL:(const GURL&)url wasPost:(BOOL)wasPost {
-  [_controller loadFinishedForURL:url wasPost:wasPost];
-}
-
-- (void)loadFailedForURL:(const GURL&)url wasPost:(BOOL)wasPost {
-  [_controller loadFailedForURL:url wasPost:wasPost];
-}
-
-- (void)networkStateChangedToOnline:(BOOL)online {
-  [_controller networkStateChangedToOnline:online];
-}
-
-#pragma mark AutoReloadDelegate methods
-
-- (void)reload {
-  [_tab navigationManager]->Reload(web::ReloadType::NORMAL,
-                                   false /* check_for_repost */);
-}
-
-@end
diff --git a/ios/chrome/browser/web/auto_reload_controller.h b/ios/chrome/browser/web/auto_reload_controller.h
deleted file mode 100644
index ef14b63a..0000000
--- a/ios/chrome/browser/web/auto_reload_controller.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_CONTROLLER_H_
-
-#import <Foundation/Foundation.h>
-
-#include "url/gurl.h"
-
-// AutoReloadDelegate is the interface by which AutoReloadController affects the
-// outside world. Tests can use a mock object implementing this protocol;
-// normally, this is provided by AutoReloadBridge.
-@protocol AutoReloadDelegate
-
-// When called, this method should reload the tab being tracked (see the class
-// comment on AutoReloadController below).
-- (void)reload;
-
-@end
-
-// AutoReloadController implements the auto-reload logic. An
-// AutoReloadController instance receives state change notifications from an
-// AutoReloadBridge and calls back to its AutoReloadDelegate (in practice the
-// same object as the AutoReloadBridge) to issue reload requests. Conceptually,
-// an AutoReloadController tracks the state of a single tab.
-@interface AutoReloadController : NSObject
-
-// Initialize this object with a supplied delegate and initial online status.
-- (instancetype)initWithDelegate:(id<AutoReloadDelegate>)delegate
-                    onlineStatus:(BOOL)onlineStatus;
-
-// This method notifies this object that a page load started for |url|.
-- (void)loadStartedForURL:(const GURL&)url;
-
-// This method notifies this object that a page load finished for |url|.
-- (void)loadFinishedForURL:(const GURL&)url wasPost:(BOOL)wasPost;
-
-// This method notifies this object that a page load failed for |url|.
-- (void)loadFailedForURL:(const GURL&)url wasPost:(BOOL)wasPost;
-
-// This method notifies this object that the device's network state changed to
-// |online|.
-- (void)networkStateChangedToOnline:(BOOL)online;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_WEB_AUTO_RELOAD_CONTROLLER_H_
diff --git a/ios/chrome/browser/web/auto_reload_controller.mm b/ios/chrome/browser/web/auto_reload_controller.mm
deleted file mode 100644
index 2e64ca93..0000000
--- a/ios/chrome/browser/web/auto_reload_controller.mm
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/web/auto_reload_controller.h"
-
-#include <memory>
-
-#include "base/mac/bind_objc_block.h"
-#include "base/timer/timer.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-base::TimeDelta GetAutoReloadTime(size_t reload_count) {
-  static const int kDelaysMs[] = {
-      0, 5000, 30000, 60000, 300000, 600000, 1800000,
-  };
-  if (reload_count >= arraysize(kDelaysMs))
-    reload_count = arraysize(kDelaysMs) - 1;
-  return base::TimeDelta::FromMilliseconds(kDelaysMs[reload_count]);
-}
-
-}  // namespace
-
-@interface AutoReloadController () {
-  GURL _failedUrl;
-  int _reloadCount;
-  BOOL _shouldReload;
-  BOOL _online;
-  __weak id<AutoReloadDelegate> _delegate;
-  std::unique_ptr<base::Timer> _timer;
-}
-
-// This method is called when the system transitions to offline from online,
-// possibly causing a paused reload timer to start.
-- (void)transitionedToOffline;
-
-// This method is called when the system transitions from online to offline,
-// possibly pausing the reload timer.
-- (void)transitionedToOnline;
-
-// This method is called to actually start the reload timer.
-- (void)startTimer;
-
-// This method is called back from the reload timer when it fires.
-- (void)timerFired;
-
-@end
-
-@implementation AutoReloadController
-
-- (id)initWithDelegate:(id<AutoReloadDelegate>)delegate
-          onlineStatus:(BOOL)online {
-  if ((self = [super init])) {
-    _delegate = delegate;
-    _timer.reset(new base::Timer(false /* don't retain user task */,
-                                 false /* don't repeat automatically */));
-    _online = online;
-  }
-  return self;
-}
-
-- (void)loadStartedForURL:(const GURL&)url {
-  if (_timer->IsRunning()) {
-    // Stop the timer, since the starting load was not started by this class and
-    // it would be bad to replace another load.
-    _timer->Stop();
-  }
-  if (url != _failedUrl) {
-    // Changed URLs, reset the backoff counter.
-    _reloadCount = 0;
-  }
-}
-
-- (void)loadFinishedForURL:(const GURL&)url wasPost:(BOOL)wasPost {
-  DCHECK(!_timer->IsRunning());
-}
-
-- (void)loadFailedForURL:(const GURL&)url wasPost:(BOOL)wasPost {
-  DCHECK(!_timer->IsRunning());
-  if (wasPost)
-    return;
-  _failedUrl = url;
-  if (_online)
-    [self startTimer];
-  else
-    _shouldReload = true;
-}
-
-- (void)networkStateChangedToOnline:(BOOL)online {
-  if (!online && _online)
-    [self transitionedToOffline];
-  else if (online && !_online)
-    [self transitionedToOnline];
-  _online = online;
-}
-
-- (void)setTimerForTesting:(std::unique_ptr<base::Timer>)timer {
-  _timer.reset(timer.release());
-}
-
-- (void)startTimer {
-  __weak AutoReloadController* weakSelf = self;
-  base::TimeDelta delay = GetAutoReloadTime(_reloadCount);
-  _timer->Start(FROM_HERE, delay, base::BindBlockArc(^{
-                  AutoReloadController* strongSelf = weakSelf;
-                  // self owns the timer owns this closure, so self must outlive
-                  // this closure.
-                  DCHECK(strongSelf);
-                  [strongSelf timerFired];
-                }));
-}
-
-- (void)transitionedToOffline {
-  DCHECK(!_shouldReload);
-  if (_timer->IsRunning()) {
-    _shouldReload = true;
-    _timer->Stop();
-  }
-}
-
-- (void)transitionedToOnline {
-  if (_shouldReload) {
-    _shouldReload = false;
-    [self startTimer];
-  }
-}
-
-- (void)timerFired {
-  _reloadCount++;
-  [_delegate reload];
-}
-
-@end
diff --git a/ios/chrome/browser/web/auto_reload_controller_unittest.mm b/ios/chrome/browser/web/auto_reload_controller_unittest.mm
deleted file mode 100644
index 1174227..0000000
--- a/ios/chrome/browser/web/auto_reload_controller_unittest.mm
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ios/chrome/browser/web/auto_reload_controller.h"
-
-#include <memory>
-
-#include "base/timer/mock_timer.h"
-#include "base/timer/timer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-@interface AutoReloadController (Testing)
-
-- (void)setTimerForTesting:(std::unique_ptr<base::Timer>)timer;
-
-@end
-
-@interface TestAutoReloadDelegate : NSObject<AutoReloadDelegate>
-@end
-
-@implementation TestAutoReloadDelegate {
-  int reloads_;
-}
-
-- (void)reload {
-  reloads_++;
-}
-
-- (int)reloads {
-  return reloads_;
-}
-
-@end
-
-class AutoReloadControllerTest : public testing::Test {
- public:
-  AutoReloadControllerTest() : timer_(new base::MockTimer(false, false)) {}
-
- protected:
-  void SetUp() override {
-    testing::Test::SetUp();
-    delegate_ = [[TestAutoReloadDelegate alloc] init];
-    controller_ = [[AutoReloadController alloc] initWithDelegate:delegate_
-                                                    onlineStatus:YES];
-    // Note: even though setTimerForTesting theoretically passes ownership of
-    // the timer to the controller, this class retains a weak pointer to the
-    // timer so it can query or fire it for testing. The only reason this is
-    // safe is that this class owns the controller which now owns the timer, so
-    // the timer has the same lifetime as this class.
-    [controller_ setTimerForTesting:std::unique_ptr<base::Timer>(timer_)];
-  }
-
-  // Synthesize a failing page load.
-  void DoFailingLoad(const GURL& url) {
-    [controller_ loadStartedForURL:url];
-    [controller_ loadFailedForURL:url wasPost:NO];
-  }
-
-  // Synthesize a succeeding page load.
-  void DoSucceedingLoad(const GURL& url) {
-    [controller_ loadStartedForURL:url];
-    [controller_ loadFinishedForURL:url wasPost:NO];
-  }
-
-  TestAutoReloadDelegate* delegate_;
-  AutoReloadController* controller_;
-  base::MockTimer* timer_;  // weak
-};
-
-TEST_F(AutoReloadControllerTest, AutoReloadSucceeds) {
-  const GURL kTestUrl("https://www.google.com");
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  EXPECT_EQ(0, [delegate_ reloads]);
-  timer_->Fire();
-  EXPECT_EQ(1, [delegate_ reloads]);
-  DoSucceedingLoad(kTestUrl);
-  EXPECT_FALSE(timer_->IsRunning());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadRetries) {
-  const GURL kTestUrl("https://www.google.com");
-  DoFailingLoad(kTestUrl);
-  EXPECT_EQ(0, [delegate_ reloads]);
-  timer_->Fire();
-  DoFailingLoad(kTestUrl);
-  EXPECT_EQ(1, [delegate_ reloads]);
-  timer_->Fire();
-  DoFailingLoad(kTestUrl);
-  EXPECT_EQ(2, [delegate_ reloads]);
-  timer_->Fire();
-  DoSucceedingLoad(kTestUrl);
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadBacksOff) {
-  const GURL kTestUrl("https://www.google.com");
-  DoFailingLoad(kTestUrl);
-  base::TimeDelta previous = timer_->GetCurrentDelay();
-  timer_->Fire();
-  DoFailingLoad(kTestUrl);
-  int tries = 0;
-  const int kMaxTries = 20;
-  while (tries < kMaxTries && timer_->GetCurrentDelay() != previous) {
-    previous = timer_->GetCurrentDelay();
-    timer_->Fire();
-    DoFailingLoad(kTestUrl);
-    tries++;
-  }
-
-  EXPECT_NE(tries, 20);
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadStopsOnUserLoadStart) {
-  const GURL kTestUrl("https://www.google.com");
-  const GURL kOtherUrl("https://mail.google.com");
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  [controller_ loadStartedForURL:kOtherUrl];
-  EXPECT_FALSE(timer_->IsRunning());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadBackoffResetsOnUserLoadStart) {
-  const GURL kTestUrl("https://www.google.com");
-  const GURL kOtherUrl("https://mail.google.com");
-  base::TimeDelta first_delay;
-  base::TimeDelta second_delay;
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  first_delay = timer_->GetCurrentDelay();
-  timer_->Fire();
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  second_delay = timer_->GetCurrentDelay();
-  EXPECT_NE(first_delay, second_delay);
-
-  DoFailingLoad(kOtherUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  EXPECT_EQ(first_delay, timer_->GetCurrentDelay());
-  timer_->Fire();
-  DoFailingLoad(kOtherUrl);
-  EXPECT_EQ(second_delay, timer_->GetCurrentDelay());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadStopsAtOffline) {
-  const GURL kTestUrl("https://www.google.com");
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  [controller_ networkStateChangedToOnline:NO];
-  EXPECT_FALSE(timer_->IsRunning());
-  [controller_ networkStateChangedToOnline:YES];
-  EXPECT_TRUE(timer_->IsRunning());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadDoesntStartWhileOffline) {
-  const GURL kTestUrl("https://www.google.com");
-  [controller_ loadStartedForURL:kTestUrl];
-  [controller_ networkStateChangedToOnline:NO];
-  [controller_ loadFailedForURL:kTestUrl wasPost:NO];
-  EXPECT_FALSE(timer_->IsRunning());
-  [controller_ networkStateChangedToOnline:YES];
-  EXPECT_TRUE(timer_->IsRunning());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadDoesNotBackoffAtNetworkChange) {
-  const GURL kTestUrl("https://www.google.com");
-  DoFailingLoad(kTestUrl);
-  EXPECT_TRUE(timer_->IsRunning());
-  base::TimeDelta delay = timer_->GetCurrentDelay();
-  [controller_ networkStateChangedToOnline:NO];
-  [controller_ networkStateChangedToOnline:YES];
-  EXPECT_TRUE(timer_->IsRunning());
-  EXPECT_EQ(delay, timer_->GetCurrentDelay());
-}
-
-TEST_F(AutoReloadControllerTest, AutoReloadDoesNotReloadPosts) {
-  const GURL kTestUrl("https://www.google.com");
-  [controller_ loadStartedForURL:kTestUrl];
-  [controller_ loadFailedForURL:kTestUrl wasPost:YES];
-  EXPECT_FALSE(timer_->IsRunning());
-}
diff --git a/ios/chrome/search_widget_extension/copied_url_view.mm b/ios/chrome/search_widget_extension/copied_url_view.mm
index e1f2e26..b0f0296f 100644
--- a/ios/chrome/search_widget_extension/copied_url_view.mm
+++ b/ios/chrome/search_widget_extension/copied_url_view.mm
@@ -130,7 +130,7 @@
           constraintEqualToAnchor:self.trailingAnchor
                          constant:-ui_util::kContentMargin],
       [_copiedButtonView.topAnchor
-          constraintEqualToAnchor:_hairlineView.bottomAnchor
+          constraintEqualToAnchor:self.topAnchor
                          constant:ui_util::kContentMargin],
       [_copiedButtonView.bottomAnchor
           constraintEqualToAnchor:self.bottomAnchor
diff --git a/ios/chrome/search_widget_extension/search_widget_view.mm b/ios/chrome/search_widget_extension/search_widget_view.mm
index fb278d6fb..899b4166 100644
--- a/ios/chrome/search_widget_extension/search_widget_view.mm
+++ b/ios/chrome/search_widget_extension/search_widget_view.mm
@@ -121,6 +121,8 @@
 }
 
 - (CGFloat)actionContentHeight {
+  [self.actionsContent setNeedsLayout];
+  [self.actionsContent layoutIfNeeded];
   CGFloat height =
       [self.actionsContent
           systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
@@ -129,6 +131,8 @@
 }
 
 - (CGFloat)copiedURLSectionHeight {
+  [self.copiedURLSection setNeedsLayout];
+  [self.copiedURLSection layoutIfNeeded];
   CGFloat height =
       [self.copiedURLSection
           systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
diff --git a/ios/web/web_state/navigation_callbacks_inttest.mm b/ios/web/web_state/navigation_callbacks_inttest.mm
index a85caca..c62534a 100644
--- a/ios/web/web_state/navigation_callbacks_inttest.mm
+++ b/ios/web/web_state/navigation_callbacks_inttest.mm
@@ -48,6 +48,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_FALSE((*context)->IsRendererInitiated());
   ASSERT_FALSE((*context)->GetResponseHeaders());
   ASSERT_TRUE(web_state->IsLoading());
   NavigationManager* navigation_manager = web_state->GetNavigationManager();
@@ -70,6 +71,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_FALSE((*context)->IsRendererInitiated());
   ASSERT_TRUE((*context)->GetResponseHeaders());
   std::string mime_type;
   (*context)->GetResponseHeaders()->GetMimeType(&mime_type);
@@ -84,7 +86,11 @@
 // Verifies correctness of |NavigationContext| (|arg0|) for navigations via POST
 // HTTP methods passed to |DidStartNavigation|. Stores |NavigationContext| in
 // |context| pointer.
-ACTION_P3(VerifyPostStartedContext, web_state, url, context) {
+ACTION_P4(VerifyPostStartedContext,
+          web_state,
+          url,
+          context,
+          renderer_initiated) {
   *context = arg0;
   ASSERT_TRUE(*context);
   EXPECT_EQ(web_state, (*context)->GetWebState());
@@ -92,6 +98,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_TRUE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_EQ(renderer_initiated, (*context)->IsRendererInitiated());
   ASSERT_FALSE((*context)->GetResponseHeaders());
   ASSERT_TRUE(web_state->IsLoading());
   // TODO(crbug.com/676129): Reload does not create a pending item. Remove this
@@ -108,7 +115,11 @@
 // Verifies correctness of |NavigationContext| (|arg0|) for navigations via POST
 // HTTP methods passed to |DidFinishNavigation|. Stores |NavigationContext| in
 // |context| pointer.
-ACTION_P3(VerifyPostFinishedContext, web_state, url, context) {
+ACTION_P4(VerifyPostFinishedContext,
+          web_state,
+          url,
+          context,
+          renderer_initiated) {
   ASSERT_EQ(*context, arg0);
   EXPECT_EQ(web_state, (*context)->GetWebState());
   ASSERT_TRUE((*context));
@@ -117,6 +128,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_TRUE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_EQ(renderer_initiated, (*context)->IsRendererInitiated());
   ASSERT_TRUE(web_state->IsLoading());
   NavigationManager* navigation_manager = web_state->GetNavigationManager();
   NavigationItem* item = navigation_manager->GetLastCommittedItem();
@@ -127,11 +139,12 @@
 // Verifies correctness of |NavigationContext| (|arg0|) for same page navigation
 // passed to |DidFinishNavigation|. Stores |NavigationContext| in |context|
 // pointer.
-ACTION_P4(VerifySameDocumentStartedContext,
+ACTION_P5(VerifySameDocumentStartedContext,
           web_state,
           url,
           context,
-          page_transition) {
+          page_transition,
+          renderer_initiated) {
   *context = arg0;
   ASSERT_TRUE(*context);
   EXPECT_EQ(web_state, (*context)->GetWebState());
@@ -147,11 +160,12 @@
 // Verifies correctness of |NavigationContext| (|arg0|) for same page navigation
 // passed to |DidFinishNavigation|. Asserts that |NavigationContext| the same as
 // |context|.
-ACTION_P4(VerifySameDocumentFinishedContext,
+ACTION_P5(VerifySameDocumentFinishedContext,
           web_state,
           url,
           context,
-          page_transition) {
+          page_transition,
+          renderer_initiated) {
   ASSERT_EQ(*context, arg0);
   ASSERT_TRUE(*context);
   EXPECT_EQ(web_state, (*context)->GetWebState());
@@ -182,6 +196,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_FALSE((*context)->IsRendererInitiated());
   EXPECT_FALSE((*context)->GetResponseHeaders());
   ASSERT_TRUE(web_state->IsLoading());
   NavigationManager* navigation_manager = web_state->GetNavigationManager();
@@ -203,6 +218,7 @@
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->IsPost());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_FALSE((*context)->IsRendererInitiated());
   EXPECT_FALSE((*context)->GetResponseHeaders());
   NavigationManager* navigation_manager = web_state->GetNavigationManager();
   NavigationItem* item = navigation_manager->GetLastCommittedItem();
@@ -223,6 +239,7 @@
                                (*context)->GetPageTransition()));
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_TRUE((*context)->IsRendererInitiated());
   EXPECT_FALSE((*context)->GetResponseHeaders());
   // TODO(crbug.com/676129): Reload does not create a pending item. Check
   // pending item once the bug is fixed.
@@ -242,6 +259,7 @@
                                (*context)->GetPageTransition()));
   EXPECT_FALSE((*context)->IsSameDocument());
   EXPECT_FALSE((*context)->GetError());
+  EXPECT_TRUE((*context)->IsRendererInitiated());
   if (is_web_page) {
     ASSERT_TRUE((*context)->GetResponseHeaders());
     std::string mime_type;
@@ -370,12 +388,14 @@
   EXPECT_CALL(*observer_, DidStartNavigation(_))
       .WillOnce(VerifySameDocumentStartedContext(
           web_state(), hash_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_TYPED));
+          ui::PageTransition::PAGE_TRANSITION_TYPED,
+          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
       .WillOnce(VerifySameDocumentFinishedContext(
           web_state(), hash_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_TYPED));
+          ui::PageTransition::PAGE_TRANSITION_TYPED,
+          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStopLoading());
   LoadUrl(hash_url);
 
@@ -383,12 +403,14 @@
   EXPECT_CALL(*observer_, DidStartNavigation(_))
       .WillOnce(VerifySameDocumentStartedContext(
           web_state(), url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
       .WillOnce(VerifySameDocumentFinishedContext(
           web_state(), url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStopLoading());
   ExecuteBlockAndWaitForLoad(url, ^{
     navigation_manager()->GoBack();
@@ -417,12 +439,14 @@
   EXPECT_CALL(*observer_, DidStartNavigation(_))
       .WillOnce(VerifySameDocumentStartedContext(
           web_state(), hash_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
       .WillOnce(VerifySameDocumentFinishedContext(
           web_state(), hash_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStopLoading());
   ExecuteJavaScript(@"window.location.hash = '#1'");
 }
@@ -449,11 +473,13 @@
   EXPECT_CALL(*observer_, DidStartNavigation(_))
       .WillOnce(VerifySameDocumentStartedContext(
           web_state(), push_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
       .WillOnce(VerifySameDocumentFinishedContext(
           web_state(), push_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   ExecuteJavaScript(@"window.history.pushState('', 'Test', 'test.html')");
 
   // Perform replace state using JavaScript.
@@ -461,11 +487,13 @@
   EXPECT_CALL(*observer_, DidStartNavigation(_))
       .WillOnce(VerifySameDocumentStartedContext(
           web_state(), replace_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
       .WillOnce(VerifySameDocumentFinishedContext(
           web_state(), replace_url, &context,
-          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT));
+          ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT,
+          /*renderer_initiated=*/true));
   ExecuteJavaScript(@"window.history.replaceState('', 'Test', '1.html')");
 }
 
@@ -515,10 +543,12 @@
   // Perform new page navigation.
   NavigationContext* context = nullptr;
   EXPECT_CALL(*observer_, DidStartNavigation(_))
-      .WillOnce(VerifyPostStartedContext(web_state(), url, &context));
+      .WillOnce(VerifyPostStartedContext(web_state(), url, &context,
+                                         /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
-      .WillOnce(VerifyPostFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyPostFinishedContext(web_state(), url, &context,
+                                          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStopLoading());
 
   // Load request using POST HTTP method.
@@ -551,10 +581,12 @@
 
   // Submit the form using JavaScript.
   EXPECT_CALL(*observer_, DidStartNavigation(_))
-      .WillOnce(VerifyPostStartedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostStartedContext(web_state(), action, &context,
+                                         /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
-      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context,
+                                          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStopLoading());
   ExecuteJavaScript(@"document.getElementById('form').submit();");
   ASSERT_TRUE(WaitForWebViewContainingText(web_state(), responses[action]));
@@ -590,10 +622,12 @@
 
   // Reload the page.
   EXPECT_CALL(*observer_, DidStartNavigation(_))
-      .WillOnce(VerifyPostStartedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostStartedContext(web_state(), action, &context,
+                                         /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
-      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context,
+                                          /*renderer_initiated=*/true));
   EXPECT_CALL(*observer_, DidStopLoading());
   // TODO(crbug.com/700958): ios/web ignores |check_for_repost| flag and current
   // delegate does not run callback for ShowRepostFormWarningDialog. Clearing
@@ -645,10 +679,12 @@
 
   // Go forward.
   EXPECT_CALL(*observer_, DidStartNavigation(_))
-      .WillOnce(VerifyPostStartedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostStartedContext(web_state(), action, &context,
+                                         /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStartLoading());
   EXPECT_CALL(*observer_, DidFinishNavigation(_))
-      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context));
+      .WillOnce(VerifyPostFinishedContext(web_state(), action, &context,
+                                          /*renderer_initiated=*/false));
   EXPECT_CALL(*observer_, DidStopLoading());
   // TODO(crbug.com/700958): ios/web ignores |check_for_repost| flag and current
   // delegate does not run callback for ShowRepostFormWarningDialog. Clearing
diff --git a/media/audio/alsa/alsa_input.cc b/media/audio/alsa/alsa_input.cc
index 6d756c8..790cd74 100644
--- a/media/audio/alsa/alsa_input.cc
+++ b/media/audio/alsa/alsa_input.cc
@@ -221,6 +221,11 @@
       callback_->OnData(this, audio_bus_.get(),
                         base::TimeTicks::Now() - hardware_delay,
                         normalized_volume);
+    } else if (frames_read < 0) {
+      bool success = Recover(frames_read);
+      LOG(WARNING) << "PcmReadi failed with error " << frames_read << ". "
+                   << (success ? "Successfully" : "Unsuccessfully")
+                   << " recovered.";
     } else {
       LOG(WARNING) << "PcmReadi returning less than expected frames: "
                    << frames_read << " vs. " << params_.frames_per_buffer()
diff --git a/net/cert/x509_util_nss.cc b/net/cert/x509_util_nss.cc
index 67cc2b3b..b32bd38 100644
--- a/net/cert/x509_util_nss.cc
+++ b/net/cert/x509_util_nss.cc
@@ -306,6 +306,14 @@
   return true;
 }
 
+bool GetPEMEncoded(CERTCertificate* cert, std::string* pem_encoded) {
+  if (!cert || !cert->derCert.len)
+    return false;
+  std::string der(reinterpret_cast<char*>(cert->derCert.data),
+                  cert->derCert.len);
+  return X509Certificate::GetPEMEncodedFromDER(der, pem_encoded);
+}
+
 void GetRFC822SubjectAltNames(CERTCertificate* cert_handle,
                               std::vector<std::string>* names) {
   crypto::ScopedSECItem alt_name(SECITEM_AllocItem(NULL, NULL, 0));
@@ -414,8 +422,10 @@
                       base::Time* not_after) {
   PRTime pr_not_before, pr_not_after;
   if (CERT_GetCertTimes(cert, &pr_not_before, &pr_not_after) == SECSuccess) {
-    *not_before = crypto::PRTimeToBaseTime(pr_not_before);
-    *not_after = crypto::PRTimeToBaseTime(pr_not_after);
+    if (not_before)
+      *not_before = crypto::PRTimeToBaseTime(pr_not_before);
+    if (not_after)
+      *not_after = crypto::PRTimeToBaseTime(pr_not_after);
     return true;
   }
   return false;
diff --git a/net/cert/x509_util_nss.h b/net/cert/x509_util_nss.h
index 3e144f9..6de1b49 100644
--- a/net/cert/x509_util_nss.h
+++ b/net/cert/x509_util_nss.h
@@ -82,6 +82,10 @@
 // true and writes the DER encoded certificate to |*der_encoded|.
 NET_EXPORT bool GetDEREncoded(CERTCertificate* cert, std::string* der_encoded);
 
+// Obtains the PEM encoded certificate data for |cert|. On success, returns
+// true and writes the PEM encoded certificate to |*pem_encoded|.
+NET_EXPORT bool GetPEMEncoded(CERTCertificate* cert, std::string* pem_encoded);
+
 // Stores the values of all rfc822Name subjectAltNames from |cert_handle|
 // into |names|. If no names are present, clears |names|.
 // WARNING: This method does not validate that the rfc822Name is
@@ -122,7 +126,8 @@
 NET_EXPORT std::string GetCERTNameDisplayName(CERTName* name);
 
 // Stores the notBefore and notAfter times from |cert| into |*not_before| and
-// |*not_after|, returning true if successful.
+// |*not_after|, returning true if successful. |not_before| or |not_after| may
+// be null.
 NET_EXPORT bool GetValidityTimes(CERTCertificate* cert,
                                  base::Time* not_before,
                                  base::Time* not_after);
diff --git a/net/cert/x509_util_nss_unittest.cc b/net/cert/x509_util_nss_unittest.cc
index 458fd00f..3b6af5d 100644
--- a/net/cert/x509_util_nss_unittest.cc
+++ b/net/cert/x509_util_nss_unittest.cc
@@ -370,6 +370,25 @@
             not_after.ToDoubleT());
 }
 
+TEST(X509UtilNSSTest, GetValidityTimesOptionalArgs) {
+  ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes(
+      google_der, arraysize(google_der)));
+  ASSERT_TRUE(google_cert);
+
+  base::Time not_before;
+  EXPECT_TRUE(
+      x509_util::GetValidityTimes(google_cert.get(), &not_before, nullptr));
+  // Constants copied from x509_certificate_unittest.cc.
+  EXPECT_EQ(1238192407,  // Mar 27 22:20:07 2009 GMT
+            not_before.ToDoubleT());
+
+  base::Time not_after;
+  EXPECT_TRUE(
+      x509_util::GetValidityTimes(google_cert.get(), nullptr, &not_after));
+  EXPECT_EQ(1269728407,  // Mar 27 22:20:07 2010 GMT
+            not_after.ToDoubleT());
+}
+
 TEST(X509UtilNSSTest, CalculateFingerprint256) {
   static const SHA256HashValue google_fingerprint = {
       {0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc
index 964e6f7..a205f3b 100644
--- a/net/quic/chromium/quic_stream_factory.cc
+++ b/net/quic/chromium/quic_stream_factory.cc
@@ -1025,22 +1025,19 @@
 }
 
 void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
-  // Copy |server_id|, because |job| might be destroyed before this method
-  // returns.
-  const QuicServerId server_id(job->key().server_id());
-
-  auto iter = active_jobs_.find(server_id);
+  auto iter = active_jobs_.find(job->key().server_id());
   // TODO(xunjieli): Change following CHECKs back to DCHECKs after
   // crbug.com/750271 is fixed.
   CHECK(iter != active_jobs_.end());
   if (rv == OK) {
     set_require_confirmation(false);
 
-    SessionMap::iterator session_it = active_sessions_.find(server_id);
+    SessionMap::iterator session_it =
+        active_sessions_.find(job->key().server_id());
     CHECK(session_it != active_sessions_.end());
     QuicChromiumClientSession* session = session_it->second;
     for (auto* request : iter->second->stream_requests()) {
-      CHECK(request->server_id() == server_id);
+      CHECK(request->server_id() == job->key().server_id());
       // Do not notify |request| yet.
       request->SetSession(session->CreateHandle());
     }
diff --git a/services/metrics/public/cpp/ukm_recorder.cc b/services/metrics/public/cpp/ukm_recorder.cc
index 8b3ae6a7..0cb0b15 100644
--- a/services/metrics/public/cpp/ukm_recorder.cc
+++ b/services/metrics/public/cpp/ukm_recorder.cc
@@ -14,7 +14,7 @@
 
 UkmRecorder* g_ukm_recorder = nullptr;
 
-#if defined(OS_IOS) || defined(OS_CHROMEOS)
+#if defined(OS_IOS)
 const base::Feature kUkmFeature = {"Ukm", base::FEATURE_DISABLED_BY_DEFAULT};
 #else
 const base::Feature kUkmFeature = {"Ukm", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc
index aa0fa1ec..b1afd56e 100644
--- a/services/ui/ws/event_dispatcher_unittest.cc
+++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -2387,10 +2387,12 @@
   viz::AggregatedHitTestRegion* aggregated_hit_test_region_list =
       aggregated_hit_test_region();
   aggregated_hit_test_region_list[0] = viz::AggregatedHitTestRegion(
-      root_window()->frame_sink_id(), viz::mojom::kHitTestMine,
+      root_window()->frame_sink_id(),
+      viz::mojom::kHitTestMine | viz::mojom::kHitTestMouse,
       root_window()->bounds(), root_window()->transform(), 1);  // root_window
   aggregated_hit_test_region_list[1] = viz::AggregatedHitTestRegion(
-      child->frame_sink_id(), viz::mojom::kHitTestMine, child->bounds(),
+      child->frame_sink_id(),
+      viz::mojom::kHitTestMine | viz::mojom::kHitTestMouse, child->bounds(),
       child->transform(), 0);  // child
 
   // Send event that is over child.
diff --git a/services/ui/ws/event_targeter.cc b/services/ui/ws/event_targeter.cc
index 467bf33..ddd1353 100644
--- a/services/ui/ws/event_targeter.cc
+++ b/services/ui/ws/event_targeter.cc
@@ -59,7 +59,7 @@
             updated_display_location.display_id);
     if (hit_test_query) {
       viz::Target target = hit_test_query->FindTargetForLocation(
-          updated_display_location.location);
+          event_source, updated_display_location.location);
       if (target.frame_sink_id.is_valid()) {
         ServerWindow* target_window =
             event_targeter_delegate_->GetWindowFromFrameSinkId(
diff --git a/services/ui/ws/window_finder.h b/services/ui/ws/window_finder.h
index e845860..5a461d22 100644
--- a/services/ui/ws/window_finder.h
+++ b/services/ui/ws/window_finder.h
@@ -5,6 +5,8 @@
 #ifndef SERVICES_UI_WS_WINDOW_FINDER_H_
 #define SERVICES_UI_WS_WINDOW_FINDER_H_
 
+#include "components/viz/host/hit_test/hit_test_query.h"
+
 namespace gfx {
 class Point;
 }
@@ -19,10 +21,7 @@
   bool in_non_client_area = false;
 };
 
-enum class EventSource {
-  MOUSE,
-  TOUCH,
-};
+using EventSource = viz::EventSource;
 
 // Finds the deepest visible child of |root| that should receive an event at
 // |location|. |location| is in the coordinate space of |root_window|. The
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 03cfaab..6fad4d2 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -122,6 +122,36 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -484,6 +514,36 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -880,6 +940,37 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "M",
+              "device_type": "bullhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -1252,6 +1343,36 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -1644,6 +1765,36 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -2006,6 +2157,36 @@
         },
         "test": "gl_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -2476,6 +2657,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -2883,6 +3077,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -2942,6 +3149,19 @@
         },
         "test": "angle_unittests",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1912",
+              "os": "Ubuntu"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": []
@@ -3072,6 +3292,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -3520,6 +3753,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -3968,6 +4214,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "10de:1cb3",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -4423,6 +4682,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -4951,6 +5223,19 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -5363,6 +5648,19 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -5795,6 +6093,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -6239,6 +6551,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -6718,6 +7044,24 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            },
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -7186,6 +7530,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "1002:679e",
+              "os": "Mac-10.10"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -7570,6 +7927,19 @@
         },
         "test": "gles2_conform_test",
         "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "1002:679e",
+              "os": "Mac-10.10"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -7987,6 +8357,19 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -8418,6 +8801,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -8834,6 +9231,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -9271,6 +9682,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -9736,6 +10161,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -10134,6 +10573,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Ubuntu"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -10288,6 +10740,19 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -10431,6 +10896,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -10578,6 +11057,20 @@
         "use_xvfb": false
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
         "args": [
           "--gtest_filter=*Detection*",
           "--use-gpu-in-tests"
@@ -10756,6 +11249,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       }
@@ -11087,6 +11593,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-10"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -11682,6 +12201,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912",
+              "os": "Windows-10"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -12285,6 +12817,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "10de:1cb3",
+              "os": "Windows-10"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -12913,6 +13458,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-10"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -13611,6 +14169,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -14168,6 +14739,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -14763,6 +15347,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -15367,6 +15964,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -15971,6 +16581,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -16767,6 +17390,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
@@ -17368,6 +18004,19 @@
             }
           ]
         },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
         "test": "swiftshader_unittests",
         "use_xvfb": false
       },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index dc882d6..ef01d040 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -224,7 +224,6 @@
 crbug.com/591099 animations/interpolation/background-size-interpolation.html [ Pass Timeout ]
 crbug.com/591099 animations/interpolation/border-image-width-interpolation.html [ Crash Pass Timeout ]
 crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Crash Pass Timeout ]
-crbug.com/591099 animations/interpolation/svg-d-interpolation.html [ Crash Timeout ]
 crbug.com/591099 animations/interpolation/svg-stroke-dasharray-interpolation.html [ Crash Timeout ]
 crbug.com/591099 animations/interpolation/webkit-clip-path-interpolation.html [ Crash Pass Timeout ]
 crbug.com/757767 animations/interpolation/webkit-column-count-interpolation.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 5d4414e5..740ffee 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -440,7 +440,6 @@
 crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-filter-modified-save-restore.html [ Slow ]
 crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-filter-modified.html [ Slow ]
 crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-scale-drawImage-shadow.html [ Slow ]
-crbug.com/726075 [ Win Debug ] virtual/threaded/animations/interpolation/svg-d-interpolation.html [ Slow ]
 crbug.com/726075 [ Win Debug ] virtual/threaded/animations/svg/animated-filter-svg-element.html [ Slow ]
 
 # IDB Observer tests require multiple browsing contexts/workers interacting with
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 1149b32..e248315c 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2497,6 +2497,12 @@
 # Added 2016-12-15
 crbug.com/674466 [ Win10 ] fast/forms/select/menulist-appearance-rtl.html [ Pass Failure ]
 
+# Need rebaseline after skia roll with https://skia-review.googlesource.com/c/skia/+/43183/
+crbug.com/760738 virtual/gpu-rasterization/images/color-profile-background-image-space.html [ NeedsManualRebaseline ]
+crbug.com/760738 virtual/gpu-rasterization/images/color-profile-svg-fill-text.html [ NeedsManualRebaseline ]
+crbug.com/760738 virtual/gpu-rasterization/images/color-profile-svg.html [ NeedsManualRebaseline ]
+crbug.com/760738 virtual/gpu-rasterization/images/cross-fade-background-size.html [ NeedsManualRebaseline ]
+
 # ====== Random order flaky tests from here ======
 # These tests are flaky when run in random order, which is the default on Linux & Mac since since 2016-12-16.
 
@@ -3610,7 +3616,6 @@
 crbug.com/757698 external/wpt/WebCryptoAPI/generateKey/test_successes_RSASSA-PKCS1-v1_5.https.html [ Skip ]
 
 # Tests occasionaly timing out (flaky) on WebKit Win7 dbg builder
-crbug.com/757955 [ Win7 Debug ] animations/interpolation/svg-d-interpolation.html [ Pass Timeout ]
 crbug.com/757955 [ Win7 Debug ] http/tests/devtools/sources/debugger-pause/pause-on-elements-panel.html [ Pass Timeout ]
 crbug.com/667560 [ Win7 Debug ] virtual/mojo-loading/http/tests/devtools/sources/debugger-pause/pause-on-elements-panel.html [ Pass Timeout ]
 crbug.com/757955 [ Win7 Debug ] media/color-profile-video-seek-filter.html [ Pass Timeout ]
@@ -3670,3 +3675,6 @@
 crbug.com/762423 [ Android ] http/tests/dom/create-contextual-fragment-from-svg-document-range.html [ Pass Crash ]
 crbug.com/762399 [ Android ] http/tests/cache/zero-length-xhr.html [ Pass Crash ]
 crbug.com/762486 [ Win7 Debug ] virtual/mojo-loading/http/tests/security/xss-DENIED-iframe-src-alias.html [ Pass Failure ]
+
+# Flaky
+crbug.com/747975 [ Mac10.12 Linux ] virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index 84efee2..3da8f1e 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -21,10 +21,10 @@
 external/wpt/annotation-model [ Skip ]
 external/wpt/annotation-protocol [ Skip ]
 external/wpt/annotation-vocab [ Skip ]
-external/wpt/app-uri [ Skip ]
 external/wpt/check_stability.ini [ Skip ]
 external/wpt/config.default.json [ Skip ]
 external/wpt/conformance-checkers [ Skip ]
+external/wpt/core-aam [ Skip ]
 external/wpt/css/.htaccess [ Skip ]
 external/wpt/css/CSS1 [ Skip ]
 external/wpt/css/CSS2/LICENSE-BSD [ Skip ]
@@ -163,17 +163,11 @@
 external/wpt/fonts/math [ Skip ]
 external/wpt/html-longdesc [ Skip ]
 external/wpt/js [ Skip ]
-external/wpt/lint [ Skip ]
-external/wpt/manifest [ Skip ]
 external/wpt/mathml [ Skip ]
-external/wpt/microdata [ Skip ]
 external/wpt/old-tests [ Skip ]
 external/wpt/proximity [ Skip ]
-external/wpt/resources/docs [ Skip ]
-external/wpt/resources/examples [ Skip ]
 external/wpt/resources/webidl2/README.md [ Skip ]
 external/wpt/resources/webidl2/test [ Skip ]
-external/wpt/serve [ Skip ]
 external/wpt/serve.py [ Skip ]
 external/wpt/server-side.md [ Skip ]
 external/wpt/svg-aam [ Skip ]
@@ -206,7 +200,6 @@
 # webkitpy/thirdparty/wpt so that we can manually update them and keep
 # a stable pinned version.
 external/wpt/tools [ Skip ]
-external/wpt/wptrun [ Skip ]
 external/wpt/wpt [ Skip ]
 external/wpt/wpt.py [ Skip ]
 
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-001.html b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-001.html
new file mode 100644
index 0000000..999efe0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-001.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+.parent {
+  cx: 100px;
+}
+.target {
+  font-size: 16px;
+  cx: 50px;
+}
+.expected {
+  fill: green;
+}
+</style>
+<body>
+<template id="target-template">
+  <svg width="90" height="90">
+    <path class="target" />
+  </svg>
+</template>
+<script src="resources/interpolation-test.js"></script>
+<script>
+'use strict';
+
+// Distinct number of path segments
+assertNoInterpolation({
+  property: 'd',
+  from: "path('m 0 0 h 1 h 2')",
+  to: "path('m 0 0 h 3')"
+});
+
+assertNoInterpolation({
+  property: 'd',
+  from: "path('M 1 2 L 3 4 Z')",
+  to: "none"
+});
+
+// Distinct segment types
+assertNoInterpolation({
+  property: 'd',
+  from: "path('m 10 0 h 1')",
+  to: "path('m 20 0 v 2')"
+});
+
+assertNoInterpolation({
+  property: 'd',
+  from: "path('m 1 2 l 3 4 Z')",
+  to: "path('m 1 2 l 3 4')"
+});
+
+// Exercise each segment type
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 Z')",
+  to: "path('m 0 0 Z')"
+}, [
+  {at: -0.4, is: "path('m 0 0 Z')"},
+  {at: 0, is: "path('m 0 0 Z')"},
+  {at: 0.2, is: "path('m 0 0 Z')"},
+  {at: 0.6, is: "path('m 0 0 Z')"},
+  {at: 1, is: "path('m 0 0 Z')"},
+  {at: 1.4, is: "path('m 0 0 Z')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('M 20 50')",
+  to: "path('M 30 70')"
+}, [
+  {at: -0.4, is: "path('M 16 42')"},
+  {at: 0, is: "path('M 20 50')"},
+  {at: 0.2, is: "path('M 22 54')"},
+  {at: 0.6, is: "path('M 26 62')"},
+  {at: 1, is: "path('M 30 70')"},
+  {at: 1.4, is: "path('M 34 78')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 20 50')",
+  to: "path('m 30 70')"
+}, [
+  {at: -0.4, is: "path('m 16 42')"},
+  {at: 0, is: "path('m 20 50')"},
+  {at: 0.2, is: "path('m 22 54')"},
+  {at: 0.6, is: "path('m 26 62')"},
+  {at: 1, is: "path('m 30 70')"},
+  {at: 1.4, is: "path('m 34 78')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 L 20 50')",
+  to: "path('m 0 0 L 30 70')"
+}, [
+  {at: -0.4, is: "path('m 0 0 L 16 42')"},
+  {at: 0, is: "path('m 0 0 L 20 50')"},
+  {at: 0.2, is: "path('m 0 0 L 22 54')"},
+  {at: 0.6, is: "path('m 0 0 L 26 62')"},
+  {at: 1, is: "path('m 0 0 L 30 70')"},
+  {at: 1.4, is: "path('m 0 0 L 34 78')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 l 20 50')",
+  to: "path('m 0 0 l 30 70')"
+}, [
+  {at: -0.4, is: "path('m 0 0 l 16 42')"},
+  {at: 0, is: "path('m 0 0 l 20 50')"},
+  {at: 0.2, is: "path('m 0 0 l 22 54')"},
+  {at: 0.6, is: "path('m 0 0 l 26 62')"},
+  {at: 1, is: "path('m 0 0 l 30 70')"},
+  {at: 1.4, is: "path('m 0 0 l 34 78')"}
+]);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-002.html b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-002.html
new file mode 100644
index 0000000..7450038
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-002.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+.parent {
+  cx: 100px;
+}
+.target {
+  font-size: 16px;
+  cx: 50px;
+}
+.expected {
+  fill: green;
+}
+</style>
+<body>
+<template id="target-template">
+  <svg width="90" height="90">
+    <path class="target" />
+  </svg>
+</template>
+<script src="resources/interpolation-test.js"></script>
+<script>
+'use strict';
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 C 32 42 52 62 12 22')",
+  to: "path('m 0 0 C 37 47 57 67 17 27')",
+}, [
+  {at: -0.4, is: "path('m 0 0 C 30 40 50 60 10 20')"},
+  {at: 0, is: "path('m 0 0 C 32 42 52 62 12 22')"},
+  {at: 0.2, is: "path('m 0 0 C 33 43 53 63 13 23')"},
+  {at: 0.6, is: "path('m 0 0 C 35 45 55 65 15 25')"},
+  {at: 1, is: "path('m 0 0 C 37 47 57 67 17 27')"},
+  {at: 1.4, is: "path('m 0 0 C 39 49 59 69 19 29')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 c 32 42 52 62 12 22')",
+  to: "path('m 0 0 c 37 47 57 67 17 27')"
+}, [
+  {at: -0.4, is: "path('m 0 0 c 30 40 50 60 10 20')"},
+  {at: 0, is: "path('m 0 0 c 32 42 52 62 12 22')"},
+  {at: 0.2, is: "path('m 0 0 c 33 43 53 63 13 23')"},
+  {at: 0.6, is: "path('m 0 0 c 35 45 55 65 15 25')"},
+  {at: 1, is: "path('m 0 0 c 37 47 57 67 17 27')"},
+  {at: 1.4, is: "path('m 0 0 c 39 49 59 69 19 29')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 Q 32 42 52 62')",
+  to: "path('m 0 0 Q 37 47 57 67')"
+}, [
+  {at: -0.4, is: "path('m 0 0 Q 30 40 50 60')"},
+  {at: 0, is: "path('m 0 0 Q 32 42 52 62')"},
+  {at: 0.2, is: "path('m 0 0 Q 33 43 53 63')"},
+  {at: 0.6, is: "path('m 0 0 Q 35 45 55 65')"},
+  {at: 1, is: "path('m 0 0 Q 37 47 57 67')"},
+  {at: 1.4, is: "path('m 0 0 Q 39 49 59 69')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 q 32 42 52 62')",
+  to: "path('m 0 0 q 37 47 57 67')"
+}, [
+  {at: -0.4, is: "path('m 0 0 q 30 40 50 60')"},
+  {at: 0, is: "path('m 0 0 q 32 42 52 62')"},
+  {at: 0.2, is: "path('m 0 0 q 33 43 53 63')"},
+  {at: 0.6, is: "path('m 0 0 q 35 45 55 65')"},
+  {at: 1, is: "path('m 0 0 q 37 47 57 67')"},
+  {at: 1.4, is: "path('m 0 0 q 39 49 59 69')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 A 10 20 30 1 0 40 50')",
+  to: "path('m 0 0 A 60 70 80 0 1 90 100')"
+}, [
+  {at: -0.4, is: "path('m 0 0 A -10 0 10 1 0 20 30')"},
+  {at: 0, is: "path('m 0 0 A 10 20 30 1 0 40 50')"},
+  {at: 0.2, is: "path('m 0 0 A 20 30 40 1 0 50 60')"},
+  {at: 0.6, is: "path('m 0 0 A 40 50 60 0 1 70 80')"},
+  {at: 1, is: "path('m 0 0 A 60 70 80 0 1 90 100')"},
+  {at: 1.4, is: "path('m 0 0 A 80 90 100 0 1 110 120')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 a 10 20 30 1 0 40 50')",
+  to: "path('m 0 0 a 60 70 80 0 1 90 100')"
+}, [
+  {at: -0.4, is: "path('m 0 0 a -10 0 10 1 0 20 30')"},
+  {at: 0, is: "path('m 0 0 a 10 20 30 1 0 40 50')"},
+  {at: 0.2, is: "path('m 0 0 a 20 30 40 1 0 50 60')"},
+  {at: 0.6, is: "path('m 0 0 a 40 50 60 0 1 70 80')"},
+  {at: 1, is: "path('m 0 0 a 60 70 80 0 1 90 100')"},
+  {at: 1.4, is: "path('m 0 0 a 80 90 100 0 1 110 120')"}
+]);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-003.html b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-003.html
new file mode 100644
index 0000000..62ab549
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-003.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+.parent {
+  cx: 100px;
+}
+.target {
+  font-size: 16px;
+  cx: 50px;
+}
+.expected {
+  fill: green;
+}
+</style>
+<body>
+<template id="target-template">
+  <svg width="90" height="90">
+    <path class="target" />
+  </svg>
+</template>
+<script src="resources/interpolation-test.js"></script>
+<script>
+'use strict';
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 H 10')",
+  to: "path('m 0 0 H 60')"
+}, [
+  {at: -0.4, is: "path('m 0 0 H -10')"},
+  {at: 0, is: "path('m 0 0 H 10')"},
+  {at: 0.2, is: "path('m 0 0 H 20')"},
+  {at: 0.6, is: "path('m 0 0 H 40')"},
+  {at: 1, is: "path('m 0 0 H 60')"},
+  {at: 1.4, is: "path('m 0 0 H 80')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 h 10')",
+  to: "path('m 0 0 h 60')"
+}, [
+  {at: -0.4, is: "path('m 0 0 h -10')"},
+  {at: 0, is: "path('m 0 0 h 10')"},
+  {at: 0.2, is: "path('m 0 0 h 20')"},
+  {at: 0.6, is: "path('m 0 0 h 40')"},
+  {at: 1, is: "path('m 0 0 h 60')"},
+  {at: 1.4, is: "path('m 0 0 h 80')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 V 10')",
+  to: "path('m 0 0 V 60')"
+}, [
+  {at: -0.4, is: "path('m 0 0 V -10')"},
+  {at: 0, is: "path('m 0 0 V 10')"},
+  {at: 0.2, is: "path('m 0 0 V 20')"},
+  {at: 0.6, is: "path('m 0 0 V 40')"},
+  {at: 1, is: "path('m 0 0 V 60')"},
+  {at: 1.4, is: "path('m 0 0 V 80')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 v 10')",
+  to: "path('m 0 0 v 60')"
+}, [
+  {at: -0.4, is: "path('m 0 0 v -10')"},
+  {at: 0, is: "path('m 0 0 v 10')"},
+  {at: 0.2, is: "path('m 0 0 v 20')"},
+  {at: 0.6, is: "path('m 0 0 v 40')"},
+  {at: 1, is: "path('m 0 0 v 60')"},
+  {at: 1.4, is: "path('m 0 0 v 80')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 S 32 42 52 62')",
+  to: "path('m 0 0 S 37 47 57 67')"
+}, [
+  {at: -0.4, is: "path('m 0 0 S 30 40 50 60')"},
+  {at: 0, is: "path('m 0 0 S 32 42 52 62')"},
+  {at: 0.2, is: "path('m 0 0 S 33 43 53 63')"},
+  {at: 0.6, is: "path('m 0 0 S 35 45 55 65')"},
+  {at: 1, is: "path('m 0 0 S 37 47 57 67')"},
+  {at: 1.4, is: "path('m 0 0 S 39 49 59 69')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 s 32 42 52 62')",
+  to: "path('m 0 0 s 37 47 57 67')"
+}, [
+  {at: -0.4, is: "path('m 0 0 s 30 40 50 60')"},
+  {at: 0, is: "path('m 0 0 s 32 42 52 62')"},
+  {at: 0.2, is: "path('m 0 0 s 33 43 53 63')"},
+  {at: 0.6, is: "path('m 0 0 s 35 45 55 65')"},
+  {at: 1, is: "path('m 0 0 s 37 47 57 67')"},
+  {at: 1.4, is: "path('m 0 0 s 39 49 59 69')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 T 20 50')",
+  to: "path('m 0 0 T 30 70')"
+}, [
+  {at: -0.4, is: "path('m 0 0 T 16 42')"},
+  {at: 0, is: "path('m 0 0 T 20 50')"},
+  {at: 0.2, is: "path('m 0 0 T 22 54')"},
+  {at: 0.6, is: "path('m 0 0 T 26 62')"},
+  {at: 1, is: "path('m 0 0 T 30 70')"},
+  {at: 1.4, is: "path('m 0 0 T 34 78')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 0 0 t 20 50')",
+  to: "path('m 0 0 t 30 70')"
+}, [
+  {at: -0.4, is: "path('m 0 0 t 16 42')"},
+  {at: 0, is: "path('m 0 0 t 20 50')"},
+  {at: 0.2, is: "path('m 0 0 t 22 54')"},
+  {at: 0.6, is: "path('m 0 0 t 26 62')"},
+  {at: 1, is: "path('m 0 0 t 30 70')"},
+  {at: 1.4, is: "path('m 0 0 t 34 78')"},
+]);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-004.html b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-004.html
new file mode 100644
index 0000000..18a3427
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation-004.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+.parent {
+  cx: 100px;
+}
+.target {
+  font-size: 16px;
+  cx: 50px;
+}
+.expected {
+  fill: green;
+}
+</style>
+<body>
+<template id="target-template">
+  <svg width="90" height="90">
+    <path class="target" />
+  </svg>
+</template>
+<script src="resources/interpolation-test.js"></script>
+<script>
+'use strict';
+
+// Mix relative and non-relative
+assertInterpolation({
+  property: 'd',
+  from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')",
+  to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 200 100 z')"
+}, [
+  {at: -0.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 60 -180 Z')"},
+  {at: 0, is: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"},
+  {at: 0.2, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 120 -60 Z')"},
+  {at: 0.6, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 160 20 Z')"},
+  {at: 1, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 200 100 Z')"},
+  {at: 1.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 240 180 Z')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')",
+  to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')"
+}, [
+  {at: -0.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
+  {at: 0, is: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"},
+  {at: 0.2, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
+  {at: 0.6, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
+  {at: 1, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
+  {at: 1.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 l 20 30 z l 50 60 z m 70 80 l 90 60 z t 70 120')",
+  to: "path('M 110 120 L 130 150 Z L 80 110 Z M 100 140 L 190 200 Z T 210 220')"
+}, [
+  {at: -0.4, is: "path('M -30 -20 L -10 10 Z L 52 68 Z M 72 84 L 162 144 Z T 126 220')"},
+  {at: 0, is: "path('m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120')"},
+  {at: 0.2, is: "path('M 30 40 L 50 70 Z L 64 86 Z M 84 108 L 174 168 Z T 162 220')"},
+  {at: 0.6, is: "path('M 70 80 L 90 110 Z L 72 98 Z M 92 124 L 182 184 Z T 186 220')"},
+  {at: 1, is: "path('M 110 120 L 130 150 Z L 80 110 Z M 100 140 L 190 200 Z T 210 220')"},
+  {at: 1.4, is: "path('M 150 160 L 170 190 Z L 88 122 Z M 108 156 L 198 216 Z T 234 220')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 c 40 50 30 60 80 70 c 90 100 140 110 120 130')",
+  to: "path('M 110 120 C 140 150 130 160 180 170 C 290 300 340 310 320 330')"
+}, [
+  {at: -0.4, is: "path('M -30 -20 C 14 38 4 48 54 58 C 136 146 186 156 166 176')"},
+  {at: 0, is: "path('m 10 20 c 40 50 30 60 80 70 c 90 100 140 110 120 130')"},
+  {at: 0.2, is: "path('M 30 40 C 68 86 58 96 108 106 C 202 212 252 222 232 242')"},
+  {at: 0.6, is: "path('M 70 80 C 104 118 94 128 144 138 C 246 256 296 266 276 286')"},
+  {at: 1, is: "path('M 110 120 C 140 150 130 160 180 170 C 290 300 340 310 320 330')"},
+  {at: 1.4, is: "path('M 150 160 C 176 182 166 192 216 202 C 334 344 384 354 364 374')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 q 30 60 40 50 q 100 70 90 80')",
+  to: "path('M 110 120 Q 130 160 140 150 Q 200 170 190 180')"
+}, [
+  {at: -0.4, is: "path('M -30 -20 Q 4 48 14 38 Q 130 128 120 138')"},
+  {at: 0, is: "path('m 10 20 q 30 60 40 50 q 100 70 90 80')"},
+  {at: 0.2, is: "path('M 30 40 Q 58 96 68 86 Q 160 146 150 156')"},
+  {at: 0.6, is: "path('M 70 80 Q 94 128 104 118 Q 180 158 170 168')"},
+  {at: 1, is: "path('M 110 120 Q 130 160 140 150 Q 200 170 190 180')"},
+  {at: 1.4, is: "path('M 150 160 Q 166 192 176 182 Q 220 182 210 192')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 s 30 60 40 50 s 100 70 90 80')",
+  to: "path('M 110 120 S 130 160 140 150 S 200 170 190 180')"
+}, [
+  {at: -0.4, is: "path('M -30 -20 S 4 48 14 38 S 130 128 120 138')"},
+  {at: 0, is: "path('m 10 20 s 30 60 40 50 s 100 70 90 80')"},
+  {at: 0.2, is: "path('M 30 40 S 58 96 68 86 S 160 146 150 156')"},
+  {at: 0.6, is: "path('M 70 80 S 94 128 104 118 S 180 158 170 168')"},
+  {at: 1, is: "path('M 110 120 S 130 160 140 150 S 200 170 190 180')"},
+  {at: 1.4, is: "path('M 150 160 S 166 192 176 182 S 220 182 210 192')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 h 30 v 40 h 50 v 60 l 70 80')",
+  to: "path('M 110 120 H 130 V 140 H 250 V 260 L 270 280')"
+}, [
+  {at: -0.4, is: "path('M -30 -20 H 4 V 28 H 26 V 64 L 116 168')"},
+  {at: 0, is: "path('m 10 20 h 30 v 40 h 50 v 60 l 70 80')"},
+  {at: 0.2, is: "path('M 30 40 H 58 V 76 H 122 V 148 L 182 216')"},
+  {at: 0.6, is: "path('M 70 80 H 94 V 108 H 186 V 204 L 226 248')"},
+  {at: 1, is: "path('M 110 120 H 130 V 140 H 250 V 260 L 270 280')"},
+  {at: 1.4, is: "path('M 150 160 H 166 V 172 H 314 V 316 L 314 312')"}
+]);
+
+assertInterpolation({
+  property: 'd',
+  from: "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')",
+  to: "path('M 20 30 A 60 70 80 0 1 90 100 A 160 170 80 0 1 90 100')"
+}, [
+  {at: -0.4, is: "path('M 6 16 A -10 0 10 1 0 34 58 A 90 100 10 1 1 230 128')"},
+  {at: 0, is: "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')"},
+  {at: 0.2, is: "path('M 12 22 A 20 30 40 1 0 58 76 A 120 130 40 1 1 170 116')"},
+  {at: 0.6, is: "path('M 16 26 A 40 50 60 0 1 74 88 A 140 150 60 0 1 130 108')"},
+  {at: 1, is: "path('M 20 30 A 60 70 80 0 1 90 100 A 160 170 80 0 1 90 100')"},
+  {at: 1.4, is: "path('M 24 34 A 80 90 100 0 1 106 112 A 180 190 100 0 1 50 92')"}
+]);
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation.html b/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation.html
deleted file mode 100644
index 211dfdf7..0000000
--- a/third_party/WebKit/LayoutTests/animations/interpolation/svg-d-interpolation.html
+++ /dev/null
@@ -1,406 +0,0 @@
-<!DOCTYPE html>
-<meta charset="UTF-8">
-<style>
-.parent {
-  cx: 100px;
-}
-.target {
-  font-size: 16px;
-  cx: 50px;
-}
-.expected {
-  fill: green;
-}
-</style>
-<body>
-<template id="target-template">
-  <svg width="90" height="90">
-    <path class="target" />
-  </svg>
-</template>
-<script src="resources/interpolation-test.js"></script>
-<script>
-'use strict';
-
-// Distinct number of path segments
-assertNoInterpolation({
-  property: 'd',
-  from: "path('m 0 0 h 1 h 2')",
-  to: "path('m 0 0 h 3')"
-});
-
-assertNoInterpolation({
-  property: 'd',
-  from: "path('M 1 2 L 3 4 Z')",
-  to: "none"
-});
-
-// Distinct segment types
-assertNoInterpolation({
-  property: 'd',
-  from: "path('m 10 0 h 1')",
-  to: "path('m 20 0 v 2')"
-});
-
-assertNoInterpolation({
-  property: 'd',
-  from: "path('m 1 2 l 3 4 Z')",
-  to: "path('m 1 2 l 3 4')"
-});
-
-// Exercise each segment type
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 Z')",
-  to: "path('m 0 0 Z')"
-}, [
-  {at: -0.4, is: "path('m 0 0 Z')"},
-  {at: 0, is: "path('m 0 0 Z')"},
-  {at: 0.2, is: "path('m 0 0 Z')"},
-  {at: 0.6, is: "path('m 0 0 Z')"},
-  {at: 1, is: "path('m 0 0 Z')"},
-  {at: 1.4, is: "path('m 0 0 Z')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('M 20 50')",
-  to: "path('M 30 70')"
-}, [
-  {at: -0.4, is: "path('M 16 42')"},
-  {at: 0, is: "path('M 20 50')"},
-  {at: 0.2, is: "path('M 22 54')"},
-  {at: 0.6, is: "path('M 26 62')"},
-  {at: 1, is: "path('M 30 70')"},
-  {at: 1.4, is: "path('M 34 78')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 20 50')",
-  to: "path('m 30 70')"
-}, [
-  {at: -0.4, is: "path('m 16 42')"},
-  {at: 0, is: "path('m 20 50')"},
-  {at: 0.2, is: "path('m 22 54')"},
-  {at: 0.6, is: "path('m 26 62')"},
-  {at: 1, is: "path('m 30 70')"},
-  {at: 1.4, is: "path('m 34 78')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 L 20 50')",
-  to: "path('m 0 0 L 30 70')"
-}, [
-  {at: -0.4, is: "path('m 0 0 L 16 42')"},
-  {at: 0, is: "path('m 0 0 L 20 50')"},
-  {at: 0.2, is: "path('m 0 0 L 22 54')"},
-  {at: 0.6, is: "path('m 0 0 L 26 62')"},
-  {at: 1, is: "path('m 0 0 L 30 70')"},
-  {at: 1.4, is: "path('m 0 0 L 34 78')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 l 20 50')",
-  to: "path('m 0 0 l 30 70')"
-}, [
-  {at: -0.4, is: "path('m 0 0 l 16 42')"},
-  {at: 0, is: "path('m 0 0 l 20 50')"},
-  {at: 0.2, is: "path('m 0 0 l 22 54')"},
-  {at: 0.6, is: "path('m 0 0 l 26 62')"},
-  {at: 1, is: "path('m 0 0 l 30 70')"},
-  {at: 1.4, is: "path('m 0 0 l 34 78')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 C 32 42 52 62 12 22')",
-  to: "path('m 0 0 C 37 47 57 67 17 27')",
-}, [
-  {at: -0.4, is: "path('m 0 0 C 30 40 50 60 10 20')"},
-  {at: 0, is: "path('m 0 0 C 32 42 52 62 12 22')"},
-  {at: 0.2, is: "path('m 0 0 C 33 43 53 63 13 23')"},
-  {at: 0.6, is: "path('m 0 0 C 35 45 55 65 15 25')"},
-  {at: 1, is: "path('m 0 0 C 37 47 57 67 17 27')"},
-  {at: 1.4, is: "path('m 0 0 C 39 49 59 69 19 29')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 c 32 42 52 62 12 22')",
-  to: "path('m 0 0 c 37 47 57 67 17 27')"
-}, [
-  {at: -0.4, is: "path('m 0 0 c 30 40 50 60 10 20')"},
-  {at: 0, is: "path('m 0 0 c 32 42 52 62 12 22')"},
-  {at: 0.2, is: "path('m 0 0 c 33 43 53 63 13 23')"},
-  {at: 0.6, is: "path('m 0 0 c 35 45 55 65 15 25')"},
-  {at: 1, is: "path('m 0 0 c 37 47 57 67 17 27')"},
-  {at: 1.4, is: "path('m 0 0 c 39 49 59 69 19 29')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 Q 32 42 52 62')",
-  to: "path('m 0 0 Q 37 47 57 67')"
-}, [
-  {at: -0.4, is: "path('m 0 0 Q 30 40 50 60')"},
-  {at: 0, is: "path('m 0 0 Q 32 42 52 62')"},
-  {at: 0.2, is: "path('m 0 0 Q 33 43 53 63')"},
-  {at: 0.6, is: "path('m 0 0 Q 35 45 55 65')"},
-  {at: 1, is: "path('m 0 0 Q 37 47 57 67')"},
-  {at: 1.4, is: "path('m 0 0 Q 39 49 59 69')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 q 32 42 52 62')",
-  to: "path('m 0 0 q 37 47 57 67')"
-}, [
-  {at: -0.4, is: "path('m 0 0 q 30 40 50 60')"},
-  {at: 0, is: "path('m 0 0 q 32 42 52 62')"},
-  {at: 0.2, is: "path('m 0 0 q 33 43 53 63')"},
-  {at: 0.6, is: "path('m 0 0 q 35 45 55 65')"},
-  {at: 1, is: "path('m 0 0 q 37 47 57 67')"},
-  {at: 1.4, is: "path('m 0 0 q 39 49 59 69')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 A 10 20 30 1 0 40 50')",
-  to: "path('m 0 0 A 60 70 80 0 1 90 100')"
-}, [
-  {at: -0.4, is: "path('m 0 0 A -10 0 10 1 0 20 30')"},
-  {at: 0, is: "path('m 0 0 A 10 20 30 1 0 40 50')"},
-  {at: 0.2, is: "path('m 0 0 A 20 30 40 1 0 50 60')"},
-  {at: 0.6, is: "path('m 0 0 A 40 50 60 0 1 70 80')"},
-  {at: 1, is: "path('m 0 0 A 60 70 80 0 1 90 100')"},
-  {at: 1.4, is: "path('m 0 0 A 80 90 100 0 1 110 120')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 a 10 20 30 1 0 40 50')",
-  to: "path('m 0 0 a 60 70 80 0 1 90 100')"
-}, [
-  {at: -0.4, is: "path('m 0 0 a -10 0 10 1 0 20 30')"},
-  {at: 0, is: "path('m 0 0 a 10 20 30 1 0 40 50')"},
-  {at: 0.2, is: "path('m 0 0 a 20 30 40 1 0 50 60')"},
-  {at: 0.6, is: "path('m 0 0 a 40 50 60 0 1 70 80')"},
-  {at: 1, is: "path('m 0 0 a 60 70 80 0 1 90 100')"},
-  {at: 1.4, is: "path('m 0 0 a 80 90 100 0 1 110 120')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 H 10')",
-  to: "path('m 0 0 H 60')"
-}, [
-  {at: -0.4, is: "path('m 0 0 H -10')"},
-  {at: 0, is: "path('m 0 0 H 10')"},
-  {at: 0.2, is: "path('m 0 0 H 20')"},
-  {at: 0.6, is: "path('m 0 0 H 40')"},
-  {at: 1, is: "path('m 0 0 H 60')"},
-  {at: 1.4, is: "path('m 0 0 H 80')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 h 10')",
-  to: "path('m 0 0 h 60')"
-}, [
-  {at: -0.4, is: "path('m 0 0 h -10')"},
-  {at: 0, is: "path('m 0 0 h 10')"},
-  {at: 0.2, is: "path('m 0 0 h 20')"},
-  {at: 0.6, is: "path('m 0 0 h 40')"},
-  {at: 1, is: "path('m 0 0 h 60')"},
-  {at: 1.4, is: "path('m 0 0 h 80')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 V 10')",
-  to: "path('m 0 0 V 60')"
-}, [
-  {at: -0.4, is: "path('m 0 0 V -10')"},
-  {at: 0, is: "path('m 0 0 V 10')"},
-  {at: 0.2, is: "path('m 0 0 V 20')"},
-  {at: 0.6, is: "path('m 0 0 V 40')"},
-  {at: 1, is: "path('m 0 0 V 60')"},
-  {at: 1.4, is: "path('m 0 0 V 80')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 v 10')",
-  to: "path('m 0 0 v 60')"
-}, [
-  {at: -0.4, is: "path('m 0 0 v -10')"},
-  {at: 0, is: "path('m 0 0 v 10')"},
-  {at: 0.2, is: "path('m 0 0 v 20')"},
-  {at: 0.6, is: "path('m 0 0 v 40')"},
-  {at: 1, is: "path('m 0 0 v 60')"},
-  {at: 1.4, is: "path('m 0 0 v 80')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 S 32 42 52 62')",
-  to: "path('m 0 0 S 37 47 57 67')"
-}, [
-  {at: -0.4, is: "path('m 0 0 S 30 40 50 60')"},
-  {at: 0, is: "path('m 0 0 S 32 42 52 62')"},
-  {at: 0.2, is: "path('m 0 0 S 33 43 53 63')"},
-  {at: 0.6, is: "path('m 0 0 S 35 45 55 65')"},
-  {at: 1, is: "path('m 0 0 S 37 47 57 67')"},
-  {at: 1.4, is: "path('m 0 0 S 39 49 59 69')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 s 32 42 52 62')",
-  to: "path('m 0 0 s 37 47 57 67')"
-}, [
-  {at: -0.4, is: "path('m 0 0 s 30 40 50 60')"},
-  {at: 0, is: "path('m 0 0 s 32 42 52 62')"},
-  {at: 0.2, is: "path('m 0 0 s 33 43 53 63')"},
-  {at: 0.6, is: "path('m 0 0 s 35 45 55 65')"},
-  {at: 1, is: "path('m 0 0 s 37 47 57 67')"},
-  {at: 1.4, is: "path('m 0 0 s 39 49 59 69')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 T 20 50')",
-  to: "path('m 0 0 T 30 70')"
-}, [
-  {at: -0.4, is: "path('m 0 0 T 16 42')"},
-  {at: 0, is: "path('m 0 0 T 20 50')"},
-  {at: 0.2, is: "path('m 0 0 T 22 54')"},
-  {at: 0.6, is: "path('m 0 0 T 26 62')"},
-  {at: 1, is: "path('m 0 0 T 30 70')"},
-  {at: 1.4, is: "path('m 0 0 T 34 78')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 0 0 t 20 50')",
-  to: "path('m 0 0 t 30 70')"
-}, [
-  {at: -0.4, is: "path('m 0 0 t 16 42')"},
-  {at: 0, is: "path('m 0 0 t 20 50')"},
-  {at: 0.2, is: "path('m 0 0 t 22 54')"},
-  {at: 0.6, is: "path('m 0 0 t 26 62')"},
-  {at: 1, is: "path('m 0 0 t 30 70')"},
-  {at: 1.4, is: "path('m 0 0 t 34 78')"},
-]);
-
-// Mix relative and non-relative
-assertInterpolation({
-  property: 'd',
-  from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')",
-  to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 200 100 z')"
-}, [
-  {at: -0.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 60 -180 Z')"},
-  {at: 0, is: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"},
-  {at: 0.2, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 120 -60 Z')"},
-  {at: 0.6, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 160 20 Z')"},
-  {at: 1, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 200 100 Z')"},
-  {at: 1.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 240 180 Z')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')",
-  to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')"
-}, [
-  {at: -0.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
-  {at: 0, is: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"},
-  {at: 0.2, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
-  {at: 0.6, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
-  {at: 1, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
-  {at: 1.4, is: "path('M 0 0 L 100 100 m 0 100 l 100 0 Z l 100 -100 Z')"},
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 l 20 30 z l 50 60 z m 70 80 l 90 60 z t 70 120')",
-  to: "path('M 110 120 L 130 150 Z L 80 110 Z M 100 140 L 190 200 Z T 210 220')"
-}, [
-  {at: -0.4, is: "path('M -30 -20 L -10 10 Z L 52 68 Z M 72 84 L 162 144 Z T 126 220')"},
-  {at: 0, is: "path('m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120')"},
-  {at: 0.2, is: "path('M 30 40 L 50 70 Z L 64 86 Z M 84 108 L 174 168 Z T 162 220')"},
-  {at: 0.6, is: "path('M 70 80 L 90 110 Z L 72 98 Z M 92 124 L 182 184 Z T 186 220')"},
-  {at: 1, is: "path('M 110 120 L 130 150 Z L 80 110 Z M 100 140 L 190 200 Z T 210 220')"},
-  {at: 1.4, is: "path('M 150 160 L 170 190 Z L 88 122 Z M 108 156 L 198 216 Z T 234 220')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 c 40 50 30 60 80 70 c 90 100 140 110 120 130')",
-  to: "path('M 110 120 C 140 150 130 160 180 170 C 290 300 340 310 320 330')"
-}, [
-  {at: -0.4, is: "path('M -30 -20 C 14 38 4 48 54 58 C 136 146 186 156 166 176')"},
-  {at: 0, is: "path('m 10 20 c 40 50 30 60 80 70 c 90 100 140 110 120 130')"},
-  {at: 0.2, is: "path('M 30 40 C 68 86 58 96 108 106 C 202 212 252 222 232 242')"},
-  {at: 0.6, is: "path('M 70 80 C 104 118 94 128 144 138 C 246 256 296 266 276 286')"},
-  {at: 1, is: "path('M 110 120 C 140 150 130 160 180 170 C 290 300 340 310 320 330')"},
-  {at: 1.4, is: "path('M 150 160 C 176 182 166 192 216 202 C 334 344 384 354 364 374')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 q 30 60 40 50 q 100 70 90 80')",
-  to: "path('M 110 120 Q 130 160 140 150 Q 200 170 190 180')"
-}, [
-  {at: -0.4, is: "path('M -30 -20 Q 4 48 14 38 Q 130 128 120 138')"},
-  {at: 0, is: "path('m 10 20 q 30 60 40 50 q 100 70 90 80')"},
-  {at: 0.2, is: "path('M 30 40 Q 58 96 68 86 Q 160 146 150 156')"},
-  {at: 0.6, is: "path('M 70 80 Q 94 128 104 118 Q 180 158 170 168')"},
-  {at: 1, is: "path('M 110 120 Q 130 160 140 150 Q 200 170 190 180')"},
-  {at: 1.4, is: "path('M 150 160 Q 166 192 176 182 Q 220 182 210 192')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 s 30 60 40 50 s 100 70 90 80')",
-  to: "path('M 110 120 S 130 160 140 150 S 200 170 190 180')"
-}, [
-  {at: -0.4, is: "path('M -30 -20 S 4 48 14 38 S 130 128 120 138')"},
-  {at: 0, is: "path('m 10 20 s 30 60 40 50 s 100 70 90 80')"},
-  {at: 0.2, is: "path('M 30 40 S 58 96 68 86 S 160 146 150 156')"},
-  {at: 0.6, is: "path('M 70 80 S 94 128 104 118 S 180 158 170 168')"},
-  {at: 1, is: "path('M 110 120 S 130 160 140 150 S 200 170 190 180')"},
-  {at: 1.4, is: "path('M 150 160 S 166 192 176 182 S 220 182 210 192')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 h 30 v 40 h 50 v 60 l 70 80')",
-  to: "path('M 110 120 H 130 V 140 H 250 V 260 L 270 280')"
-}, [
-  {at: -0.4, is: "path('M -30 -20 H 4 V 28 H 26 V 64 L 116 168')"},
-  {at: 0, is: "path('m 10 20 h 30 v 40 h 50 v 60 l 70 80')"},
-  {at: 0.2, is: "path('M 30 40 H 58 V 76 H 122 V 148 L 182 216')"},
-  {at: 0.6, is: "path('M 70 80 H 94 V 108 H 186 V 204 L 226 248')"},
-  {at: 1, is: "path('M 110 120 H 130 V 140 H 250 V 260 L 270 280')"},
-  {at: 1.4, is: "path('M 150 160 H 166 V 172 H 314 V 316 L 314 312')"}
-]);
-
-assertInterpolation({
-  property: 'd',
-  from: "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')",
-  to: "path('M 20 30 A 60 70 80 0 1 90 100 A 160 170 80 0 1 90 100')"
-}, [
-  {at: -0.4, is: "path('M 6 16 A -10 0 10 1 0 34 58 A 90 100 10 1 1 230 128')"},
-  {at: 0, is: "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')"},
-  {at: 0.2, is: "path('M 12 22 A 20 30 40 1 0 58 76 A 120 130 40 1 1 170 116')"},
-  {at: 0.6, is: "path('M 16 26 A 40 50 60 0 1 74 88 A 140 150 60 0 1 130 108')"},
-  {at: 1, is: "path('M 20 30 A 60 70 80 0 1 90 100 A 160 170 80 0 1 90 100')"},
-  {at: 1.4, is: "path('M 24 34 A 80 90 100 0 1 106 112 A 180 190 100 0 1 50 92')"}
-]);
-
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement11-expected.txt b/third_party/WebKit/LayoutTests/dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement11-expected.txt
index bca6e824..babd5dc 100644
--- a/third_party/WebKit/LayoutTests/dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement11-expected.txt
+++ b/third_party/WebKit/LayoutTests/dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement11-expected.txt
@@ -1,3 +1,3 @@
 Test	http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLIFrameElement11
 Status	failure
-Message	titleLink: assertEquals failed, actual , expected NIST DOM HTML Test - FRAME.
+Message	titleLink: assertEquals failed, actual Error, expected NIST DOM HTML Test - FRAME.
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 9834275..e30b32b 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -101442,11 +101442,6 @@
      {}
     ]
    ],
-   "html/browsers/the-window-object/named-access-on-the-window-object/named-objects-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/browsers/the-window-object/named-access-on-the-window-object/test.html": [
     [
      {}
@@ -250853,11 +250848,11 @@
    "testharness"
   ],
   "fetch/api/cors/cors-expose-star-expected.txt": [
-   "e2ca241fe7f57022576a5c4c4a2995c461db8e0a",
+   "4f7b7f72a370de56e276aa349bf677990ed7622e",
    "support"
   ],
   "fetch/api/cors/cors-expose-star-worker-expected.txt": [
-   "e2ca241fe7f57022576a5c4c4a2995c461db8e0a",
+   "4f7b7f72a370de56e276aa349bf677990ed7622e",
    "support"
   ],
   "fetch/api/cors/cors-expose-star-worker.html": [
@@ -250869,7 +250864,7 @@
    "testharness"
   ],
   "fetch/api/cors/cors-expose-star.js": [
-   "393131f216961ca07a225d61a5b51726d8b02c51",
+   "2403a7d229377d03230f32383e71960e32a84271",
    "support"
   ],
   "fetch/api/cors/cors-filtering-worker.html": [
@@ -250933,15 +250928,15 @@
    "testharness"
   ],
   "fetch/api/cors/cors-preflight-star.any-expected.txt": [
-   "a0dcb141e285235fbb20aafb0d2f9aeec4f7bfa5",
+   "d527ea318ff61b387ab4b6d26701edb399eaba8d",
    "support"
   ],
   "fetch/api/cors/cors-preflight-star.any.js": [
-   "5516bbb914b5d2a847d800d5c0f49a6da23b88e7",
+   "fd336bff06ef9d08b9a728592c9e7bf0c43496db",
    "testharness"
   ],
   "fetch/api/cors/cors-preflight-star.any.worker-expected.txt": [
-   "a0dcb141e285235fbb20aafb0d2f9aeec4f7bfa5",
+   "d527ea318ff61b387ab4b6d26701edb399eaba8d",
    "support"
   ],
   "fetch/api/cors/cors-preflight-status.any.js": [
@@ -254468,12 +254463,8 @@
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
-  "html/browsers/the-window-object/named-access-on-the-window-object/named-objects-expected.txt": [
-   "4e32463c271e2fb8080f9ca30c46ce09076bb0f8",
-   "support"
-  ],
   "html/browsers/the-window-object/named-access-on-the-window-object/named-objects.html": [
-   "37377d2ed04e32f8c2ada3143fa0d2d8f70c0ad6",
+   "8738c9e53e1c71b6b15ea0c3f2f0f9b0e4522144",
    "testharness"
   ],
   "html/browsers/the-window-object/named-access-on-the-window-object/test.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star.js b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star.js
index 90a9351d1..e37ddb4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-expose-star.js
@@ -4,7 +4,7 @@
 }
 
 const url = "http://{{host}}:{{ports[http][1]}}" + dirname(location.pathname) + RESOURCES_DIR + "top.txt",
-      sharedHeaders = "?pipe=header(Access-Control-Expose-Headers,*)|header(Test,X)|header(Set-Cookie,X)|"
+      sharedHeaders = "?pipe=header(Access-Control-Expose-Headers,*)|header(Test,X)|header(Set-Cookie,X)|header(*,whoa)|"
 
 promise_test(() => {
   const headers = "header(Access-Control-Allow-Origin,*)"
@@ -13,6 +13,7 @@
     assert_equals(resp.type , "cors")
     assert_equals(resp.headers.get("test"), "X")
     assert_equals(resp.headers.get("set-cookie"), null)
+    assert_equals(resp.headers.get("*"), "whoa")
   })
 }, "Basic Access-Control-Expose-Headers: * support")
 
@@ -25,7 +26,19 @@
     assert_equals(resp.headers.get("content-type"), "text/plain") // safelisted
     assert_equals(resp.headers.get("test"), null)
     assert_equals(resp.headers.get("set-cookie"), null)
+    assert_equals(resp.headers.get("*"), "whoa")
   })
-}, "Cannot use * for credentialed fetches")
+}, "* for credentialed fetches only matches literally")
+
+promise_test(() => {
+  const headers =  "header(Access-Control-Allow-Origin,*)|header(Access-Control-Expose-Headers,set-cookie)"
+  return fetch(url + sharedHeaders + headers).then(resp => {
+    assert_equals(resp.status, 200)
+    assert_equals(resp.type , "cors")
+    assert_equals(resp.headers.get("test"), "X")
+    assert_equals(resp.headers.get("set-cookie"), null)
+    assert_equals(resp.headers.get("*"), "whoa")
+  })
+}, "* can be one of several values")
 
 done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.js b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.js
index 213d805..8a18b51 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.js
@@ -16,7 +16,7 @@
     if (useMethod) {
       requestInit.method = useMethod
     }
-    if (useHeader) {
+    if (useHeader.length > 0) {
       requestInit.headers = [useHeader]
     }
     testURL += "allow_methods=" + allowMethod + "&"
@@ -36,7 +36,9 @@
 preflightTest(true, false, "*", "x-test", "SUPER", ["X-Test", "1"])
 preflightTest(true, false, "*", "*", "OK", ["X-Test", "1"])
 preflightTest(false, true, "*", "*", "OK", ["X-Test", "1"])
-preflightTest(false, true, "*", "", "PUT", undefined)
-preflightTest(false, true, "put", "*", "PUT", undefined)
+preflightTest(false, true, "*", "", "PUT", [])
+preflightTest(true, true, "PUT", "*", "PUT", [])
+preflightTest(false, true, "put", "*", "PUT", [])
 preflightTest(false, true, "get", "*", "GET", ["X-Test", "1"])
 preflightTest(false, true, "*", "*", "GET", ["X-Test", "1"])
+preflightTest(true, true, "*", "*", "*", ["*", "1"])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects-expected.txt
deleted file mode 100644
index be1d776..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-PASS Check if the first nested browsing context is returned by window['c']
-FAIL Check if window['a'] contains all embed, form, img, and object elements, and their order assert_equals: The length should be 5. expected 5 but got 4
-PASS Check that window['fs'] does not return the frameset element with name='fs' (historical)
-PASS Check if window['b'] returns the elements with the id='b'
-PASS Check if window['d'] returns the element with id='d'
-PASS Check widow[''] when there are some elements with empty id or name attribute
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects.html
index bd3a7b6d..d5b1789d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/named-objects.html
@@ -32,7 +32,6 @@
 }, "Check if the first nested browsing context is returned by window['c']");
 
 test(function() {
-  assert_equals(window['a'].length, 5, "The length should be 5.");
   assert_true(window['a'] instanceof HTMLCollection);
   assert_array_equals(window['a'],
                       [ document.getElementById('embed1'),
diff --git a/third_party/WebKit/LayoutTests/fast/events/focusingUnloadedFrame-expected.txt b/third_party/WebKit/LayoutTests/fast/events/focusingUnloadedFrame-expected.txt
index 2ae8b18..5f6ce261 100644
--- a/third_party/WebKit/LayoutTests/fast/events/focusingUnloadedFrame-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/events/focusingUnloadedFrame-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: '<!--framePath //<!--frame1-->-->'
 --------
-
+Could not load the requested resource.
+Error code: -6 (net::ERR_FILE_NOT_FOUND)
diff --git a/third_party/WebKit/LayoutTests/fast/events/onloadFrameCrash-expected.txt b/third_party/WebKit/LayoutTests/fast/events/onloadFrameCrash-expected.txt
index fd6f97229..593c9df 100644
--- a/third_party/WebKit/LayoutTests/fast/events/onloadFrameCrash-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/events/onloadFrameCrash-expected.txt
@@ -3,4 +3,5 @@
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
 --------
-
+ErrorCould not load the requested resource.
+Error code: -6 (net::ERR_FILE_NOT_FOUND)
diff --git a/third_party/WebKit/LayoutTests/fast/loader/recursive-before-unload-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/loader/recursive-before-unload-crash-expected.txt
index dd739d0..2aa33a11 100644
--- a/third_party/WebKit/LayoutTests/fast/loader/recursive-before-unload-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/loader/recursive-before-unload-crash-expected.txt
@@ -1,3 +1,4 @@
 CONSOLE ERROR: Blocked alert('onbeforeunload called, and iframe hasn't been added yet.') during beforeunload.
 ALERT: Adding iframe
-
+Could not load the requested resource.
+Error code: -102 (net::ERR_CONNECTION_REFUSED)
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
index dec83d0..0e3eb93 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
@@ -5,6 +5,7 @@
 frame "f1" - didFailProvisionalLoadWithError
 frame "f1" - didStartProvisionalLoadForFrame
 frame "f1" - didCommitLoadForFrame
+frame "f1" - didReceiveTitle: Error
 frame "f1" - didFinishDocumentLoadForFrame
 frame "f1" - didHandleOnloadEventsForFrame
 frame "f1" - didFinishLoadForFrame
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href-expected.txt
index 58149f3..3afa3ff4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-head-base-href.pl?enable-full-block=1&q=%3Cbase%20href=%27http://localhost:8000/security/xssAuditor/resources/base-href/%27%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href.html
index f313d79..e088a13 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-base-href.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-head-base-href.pl?enable-full-block=1&q=<base href='http://localhost:8000/security/xssAuditor/resources/base-href/'>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-get-from-iframe-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-get-from-iframe-expected.txt
index 036b465..968dd1c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-get-from-iframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-get-from-iframe-expected.txt
@@ -4,4 +4,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url-expected.txt
index c374da9f..70bb2c9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Ciframe%20src=javascript:alert(document.domain)%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url.html
index 00163e7..5948aaf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-iframe-javascript-url.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src='http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Ciframe%20src=javascript:alert(document.domain)%3E'>
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link-expected.txt
index 3f91acc..fbb67be 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 14: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag-click-and-notify.pl?enable-full-block=1&elmid=anchorLink&q=%3Ca+id%3DanchorLink+href%3Djavascript%3Aalert%280%29%3Etest%3C/a%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link.html
index c6b52f9..6c5f827 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-javascript-link.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src='http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag-click-and-notify.pl?enable-full-block=1&elmid=anchorLink&q=%3Ca+id%3DanchorLink+href%3Djavascript%3Aalert%280%29%3Etest%3C/a%3E'>
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick-expected.txt
index 5e848137..9d92a4c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Ca%20onclick=%27alert(String.fromCharCode(0x58,0x53,0x53))%27%3EClick%3C/a%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick.html
index 24727ca..4ae96f9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-link-onclick.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=<a%20onclick='alert(String.fromCharCode(0x58,0x53,0x53))'>Click</a>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag-expected.txt
index f655c67..4d1ae2c9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cobject%20name=%27plugin%27%20type=%27application/x-blink-test-plugin%27%3E%3Cparam%20name=%27movie%27%20value=%27http://localhost:8000/security/xssAuditor/resources/dummy.swf%27%20/%3E%3C/object%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag.html
index 16e9ff3d..2378e51a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-object-tag.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=<object name='plugin' type='application/x-blink-test-plugin'><param name='movie' value='http://localhost:8000/security/xssAuditor/resources/dummy.swf' /></object>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-post-from-iframe-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-post-from-iframe-expected.txt
index a09c5ab..4889a8a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-post-from-iframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-post-from-iframe-expected.txt
@@ -4,4 +4,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain-expected.txt
index 448ccf3..6b0a89e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain-expected.txt
@@ -1,11 +1,12 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 19: PASS: Cross-origin access threw: 'SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame.'.
 ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E'
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain.html
index 61eecee3..506ead8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-cross-domain.html
@@ -14,7 +14,7 @@
 {
     try {
         var ref = document.getElementById("frame").contentDocument.referrer;
-        console.log('FAIL: Referrer is "' + ref + '"'); 
+        console.log('FAIL: Referrer is "' + ref + '"');
     } catch (e) {
         console.log('PASS: Cross-origin access threw: \'' + e.toString() + '\'.');
     }
@@ -23,7 +23,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkframe()" src="http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-expected.txt
index 268f3ca..a60d4ae 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-expected.txt
@@ -1,11 +1,12 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 19: FAIL: same-origin access threw: 'SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame.'.
 ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E'
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source-expected.txt
index 36322a1..2b2462d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source-expected.txt
@@ -1,10 +1,11 @@
 CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=%3Cscript%20src=%27http://localhost:8000/security/xssAuditor/resources/xss.js%27%3E%3C/script%3E' because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
 CONSOLE MESSAGE: line 31: PASS: "frame" is cross-origin.
-There should be no content in the iframe below:
+The loading of iframe below should be blocked:
 
 
 
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source.html
index 928fa7af..76a9c4f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag-with-source.html
@@ -12,7 +12,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkFrameIsCrossOriginAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=<script src='http://localhost:8000/security/xssAuditor/resources/xss.js'></script>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag.html
index e2c3f70..ea5313fd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/full-block-script-tag.html
@@ -23,7 +23,7 @@
 </script>
 </head>
 <body>
-<p>There should be no content in the iframe below:</p>
+<p>The loading of iframe below should be blocked:</p>
 <iframe id="frame" name="frame" onload="checkframe()" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?enable-full-block=1&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script>">
 </iframe>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt
index 021acb6..c8659d2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-2-expected.txt
index 6d9ac86..b4b20c7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-2-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-3-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-3-expected.txt
index 86afcc6..be6e426a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-3-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-3-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-4-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-4-expected.txt
index 6de0d20..722b3cd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-4-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-4-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-5-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-5-expected.txt
index 7fd339be..e48736d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-5-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-5-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-6-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-6-expected.txt
index d1652d4a..8f08085 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-6-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-6-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-7-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-7-expected.txt
index 5e5231b..8f428ec 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-7-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-7-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-8-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-8-expected.txt
index 9ab0865a..0f904656 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-8-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-8-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-9-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-9-expected.txt
index cf362cc..68c4e2c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-9-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-9-expected.txt
@@ -8,4 +8,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-01-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-01-expected.txt
index a09c5ab..4889a8a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-01-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-01-expected.txt
@@ -4,4 +4,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-03-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-03-expected.txt
index 733ab4c..6e8e305 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-03-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-03-expected.txt
@@ -7,4 +7,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-04-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-04-expected.txt
index 5e4fdbd..f482cb2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-04-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/xss-protection-parsing-04-expected.txt
@@ -7,4 +7,5 @@
 --------
 Frame: 'frame'
 --------
-
+Could not load the requested resource.
+Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
diff --git a/third_party/WebKit/LayoutTests/media/controls/closed-captions-single-track.html b/third_party/WebKit/LayoutTests/media/controls/closed-captions-single-track.html
index 4c58267..554c76fb 100644
--- a/third_party/WebKit/LayoutTests/media/controls/closed-captions-single-track.html
+++ b/third_party/WebKit/LayoutTests/media/controls/closed-captions-single-track.html
@@ -36,6 +36,7 @@
 
       // Captions track should become visible after the closed caption button is pressed.
       checkCaptionsVisible(video, captions);
+      checkButtonHasClass(toggleClosedCaptionsButton(video), "visible");
 
       // Click the closed captions button again and make sure the menu does not appear.
       clickCaptionButton(video);
@@ -43,6 +44,7 @@
 
       // Captions track should become invisible after the closed caption button is pressed.
       checkCaptionsHidden(video);
+      checkButtonNotHasClass(toggleClosedCaptionsButton(video), "visible");
     }));
   });
 
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-cast.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-cast.html
new file mode 100644
index 0000000..ee37a61
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-cast.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>Test that player state is reflected in CSS classes on the cast button.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<script src="../media-file.js"></script>
+<video controls width=400></video>
+<script>
+async_test(t => {
+  var video = document.querySelector('video');
+
+  video.onloadedmetadata = t.step_func_done(function() {
+    // Pretend we have a cast device.
+    internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true);
+    checkButtonNotHasClass(castButton(video), 'on');
+
+    // Pretend we are casting.
+    internals.mediaPlayerPlayingRemotelyChanged(video, true);
+    checkButtonHasClass(castButton(video), 'on');
+  });
+
+  video.src = findMediaFile("video", "../content/counting");
+  video.play();
+});
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-fullscreen.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-fullscreen.html
new file mode 100644
index 0000000..ea43064
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-fullscreen.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<title>Test that player state is reflected in CSS classes on the fullscreen button.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<script src="../media-file.js"></script>
+<video controls width=400></video>
+<script>
+async_test(t => {
+  var video = document.querySelector('video');
+
+  video.onwebkitfullscreenchange = t.step_func_done(_ => {
+    checkButtonHasClass(fullscreenButton(video), 'fullscreen');
+  });
+
+  document.onclick = t.step_func(_ => {
+    fullscreenButton(video).click();
+  });
+
+  video.onplay = t.step_func(_ => {
+    checkButtonNotHasClass(fullscreenButton(video), 'fullscreen');
+    clickAtCoordinates(1, 1);
+  });
+
+  video.src = findMediaFile("video", "../content/counting");
+  video.play();
+});
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-mute.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-mute.html
new file mode 100644
index 0000000..368e445
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-mute.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<title>Test that player state is reflected in CSS classes on the mute button.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<script src="../media-file.js"></script>
+<video controls width=400></video>
+<script>
+async_test(t => {
+  var video = document.querySelector('video');
+  checkButtonNotHasClass(muteButton(video), 'muted');
+
+  t.step_func(_ => {
+    video.muted = true;
+
+    setTimeout(t.step_func_done(_ => {
+      checkButtonHasClass(muteButton(video), 'muted');
+    }));
+  })();
+});
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-overlay-cast.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-overlay-cast.html
new file mode 100644
index 0000000..4cebf33
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-overlay-cast.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>Test that player state is reflected in CSS classes on the overlay cast button.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<script src="../media-file.js"></script>
+<video controls width=400></video>
+<script>
+async_test(t => {
+  var video = document.querySelector('video');
+
+  video.onloadedmetadata = t.step_func_done(function() {
+    // Pretend we have a cast device.
+    internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true);
+    checkButtonNotHasClass(overlayCastButton(video), 'on');
+
+    // Pretend we are casting.
+    internals.mediaPlayerPlayingRemotelyChanged(video, true);
+    checkButtonHasClass(overlayCastButton(video), 'on');
+  });
+
+  video.src = findMediaFile("video", "../content/counting");
+  video.play();
+});
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-pause.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-pause.html
new file mode 100644
index 0000000..903f2ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-pause.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<title>Test that player state is reflected in CSS classes on the play button.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<script src="../media-file.js"></script>
+<video controls width=400></video>
+<script>
+async_test(t => {
+  var video = document.querySelector('video');
+
+  video.onplay = t.step_func(_ => {
+    checkButtonNotHasClass(playButton(video), 'pause');
+    video.pause();
+  });
+
+  video.src = findMediaFile("video", "../content/counting");
+  video.play().catch(t.step_func_done(_ => {
+    checkButtonHasClass(playButton(video), 'pause');
+  }));
+});
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/media/media-controls.js b/third_party/WebKit/LayoutTests/media/media-controls.js
index 2752348..bceaa77 100644
--- a/third_party/WebKit/LayoutTests/media/media-controls.js
+++ b/third_party/WebKit/LayoutTests/media/media-controls.js
@@ -154,6 +154,18 @@
     return false;
 }
 
+function toggleClosedCaptionsButton(videoElement) {
+    return mediaControlsButton(videoElement, 'toggle-closed-captions-button');
+}
+
+function playButton(videoElement) {
+    return mediaControlsButton(videoElement, 'play-button');
+}
+
+function muteButton(videoElement) {
+    return mediaControlsButton(videoElement, 'mute-button');
+}
+
 function clickAtCoordinates(x, y)
 {
     eventSender.mouseMoveTo(x, y);
@@ -241,3 +253,11 @@
     return computedStyle.display !== "none" &&
            computedStyle.visibility === "visible";
 }
+
+function checkButtonHasClass(button, className) {
+  assert_true(button.classList.contains(className));
+}
+
+function checkButtonNotHasClass(button, className) {
+  assert_false(button.classList.contains(className));
+}
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt
similarity index 67%
copy from third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt
copy to third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt
index fde2ac0..8213b6e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt
@@ -4,14 +4,7 @@
       "name": "LayoutView #document",
       "bounds": [800, 600],
       "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow BODY",
-          "rect": [8, 8, 784, 530],
-          "reason": "geometry"
-        }
-      ]
+      "backgroundColor": "#FFFFFF"
     },
     {
       "name": "LayoutVideo VIDEO id='v'",
@@ -41,27 +34,27 @@
       "bounds": [700, 525],
       "paintInvalidations": [
         {
+          "object": "LayoutBlockFlow (positioned) DIV class='-internal-track-segment-highlight-before'",
+          "rect": [580, 508, 70, 2],
+          "reason": "disappeared"
+        },
+        {
           "object": "LayoutFlexibleBox DIV",
           "rect": [580, 508, 70, 2],
           "reason": "geometry"
         },
         {
-          "object": "LayoutSlider INPUT",
-          "rect": [580, 508, 70, 2],
+          "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
+          "rect": [632, 491, 36, 36],
           "reason": "full"
         },
         {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [632, 485, 36, 48],
+          "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
+          "rect": [562, 491, 36, 36],
           "reason": "full"
         },
         {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [562, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutButton INPUT",
+          "object": "LayoutButton INPUT class='muted'",
           "rect": [530, 493, 32, 32],
           "reason": "full"
         }
@@ -70,14 +63,6 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutBlockFlow BODY",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
       "object": "LayoutVideo VIDEO id='v'",
       "reason": "style change"
     },
@@ -86,11 +71,7 @@
       "reason": "geometry"
     },
     {
-      "object": "LayoutButton INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSlider INPUT",
+      "object": "LayoutButton INPUT class='muted'",
       "reason": "full"
     },
     {
@@ -98,8 +79,12 @@
       "reason": "geometry"
     },
     {
-      "object": "LayoutBlockFlow DIV id='thumb'",
+      "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
       "reason": "full"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='-internal-track-segment-highlight-before'",
+      "reason": "disappeared"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt
similarity index 68%
rename from third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt
rename to third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt
index fde2ac0..21276223 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-mute-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt
@@ -4,14 +4,7 @@
       "name": "LayoutView #document",
       "bounds": [800, 600],
       "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow BODY",
-          "rect": [8, 8, 784, 530],
-          "reason": "geometry"
-        }
-      ]
+      "backgroundColor": "#FFFFFF"
     },
     {
       "name": "LayoutVideo VIDEO id='v'",
@@ -46,19 +39,19 @@
           "reason": "geometry"
         },
         {
-          "object": "LayoutSlider INPUT",
-          "rect": [580, 508, 70, 2],
+          "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
+          "rect": [597, 491, 36, 36],
           "reason": "full"
         },
         {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [632, 485, 36, 48],
+          "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
+          "rect": [562, 491, 36, 36],
           "reason": "full"
         },
         {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [562, 485, 36, 48],
-          "reason": "full"
+          "object": "LayoutBlockFlow (positioned) DIV class='-internal-track-segment-highlight-before'",
+          "rect": [580, 508, 35, 2],
+          "reason": "appeared"
         },
         {
           "object": "LayoutButton INPUT",
@@ -70,14 +63,6 @@
   ],
   "objectPaintInvalidations": [
     {
-      "object": "LayoutBlockFlow BODY",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
       "object": "LayoutVideo VIDEO id='v'",
       "reason": "style change"
     },
@@ -90,16 +75,16 @@
       "reason": "full"
     },
     {
-      "object": "LayoutSlider INPUT",
-      "reason": "full"
-    },
-    {
       "object": "LayoutFlexibleBox DIV",
       "reason": "geometry"
     },
     {
-      "object": "LayoutBlockFlow DIV id='thumb'",
+      "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
       "reason": "full"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='-internal-track-segment-highlight-before'",
+      "reason": "appeared"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/video/video-controls-layer-creation-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/video/video-controls-layer-creation-expected.png
index 2af8702..e0a1f07c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/compositing/video/video-controls-layer-creation-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/video/video-controls-layer-creation-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index ca0e28f..6558104 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index b202525..b9b0e5f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -24,11 +24,27 @@
           text run at (0,8) width 30: "/ 0:07"
     LayoutSlider {INPUT} at (108,15) size 49x2
       LayoutFlexibleBox {DIV} at (0,0) size 49x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 85x48
-          LayoutBlockFlow {DIV} at (49,0) size 36x48
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (98,142) size 85x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 85x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 49x2 [bgcolor=#DADADA]
+layer at (215,142) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 49x2 [bgcolor=#4285F4]
+layer at (165,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (48.50,0) size 0.48x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (147,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (49,-18) size 36x36
+layer at (240,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png
index 6f1b9b4..3ce85890 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt
index 57e32b07..3c8b94af7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,52) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,260) size 320x32 scrollHeight 40
+layer at (8,260) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,260) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,276) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,276) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,297) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,297) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,505) size 320x32 scrollHeight 40
+layer at (8,505) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,505) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,521) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,521) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,542) size 320x240
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,542) size 320x198 backgroundClip at (8,542) size 320x58 clip at (8,542) size 320x58
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,750) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,766) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,766) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.png
index fe0d905f..f6b4218e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.txt
index 583daaa3..3441439c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/media/media-document-audio-repaint-expected.txt
@@ -23,7 +23,7 @@
         LayoutBlockFlow {DIV} at (0,-31) size 300x32
     layer at (40,124) size 300x0
       LayoutFlexibleBox (relative positioned) {DIV} at (0,-41) size 300x0
-    layer at (40,134) size 300x32 scrollHeight 40
+    layer at (40,134) size 300x32 scrollHeight 34
       LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
         LayoutButton {INPUT} at (0,0) size 32x32
         LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -36,10 +36,26 @@
               text run at (0,8) width 30: "/ 0:01"
         LayoutSlider {INPUT} at (108,15) size 81x2
           LayoutFlexibleBox {DIV} at (0,0) size 81x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 117x48
-              LayoutBlockFlow {DIV} at (40.48,0) size 36x48
         LayoutButton {INPUT} at (207,0) size 32x32
         LayoutSlider {INPUT} at (257,15) size 25x2
           LayoutFlexibleBox {DIV} at (0,0) size 25x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-              LayoutBlockFlow {DIV} at (25,0) size 36x48
+    layer at (130,150) size 117x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 117x0
+    layer at (148,149) size 81x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 81x2 [bgcolor=#DADADA]
+    layer at (279,150) size 61x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+    layer at (148,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 39.69x2 [bgcolor=#4285F4]
+    layer at (188,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (39.69,0) size 40.50x2 [bgcolor=#5A5A5A]
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+    layer at (297,149) size 0x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+    layer at (170,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (40.48,-18) size 36x36
+    layer at (304,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-1-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-1-expected.png
new file mode 100644
index 0000000..1c1d2c6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-2-expected.png
index 42593bb..01c17c7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-2-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug137388-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
index e541818..74218e8f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
@@ -5,7 +5,7 @@
 
 EVENT(webkitfullscreenchange)
 Should report another rect which is not on the document
-handler: DIV (56, -8, 712, 48)
+handler: no rects
 
 END OF TEST
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png
index abfb363..f9afb5f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-iframe-expected.png
new file mode 100644
index 0000000..05d935d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-iframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png
index abfb363..f9afb5f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png
index abfb363..f9afb5f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index ca0e28f..5bbf3efa 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index b202525..e6485af 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -22,13 +22,29 @@
       LayoutBlockFlow (anonymous) at (4,0) size 30x32
         LayoutText {#text} at (0,8) size 30x15
           text run at (0,8) width 30: "/ 0:07"
-    LayoutSlider {INPUT} at (108,15) size 49x2
-      LayoutFlexibleBox {DIV} at (0,0) size 49x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 85x48
-          LayoutBlockFlow {DIV} at (49,0) size 36x48
+    LayoutSlider {INPUT} at (114,15) size 37x2
+      LayoutFlexibleBox {DIV} at (0,0) size 37x2
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
-      LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
+      LayoutFlexibleBox {DIV} at (6,0) size 13x2
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (104,142) size 73x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 73x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (12,-1) size 49x2 [bgcolor=#DADADA]
+layer at (221,142) size 49x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 49x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (12,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 49x2 [bgcolor=#4285F4]
+layer at (165,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (48.50,0) size 0.48x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (141,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (37,-18) size 36x36
+layer at (234,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (13,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
index 6f1b9b4..3ce85890 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
index 57e32b07..3c8b94af7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,52) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,260) size 320x32 scrollHeight 40
+layer at (8,260) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,260) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,276) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,276) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,297) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,297) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,505) size 320x32 scrollHeight 40
+layer at (8,505) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,505) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,521) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,521) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,542) size 320x240
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,542) size 320x198 backgroundClip at (8,542) size 320x58 clip at (8,542) size 320x58
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,750) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,766) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,766) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-zoom-controls-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-zoom-controls-expected.png
index f4549b6b..d144fd2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-zoom-controls-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-zoom-controls-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-zoom-controls-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-zoom-controls-expected.png
index f4549b6b..d144fd2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-zoom-controls-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-zoom-controls-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/video/video-controls-layer-creation-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/video/video-controls-layer-creation-expected.png
index 5f347be9..f7da7d4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/video/video-controls-layer-creation-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/video/video-controls-layer-creation-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index bb528ee..1064fbb7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index 5ca85b6..34ba009 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -24,11 +24,27 @@
           text run at (0,9) width 31: "/ 0:07"
     LayoutSlider {INPUT} at (108.05,15) size 48.95x2
       LayoutFlexibleBox {DIV} at (0,0) size 48.95x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 84.95x48
-          LayoutBlockFlow {DIV} at (48.95,0) size 36x48
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (98,142) size 85x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 84.95x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 48.95x2 [bgcolor=#DADADA]
+layer at (215,142) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 48.95x2 [bgcolor=#4285F4]
+layer at (163,141) size 2x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (46.98,0) size 1.95x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (147,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (48.95,-18) size 36x36
+layer at (240,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.png
index 68a1145d..ca1b998 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.txt
index 657f77fa..bf4ef43 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,50) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,258) size 320x32 scrollHeight 40
+layer at (8,258) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,258) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,274) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,273) size 72x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,274) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,273) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,273) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,273) size 72x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,273) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,273) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,256) size 36x36 backgroundClip at (8,258) size 320x32 clip at (8,258) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,256) size 36x36 backgroundClip at (8,258) size 320x32 clip at (8,258) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,294) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,294) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,502) size 320x32 scrollHeight 40
+layer at (8,502) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,502) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,518) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,517) size 72x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,518) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,517) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,517) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,517) size 72x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,517) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,517) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,500) size 36x36 backgroundClip at (8,502) size 320x32 clip at (8,502) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,500) size 36x36 backgroundClip at (8,502) size 320x32 clip at (8,502) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,538) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,538) size 320x240
 layer at (8,538) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,538) size 320x198 backgroundClip at (8,538) size 320x62 clip at (8,538) size 320x62
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,746) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,746) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,746) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,762) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,761) size 72x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,762) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,761) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,761) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,761) size 72x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,761) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,761) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,744) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,744) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-dark-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-dark-rendering-expected.png
index 65da69a..0e8c2bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-dark-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-dark-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-light-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-light-rendering-expected.png
index 23d7968..360ea7a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-light-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/video-overlay-cast-light-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.png
index 92cee9c..4b71d29 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.txt
index e9d56e2f..38126ca2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/media-document-audio-repaint-expected.txt
@@ -23,7 +23,7 @@
         LayoutBlockFlow {DIV} at (0,-31) size 300x32
     layer at (40,124) size 300x0
       LayoutFlexibleBox (relative positioned) {DIV} at (0,-41) size 300x0
-    layer at (40,134) size 300x32 scrollHeight 40
+    layer at (40,134) size 300x32 scrollHeight 34
       LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
         LayoutButton {INPUT} at (0,0) size 32x32
         LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -36,10 +36,26 @@
               text run at (0,9) width 31: "/ 0:01"
         LayoutSlider {INPUT} at (108.05,15) size 80.95x2
           LayoutFlexibleBox {DIV} at (0,0) size 80.95x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 116.95x48
-              LayoutBlockFlow {DIV} at (40.47,0) size 36x48
         LayoutButton {INPUT} at (207,0) size 32x32
         LayoutSlider {INPUT} at (257,15) size 25x2
           LayoutFlexibleBox {DIV} at (0,0) size 25x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-              LayoutBlockFlow {DIV} at (25,0) size 36x48
+    layer at (130,150) size 117x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 116.95x0
+    layer at (148,149) size 81x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 80.95x2 [bgcolor=#DADADA]
+    layer at (279,150) size 61x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+    layer at (148,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 39.66x2 [bgcolor=#4285F4]
+    layer at (188,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (39.66,0) size 40.47x2 [bgcolor=#5A5A5A]
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+    layer at (297,149) size 0x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+    layer at (171,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (40.47,-18) size 36x36
+    layer at (304,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-mute-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-mute-repaint-expected.txt
deleted file mode 100644
index e1da66c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-mute-repaint-expected.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow BODY",
-          "rect": [8, 8, 784, 529],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "LayoutVideo VIDEO id='v'",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "drawsContent": false
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutFlexibleBox (relative positioned) DIV",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox (relative positioned) DIV",
-          "rect": [0, 0, 700, 525],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutFlexibleBox (relative positioned) DIV)",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox DIV",
-          "rect": [580, 508, 70, 2],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutSlider INPUT",
-          "rect": [580, 508, 70, 2],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [632, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [562, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutButton INPUT",
-          "rect": [530, 493, 32, 32],
-          "reason": "full"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutBlockFlow BODY",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutVideo VIDEO id='v'",
-      "reason": "style change"
-    },
-    {
-      "object": "LayoutFlexibleBox (relative positioned) DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutButton INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSlider INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutFlexibleBox DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='thumb'",
-      "reason": "full"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-unmute-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-unmute-repaint-expected.txt
deleted file mode 100644
index 2298d2f..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/video-unmute-repaint-expected.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow (anonymous)",
-          "rect": [8, 8, 784, 529],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "LayoutVideo VIDEO id='v'",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "drawsContent": false
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutFlexibleBox (relative positioned) DIV",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox (relative positioned) DIV",
-          "rect": [0, 0, 700, 525],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutFlexibleBox (relative positioned) DIV)",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox DIV",
-          "rect": [580, 508, 70, 2],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutSlider INPUT",
-          "rect": [580, 508, 70, 2],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [597, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [562, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutButton INPUT",
-          "rect": [530, 493, 32, 32],
-          "reason": "full"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutBlockFlow (anonymous)",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutVideo VIDEO id='v'",
-      "reason": "style change"
-    },
-    {
-      "object": "LayoutFlexibleBox (relative positioned) DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutButton INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSlider INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutFlexibleBox DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='thumb'",
-      "reason": "full"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-1-expected.png
new file mode 100644
index 0000000..c278cfb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-2-expected.png
index b0b3ca97..a678e3b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-2-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug137388-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index bb528ee..1064fbb7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index 5ca85b6..fe3d357 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -24,11 +24,27 @@
           text run at (0,9) width 31: "/ 0:07"
     LayoutSlider {INPUT} at (108.05,15) size 48.95x2
       LayoutFlexibleBox {DIV} at (0,0) size 48.95x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 84.95x48
-          LayoutBlockFlow {DIV} at (48.95,0) size 36x48
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (98,142) size 85x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 84.95x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 48.95x2 [bgcolor=#DADADA]
+layer at (215,142) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 48.95x2 [bgcolor=#4285F4]
+layer at (164,141) size 2x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (47.48,0) size 1.45x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (147,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (48.95,-18) size 36x36
+layer at (240,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
index 68a1145d..ca1b998 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
index 657f77fa..bf4ef43 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,50) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,258) size 320x32 scrollHeight 40
+layer at (8,258) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,258) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,274) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,273) size 72x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,274) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,273) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,273) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,273) size 72x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,273) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,273) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,256) size 36x36 backgroundClip at (8,258) size 320x32 clip at (8,258) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,256) size 36x36 backgroundClip at (8,258) size 320x32 clip at (8,258) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,294) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,294) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,502) size 320x32 scrollHeight 40
+layer at (8,502) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,502) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,518) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,517) size 72x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,518) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,517) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,517) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,517) size 72x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,517) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,517) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,500) size 36x36 backgroundClip at (8,502) size 320x32 clip at (8,502) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,500) size 36x36 backgroundClip at (8,502) size 320x32 clip at (8,502) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,538) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,538) size 320x240
 layer at (8,538) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,538) size 320x198 backgroundClip at (8,538) size 320x62 clip at (8,538) size 320x62
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,746) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,746) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 23.36x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,9) width 24: "0:00"
     LayoutSlider {INPUT} at (73.36,15) size 71.64x2
       LayoutFlexibleBox {DIV} at (0,0) size 71.64x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107.64x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,746) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (63,762) size 108x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107.64x0
+layer at (81,761) size 72x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71.64x2 [bgcolor=#DADADA]
+layer at (203,762) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,761) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (81,761) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (81,761) size 72x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71.64x2 [bgcolor=#5A5A5A]
+layer at (221,761) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,761) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (63,744) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,744) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-dark-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-dark-rendering-expected.png
index 65da69a..0e8c2bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-dark-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-dark-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-light-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-light-rendering-expected.png
index 23d7968..360ea7a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-light-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/video-overlay-cast-light-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
index a164d574..46c8763 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-expose-star-worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL Basic Access-Control-Expose-Headers: * support assert_equals: expected (string) "X" but got (object) null
-PASS Cannot use * for credentialed fetches
+PASS * for credentialed fetches only matches literally
+FAIL * can be one of several values assert_equals: expected (string) "X" but got (object) null
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index 810d32db..b60014a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -3,9 +3,11 @@
 FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
-PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: )
-PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
+PASS CORS that succeeds with credentials: true; method: PUT (allowed: PUT); header:  (allowed: *)
+PASS CORS that fails with credentials: true; method: PUT (allowed: put); header:  (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: get); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: GET (allowed: *); header: X-Test,1 (allowed: *)
+PASS CORS that succeeds with credentials: true; method: * (allowed: *); header: *,1 (allowed: *)
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index 6ad8a86..7c9ef09 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index b202525..af258bc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -24,11 +24,27 @@
           text run at (0,8) width 30: "/ 0:07"
     LayoutSlider {INPUT} at (108,15) size 49x2
       LayoutFlexibleBox {DIV} at (0,0) size 49x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 85x48
-          LayoutBlockFlow {DIV} at (49,0) size 36x48
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (98,142) size 85x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 85x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 49x2 [bgcolor=#DADADA]
+layer at (215,142) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 49x2 [bgcolor=#4285F4]
+layer at (163,141) size 2x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (47.03,0) size 1.95x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (147,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (49,-18) size 36x36
+layer at (240,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.png
index d2f382e..5ba393f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.txt
index f443612f..7085bc7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,52) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,260) size 320x32 scrollHeight 40
+layer at (8,260) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,260) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,276) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,276) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,297) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,297) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,505) size 320x32 scrollHeight 40
+layer at (8,505) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,505) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,521) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,521) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,542) size 320x240
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,542) size 320x198 backgroundClip at (8,542) size 320x58 clip at (8,542) size 320x58
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,750) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,766) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,766) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.png
index 1b193a5..e723f9c2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.txt
index a779023..848fc39 100644
--- a/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/media/media-document-audio-repaint-expected.txt
@@ -23,7 +23,7 @@
         LayoutBlockFlow {DIV} at (0,-31) size 300x32
     layer at (40,124) size 300x0
       LayoutFlexibleBox (relative positioned) {DIV} at (0,-41) size 300x0
-    layer at (40,134) size 300x32 scrollHeight 40
+    layer at (40,134) size 300x32 scrollHeight 34
       LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
         LayoutButton {INPUT} at (0,0) size 32x32
         LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -36,10 +36,26 @@
               text run at (0,8) width 30: "/ 0:01"
         LayoutSlider {INPUT} at (108,15) size 81x2
           LayoutFlexibleBox {DIV} at (0,0) size 81x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 117x48
-              LayoutBlockFlow {DIV} at (40.48,0) size 36x48
         LayoutButton {INPUT} at (207,0) size 32x32
         LayoutSlider {INPUT} at (257,15) size 25x2
           LayoutFlexibleBox {DIV} at (0,0) size 25x2
-            LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-              LayoutBlockFlow {DIV} at (25,0) size 36x48
+    layer at (130,150) size 117x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 117x0
+    layer at (148,149) size 81x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 81x2 [bgcolor=#DADADA]
+    layer at (279,150) size 61x0
+      LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+    layer at (148,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 39.69x2 [bgcolor=#4285F4]
+    layer at (188,149) size 40x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (39.69,0) size 40.50x2 [bgcolor=#5A5A5A]
+    layer at (297,149) size 25x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+    layer at (297,149) size 0x2
+      LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+    layer at (170,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (40.48,-18) size 36x36
+    layer at (304,132) size 36x36 backgroundClip at (40,134) size 300x32 clip at (40,134) size 300x32
+      LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-unmute-repaint-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-unmute-repaint-expected.txt
deleted file mode 100644
index 10eb59f..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/video-unmute-repaint-expected.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow (anonymous)",
-          "rect": [8, 8, 784, 530],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "LayoutVideo VIDEO id='v'",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "drawsContent": false
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutFlexibleBox (relative positioned) DIV",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox (relative positioned) DIV",
-          "rect": [0, 0, 700, 525],
-          "reason": "geometry"
-        }
-      ]
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutFlexibleBox (relative positioned) DIV)",
-      "position": [8, 8],
-      "bounds": [700, 525],
-      "paintInvalidations": [
-        {
-          "object": "LayoutFlexibleBox DIV",
-          "rect": [580, 508, 70, 2],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutSlider INPUT",
-          "rect": [580, 508, 70, 2],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [597, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='thumb'",
-          "rect": [562, 485, 36, 48],
-          "reason": "full"
-        },
-        {
-          "object": "LayoutButton INPUT",
-          "rect": [530, 493, 32, 32],
-          "reason": "full"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutBlockFlow (anonymous)",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutVideo VIDEO id='v'",
-      "reason": "style change"
-    },
-    {
-      "object": "LayoutFlexibleBox (relative positioned) DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutButton INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSlider INPUT",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutFlexibleBox DIV",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='thumb'",
-      "reason": "full"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-1-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-1-expected.png
new file mode 100644
index 0000000..ddfe36a4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-2-expected.png
index e644dd8..198f0b57 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-2-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug137388-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
index 6ad8a86..7c9ef09 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
index b202525..b9b0e5f7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,118) size 300x32
 layer at (8,8) size 300x108
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x108
-layer at (8,126) size 300x32 scrollHeight 40
+layer at (8,126) size 300x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 300x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -24,11 +24,27 @@
           text run at (0,8) width 30: "/ 0:07"
     LayoutSlider {INPUT} at (108,15) size 49x2
       LayoutFlexibleBox {DIV} at (0,0) size 49x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 85x48
-          LayoutBlockFlow {DIV} at (49,0) size 36x48
     LayoutButton {INPUT} at (175,0) size 32x32
     LayoutSlider {INPUT} at (225,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (268,0) size 32x32
+layer at (98,142) size 85x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 85x0
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 49x2 [bgcolor=#DADADA]
+layer at (215,142) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (116,141) size 49x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 49x2 [bgcolor=#4285F4]
+layer at (165,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (48.50,0) size 0.48x2 [bgcolor=#5A5A5A]
+layer at (233,141) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (233,141) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (147,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (49,-18) size 36x36
+layer at (240,124) size 36x36 backgroundClip at (8,126) size 300x32 clip at (8,126) size 300x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
index d2f382e..5ba393f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
index f443612f..7085bc7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -20,7 +20,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,52) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,260) size 320x32 scrollHeight 40
+layer at (8,260) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -29,22 +29,38 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,260) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,276) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,276) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,275) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,275) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,275) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,258) size 36x36 backgroundClip at (8,260) size 320x32 clip at (8,260) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,297) size 320x240
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,297) size 320x198
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,505) size 320x32 scrollHeight 40
+layer at (8,505) size 320x32 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -53,16 +69,32 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,505) size 32x32
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,521) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,521) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,520) size 71x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,520) size 25x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,520) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,503) size 36x36 backgroundClip at (8,505) size 320x32 clip at (8,505) size 320x32
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutVideo (positioned) {VIDEO} at (8,542) size 320x240
 layer at (8,542) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
@@ -70,7 +102,7 @@
     LayoutBlockFlow {DIV} at (0,208) size 320x32
 layer at (8,542) size 320x198 backgroundClip at (8,542) size 320x58 clip at (8,542) size 320x58
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198
-layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 40
+layer at (8,750) size 320x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 34
   LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x32 [bgcolor=#FAFAFA]
     LayoutButton {INPUT} at (0,0) size 32x32
     LayoutFlexibleBox {DIV} at (32,0) size 24x32 [color=#5A5A5A]
@@ -79,13 +111,29 @@
           text run at (0,8) width 24: "0:00"
     LayoutSlider {INPUT} at (74,15) size 71x2
       LayoutFlexibleBox {DIV} at (0,0) size 71x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 107x48
-          LayoutBlockFlow {DIV} at (0,0) size 36x48
     LayoutButton {INPUT} at (163,0) size 32x32
     LayoutSlider {INPUT} at (213,15) size 25x2
       LayoutFlexibleBox {DIV} at (0,0) size 25x2
-        LayoutBlockFlow {DIV} at (-18,-23) size 61x48
-          LayoutBlockFlow {DIV} at (25,0) size 36x48
     LayoutButton {INPUT} at (288,0) size 32x32
 layer at (264,750) size 32x32 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
   LayoutButton {INPUT} at (256,0) size 32x32
+layer at (64,766) size 107x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 107x0
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 71x2 [bgcolor=#DADADA]
+layer at (203,766) size 61x0
+  LayoutBlockFlow (relative positioned) {DIV} at (-18,1) size 61x0
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (18,-1) size 25x2 [bgcolor=#DADADA]
+layer at (82,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#4285F4]
+layer at (82,765) size 71x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 71x2 [bgcolor=#5A5A5A]
+layer at (221,765) size 25x2 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 25x2 [bgcolor=#4285F4]
+layer at (221,765) size 0x2
+  LayoutBlockFlow (positioned) zI: 1 {DIV} at (0,0) size 0x2 [bgcolor=#5A5A5A]
+layer at (64,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (0,-18) size 36x36
+layer at (228,748) size 36x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutBlockFlow (positioned) zI: 2 {DIV} at (25,-18) size 36x36
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
new file mode 100644
index 0000000..6ad8a86
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug137388-1-expected.png b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug137388-1-expected.png
deleted file mode 100644
index 6e0c002c..0000000
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug137388-1-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/Source/core/css/parser/CSSTokenizerTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSTokenizerTest.cpp
index a8c3b13..54c49ac 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSTokenizerTest.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSTokenizerTest.cpp
@@ -103,7 +103,7 @@
   return CSSParserToken(kDelimiterToken, c);
 }
 
-static CSSParserToken UnicodeRange(UChar32 start, UChar32 end) {
+static CSSParserToken UnicodeRng(UChar32 start, UChar32 end) {
   return CSSParserToken(kUnicodeRangeToken, start, end);
 }
 
@@ -420,27 +420,27 @@
 }
 
 TEST(CSSTokenizerTest, UnicodeRangeToken) {
-  TEST_TOKENS("u+012345-123456", UnicodeRange(0x012345, 0x123456));
-  TEST_TOKENS("U+1234-2345", UnicodeRange(0x1234, 0x2345));
-  TEST_TOKENS("u+222-111", UnicodeRange(0x222, 0x111));
-  TEST_TOKENS("U+CafE-d00D", UnicodeRange(0xcafe, 0xd00d));
-  TEST_TOKENS("U+2??", UnicodeRange(0x200, 0x2ff));
-  TEST_TOKENS("U+ab12??", UnicodeRange(0xab1200, 0xab12ff));
-  TEST_TOKENS("u+??????", UnicodeRange(0x000000, 0xffffff));
-  TEST_TOKENS("u+??", UnicodeRange(0x00, 0xff));
+  TEST_TOKENS("u+012345-123456", UnicodeRng(0x012345, 0x123456));
+  TEST_TOKENS("U+1234-2345", UnicodeRng(0x1234, 0x2345));
+  TEST_TOKENS("u+222-111", UnicodeRng(0x222, 0x111));
+  TEST_TOKENS("U+CafE-d00D", UnicodeRng(0xcafe, 0xd00d));
+  TEST_TOKENS("U+2??", UnicodeRng(0x200, 0x2ff));
+  TEST_TOKENS("U+ab12??", UnicodeRng(0xab1200, 0xab12ff));
+  TEST_TOKENS("u+??????", UnicodeRng(0x000000, 0xffffff));
+  TEST_TOKENS("u+??", UnicodeRng(0x00, 0xff));
 
-  TEST_TOKENS("u+222+111", UnicodeRange(0x222, 0x222),
+  TEST_TOKENS("u+222+111", UnicodeRng(0x222, 0x222),
               Number(kIntegerValueType, 111, kPlusSign));
-  TEST_TOKENS("u+12345678", UnicodeRange(0x123456, 0x123456),
+  TEST_TOKENS("u+12345678", UnicodeRng(0x123456, 0x123456),
               Number(kIntegerValueType, 78, kNoSign));
-  TEST_TOKENS("u+123-12345678", UnicodeRange(0x123, 0x123456),
+  TEST_TOKENS("u+123-12345678", UnicodeRng(0x123, 0x123456),
               Number(kIntegerValueType, 78, kNoSign));
-  TEST_TOKENS("u+cake", UnicodeRange(0xca, 0xca), Ident("ke"));
-  TEST_TOKENS("u+1234-gggg", UnicodeRange(0x1234, 0x1234), Ident("-gggg"));
-  TEST_TOKENS("U+ab12???", UnicodeRange(0xab1200, 0xab12ff), Delim('?'));
-  TEST_TOKENS("u+a1?-123", UnicodeRange(0xa10, 0xa1f),
+  TEST_TOKENS("u+cake", UnicodeRng(0xca, 0xca), Ident("ke"));
+  TEST_TOKENS("u+1234-gggg", UnicodeRng(0x1234, 0x1234), Ident("-gggg"));
+  TEST_TOKENS("U+ab12???", UnicodeRng(0xab1200, 0xab12ff), Delim('?'));
+  TEST_TOKENS("u+a1?-123", UnicodeRng(0xa10, 0xa1f),
               Number(kIntegerValueType, -123, kMinusSign));
-  TEST_TOKENS("u+1??4", UnicodeRange(0x100, 0x1ff),
+  TEST_TOKENS("u+1??4", UnicodeRng(0x100, 0x1ff),
               Number(kIntegerValueType, 4, kNoSign));
   TEST_TOKENS("u+z", Ident("u"), Delim('+'), Ident("z"));
   TEST_TOKENS("u+", Ident("u"), Delim('+'));
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn
index 83b0296..2a267f86 100644
--- a/third_party/WebKit/Source/core/dom/BUILD.gn
+++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -267,6 +267,7 @@
     "TagCollection.h",
     "TaskRunnerHelper.cpp",
     "TaskRunnerHelper.h",
+    "TaskTypeTraits.h",
     "TemplateContentDocumentFragment.h",
     "Text.cpp",
     "Text.h",
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.cpp b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
index 87ff924c..01f2fe3 100644
--- a/third_party/WebKit/Source/core/dom/ModuleScript.cpp
+++ b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
@@ -248,7 +248,7 @@
 DEFINE_TRACE_WRAPPERS(ModuleScript) {
   // TODO(mlippautz): Support TraceWrappers(const
   // TraceWrapperV8Reference<v8::Module>&) to remove the cast.
-  visitor->TraceWrappers(record_.Cast<v8::Value>());
+  visitor->TraceWrappers(record_.UnsafeCast<v8::Value>());
   visitor->TraceWrappers(preinstantiation_error_);
 }
 
diff --git a/third_party/WebKit/Source/core/dom/TaskRunnerHelper.h b/third_party/WebKit/Source/core/dom/TaskRunnerHelper.h
index adb11ca..9ec3de3 100644
--- a/third_party/WebKit/Source/core/dom/TaskRunnerHelper.h
+++ b/third_party/WebKit/Source/core/dom/TaskRunnerHelper.h
@@ -8,6 +8,7 @@
 #include "core/CoreExport.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/HashTraits.h"
+#include "public/platform/TaskType.h"
 
 namespace blink {
 
@@ -19,126 +20,6 @@
 class WorkerOrWorkletGlobalScope;
 class WorkerThread;
 
-enum class TaskType : unsigned {
-  // Speced tasks and related internal tasks should be posted to one of
-  // the following task runners. These task runners may be throttled.
-
-  // https://html.spec.whatwg.org/multipage/webappapis.html#generic-task-sources
-  //
-  // This task source is used for features that react to DOM manipulations, such
-  // as things that happen in a non-blocking fashion when an element is inserted
-  // into the document.
-  kDOMManipulation,
-  // This task source is used for features that react to user interaction, for
-  // example keyboard or mouse input. Events sent in response to user input
-  // (e.g. click events) must be fired using tasks queued with the user
-  // interaction task source.
-  kUserInteraction,
-  // This task source is used for features that trigger in response to network
-  // activity.
-  kNetworking,
-  // This task source is used for control messages between kNetworking tasks.
-  kNetworkingControl,
-  // This task source is used to queue calls to history.back() and similar APIs.
-  kHistoryTraversal,
-
-  // https://html.spec.whatwg.org/multipage/embedded-content.html#the-embed-element
-  // This task source is used for the embed element setup steps.
-  kEmbed,
-
-  // https://html.spec.whatwg.org/multipage/embedded-content.html#media-elements
-  // This task source is used for all tasks queued in the [Media elements]
-  // section and subsections of the spec unless explicitly specified otherwise.
-  kMediaElementEvent,
-
-  // https://html.spec.whatwg.org/multipage/scripting.html#the-canvas-element
-  // This task source is used to invoke the result callback of
-  // HTMLCanvasElement.toBlob().
-  kCanvasBlobSerialization,
-
-  // https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
-  // This task source is used when an algorithm requires a microtask to be
-  // queued.
-  kMicrotask,
-
-  // https://html.spec.whatwg.org/multipage/webappapis.html#timers
-  // This task source is used to queue tasks queued by setInterval() and similar
-  // APIs.
-  kTimer,
-
-  // https://html.spec.whatwg.org/multipage/comms.html#sse-processing-model
-  // This task source is used for any tasks that are queued by EventSource
-  // objects.
-  kRemoteEvent,
-
-  // https://html.spec.whatwg.org/multipage/comms.html#feedback-from-the-protocol
-  // The task source for all tasks queued in the [WebSocket] section of the
-  // spec.
-  kWebSocket,
-
-  // https://html.spec.whatwg.org/multipage/comms.html#web-messaging
-  // This task source is used for the tasks in cross-document messaging.
-  kPostedMessage,
-
-  // https://html.spec.whatwg.org/multipage/comms.html#message-ports
-  kUnshippedPortMessage,
-
-  // https://www.w3.org/TR/FileAPI/#blobreader-task-source
-  // This task source is used for all tasks queued in the FileAPI spec to read
-  // byte sequences associated with Blob and File objects.
-  kFileReading,
-
-  // https://www.w3.org/TR/IndexedDB/#request-api
-  kDatabaseAccess,
-
-  // https://w3c.github.io/presentation-api/#common-idioms
-  // This task source is used for all tasks in the Presentation API spec.
-  kPresentation,
-
-  // https://www.w3.org/TR/2016/WD-generic-sensor-20160830/#sensor-task-source
-  // This task source is used for all tasks in the Sensor API spec.
-  kSensor,
-
-  // https://w3c.github.io/performance-timeline/#performance-timeline
-  kPerformanceTimeline,
-
-  // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
-  // This task source is used for all tasks in the WebGL spec.
-  kWebGL,
-
-  // Use MiscPlatformAPI for a task that is defined in the spec but is not yet
-  // associated with any specific task runner in the spec. MiscPlatformAPI is
-  // not encouraged for stable and matured APIs. The spec should define the task
-  // runner explicitly.
-  // The task runner may be throttled.
-  kMiscPlatformAPI,
-
-  // Other internal tasks that cannot fit any of the above task runners
-  // can be posted here, but the usage is not encouraged. The task runner
-  // may be throttled.
-  //
-  // UnspecedLoading type should be used for all tasks associated with
-  // loading page content, UnspecedTimer should be used for all other purposes.
-  kUnspecedTimer,
-  kUnspecedLoading,
-
-  // Tasks that must not be throttled should be posted here, but the usage
-  // should be very limited.
-  kUnthrottled,
-};
-
-// HashTraits for TaskType.
-struct TaskTypeTraits : WTF::GenericHashTraits<TaskType> {
-  static const bool kEmptyValueIsZero = false;
-  static TaskType EmptyValue() { return static_cast<TaskType>(-1); }
-  static void ConstructDeletedValue(TaskType& slot, bool) {
-    slot = static_cast<TaskType>(-2);
-  }
-  static bool IsDeletedValue(TaskType value) {
-    return value == static_cast<TaskType>(-2);
-  }
-};
-
 // A set of helper functions to get a WebTaskRunner for TaskType and a context
 // object. The posted tasks are guaranteed to run in a sequence if they have the
 // same TaskType and the context objects belong to the same frame.
diff --git a/third_party/WebKit/Source/core/dom/TaskTypeTraits.h b/third_party/WebKit/Source/core/dom/TaskTypeTraits.h
new file mode 100644
index 0000000..5ed1697d
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/TaskTypeTraits.h
@@ -0,0 +1,28 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TaskTypeTraits_h
+#define TaskTypeTraits_h
+
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/HashTraits.h"
+#include "public/platform/TaskType.h"
+
+namespace blink {
+
+// HashTraits for TaskType.
+struct TaskTypeTraits : WTF::GenericHashTraits<TaskType> {
+  static const bool kEmptyValueIsZero = false;
+  static TaskType EmptyValue() { return static_cast<TaskType>(-1); }
+  static void ConstructDeletedValue(TaskType& slot, bool) {
+    slot = static_cast<TaskType>(-2);
+  }
+  static bool IsDeletedValue(TaskType value) {
+    return value == static_cast<TaskType>(-2);
+  }
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index c5f50394..3f2b03a9 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -828,9 +828,6 @@
     return WebInputEventResult::kHandledSystem;
   }
 
-  // Mouse events simulated from touch should not hit-test again.
-  DCHECK(!mouse_event.FromTouch());
-
   HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kMove;
   if (mouse_event_manager_->MousePressed()) {
     hit_type |= HitTestRequest::kActive;
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
index 28d98bb..aff11351 100644
--- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -31,6 +31,7 @@
 #include "core/loader/WorkerThreadableLoader.h"
 
 #include <memory>
+#include "core/dom/TaskRunnerHelper.h"
 #include "core/loader/DocumentThreadableLoader.h"
 #include "core/loader/ThreadableLoadingContext.h"
 #include "core/timing/WorkerGlobalScopePerformance.h"
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
index 350f6c8..f7a9f2f 100644
--- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
+++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
@@ -5,6 +5,7 @@
 #include "core/workers/ParentFrameTaskRunners.h"
 
 #include "core/dom/Document.h"
+#include "core/dom/TaskRunnerHelper.h"
 #include "core/frame/LocalFrame.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/ThreadingPrimitives.h"
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
index 398a8403..21abf96 100644
--- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
+++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
-#include "core/dom/TaskRunnerHelper.h"
+#include "core/dom/TaskTypeTraits.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Noncopyable.h"
diff --git a/third_party/WebKit/Source/modules/media_controls/BUILD.gn b/third_party/WebKit/Source/modules/media_controls/BUILD.gn
index e023686..5cece65 100644
--- a/third_party/WebKit/Source/modules/media_controls/BUILD.gn
+++ b/third_party/WebKit/Source/modules/media_controls/BUILD.gn
@@ -54,6 +54,8 @@
     "elements/MediaControlPlayButtonElement.h",
     "elements/MediaControlRemainingTimeDisplayElement.cpp",
     "elements/MediaControlRemainingTimeDisplayElement.h",
+    "elements/MediaControlSliderElement.cpp",
+    "elements/MediaControlSliderElement.h",
     "elements/MediaControlTextTrackListElement.cpp",
     "elements/MediaControlTextTrackListElement.h",
     "elements/MediaControlTimeDisplayElement.cpp",
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
index 7520a96..496d7a5 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -1204,6 +1204,13 @@
   // source or no longer have a source.
   download_button_->SetIsWanted(
       download_button_->ShouldDisplayDownloadButton());
+
+  if (MediaElement().getNetworkState() != HTMLMediaElement::kNetworkEmpty &&
+      MediaElement().getNetworkState() != HTMLMediaElement::kNetworkNoSource) {
+    setAttribute("class", "");
+  } else {
+    setAttribute("class", "not-loaded");
+  }
 }
 
 bool MediaControlsImpl::OverflowMenuVisible() {
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImplTest.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImplTest.cpp
index bfbef21a..4f8a6f4 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImplTest.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImplTest.cpp
@@ -713,36 +713,6 @@
   EXPECT_EQ(duration / 2, current_time_display->CurrentValue());
 }
 
-TEST_F(MediaControlsImplTest, VolumeSliderPaintInvalidationOnInput) {
-  EnsureSizing();
-
-  Element* volume_slider = VolumeSliderElement();
-
-  MockLayoutObject layout_object(volume_slider);
-  LayoutObject* prev_layout_object = volume_slider->GetLayoutObject();
-  volume_slider->SetLayoutObject(&layout_object);
-
-  layout_object.ClearPaintInvalidationFlags();
-  EXPECT_FALSE(layout_object.ShouldDoFullPaintInvalidation());
-  Event* event = Event::Create(EventTypeNames::input);
-  volume_slider->DefaultEventHandler(event);
-  EXPECT_TRUE(layout_object.ShouldDoFullPaintInvalidation());
-
-  layout_object.ClearPaintInvalidationFlags();
-  EXPECT_FALSE(layout_object.ShouldDoFullPaintInvalidation());
-  event = Event::Create(EventTypeNames::input);
-  volume_slider->DefaultEventHandler(event);
-  EXPECT_TRUE(layout_object.ShouldDoFullPaintInvalidation());
-
-  layout_object.ClearPaintInvalidationFlags();
-  EXPECT_FALSE(layout_object.ShouldDoFullPaintInvalidation());
-  event = Event::Create(EventTypeNames::input);
-  volume_slider->DefaultEventHandler(event);
-  EXPECT_TRUE(layout_object.ShouldDoFullPaintInvalidation());
-
-  volume_slider->SetLayoutObject(prev_layout_object);
-}
-
 TEST_F(MediaControlsImplTest, TimelineMetricsWidth) {
   MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
   testing::RunPendingTasks();
@@ -859,7 +829,7 @@
   MouseUpAt(trackTwoThirds);
 
   EXPECT_LE(0.66 * duration, MediaControls().MediaElement().currentTime());
-  EXPECT_GE(0.68 * duration, MediaControls().MediaElement().currentTime());
+  EXPECT_GE(0.70 * duration, MediaControls().MediaElement().currentTime());
 
   GetHistogramTester().ExpectUniqueSample("Media.Timeline.SeekType." TIMELINE_W,
                                           2 /* SeekType::kDragFromElsewhere */,
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp
index 59ab136..36567a5 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp
@@ -68,6 +68,7 @@
     }
   }
   UpdateOverflowString();
+  SetClass("on", IsPlayingRemotely());
 }
 
 bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() {
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlFullscreenButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlFullscreenButtonElement.cpp
index 8cc17ed..9d2f95e 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlFullscreenButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlFullscreenButtonElement.cpp
@@ -26,6 +26,7 @@
 void MediaControlFullscreenButtonElement::SetIsFullscreen(bool is_fullscreen) {
   SetDisplayType(is_fullscreen ? kMediaExitFullscreenButton
                                : kMediaEnterFullscreenButton);
+  SetClass("fullscreen", is_fullscreen);
 }
 
 bool MediaControlFullscreenButtonElement::WillRespondToMouseClickEvents() {
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
index 299006a..18b052c 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
@@ -4,6 +4,7 @@
 
 #include "modules/media_controls/elements/MediaControlInputElement.h"
 
+#include "core/dom/DOMTokenList.h"
 #include "core/dom/events/Event.h"
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLMediaElement.h"
@@ -174,6 +175,14 @@
   ctr_histogram.Count(static_cast<int>(event));
 }
 
+void MediaControlInputElement::SetClass(const AtomicString& class_name,
+                                        bool should_have_class) {
+  if (should_have_class)
+    classList().Add(class_name);
+  else
+    classList().Remove(class_name);
+}
+
 DEFINE_TRACE(MediaControlInputElement) {
   HTMLInputElement::Trace(visitor);
   MediaControlElementBase::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h
index 9dca441..528035a3 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h
@@ -59,6 +59,9 @@
   // Returns whether this element is used for the overflow menu.
   bool IsOverflowElement() const;
 
+  // Sets/removes a CSS class from this element based on |should_have_class|.
+  void SetClass(const AtomicString& class_name, bool should_have_class);
+
  private:
   friend class MediaControlInputElementTest;
 
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlMuteButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlMuteButtonElement.cpp
index c12eaeb..d9890ec8 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlMuteButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlMuteButtonElement.cpp
@@ -28,9 +28,9 @@
   // TODO(mlamouri): checking for volume == 0 because the mute button will look
   // 'muted' when the volume is 0 even if the element is not muted. This allows
   // the painting and the display type to actually match.
-  SetDisplayType((MediaElement().muted() || MediaElement().volume() == 0)
-                     ? kMediaUnMuteButton
-                     : kMediaMuteButton);
+  bool muted = MediaElement().muted() || MediaElement().volume() == 0;
+  SetDisplayType(muted ? kMediaUnMuteButton : kMediaMuteButton);
+  SetClass("muted", muted);
   UpdateOverflowString();
 }
 
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPlayButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPlayButtonElement.cpp
index 6bd48224..fa96c1b 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPlayButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPlayButtonElement.cpp
@@ -28,6 +28,7 @@
 void MediaControlPlayButtonElement::UpdateDisplayType() {
   SetDisplayType(MediaElement().paused() ? kMediaPlayButton
                                          : kMediaPauseButton);
+  SetClass("pause", MediaElement().paused());
   UpdateOverflowString();
 }
 
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.cpp
new file mode 100644
index 0000000..118ccdc
--- /dev/null
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.cpp
@@ -0,0 +1,95 @@
+// 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 "modules/media_controls/elements/MediaControlSliderElement.h"
+
+#include "core/InputTypeNames.h"
+#include "core/dom/ElementShadow.h"
+#include "core/html/HTMLDivElement.h"
+#include "platform/wtf/text/StringBuilder.h"
+
+namespace {
+
+void SetSegmentDivPosition(blink::HTMLDivElement* segment,
+                           int left,
+                           int width) {
+  StringBuilder builder;
+  builder.Append("width: ");
+  builder.AppendNumber(width);
+  builder.Append("%; left: ");
+  builder.AppendNumber(left);
+  builder.Append("%;");
+  segment->setAttribute("style", builder.ToAtomicString());
+}
+
+}  // namespace.
+
+namespace blink {
+
+MediaControlSliderElement::MediaControlSliderElement(
+    MediaControlsImpl& media_controls,
+    MediaControlElementType display_type)
+    : MediaControlInputElement(media_controls, display_type),
+      segment_highlight_before_(nullptr),
+      segment_highlight_after_(nullptr) {
+  EnsureUserAgentShadowRoot();
+  setType(InputTypeNames::range);
+  setAttribute(HTMLNames::stepAttr, "any");
+}
+
+void MediaControlSliderElement::SetupBarSegments() {
+  DCHECK((segment_highlight_after_ && segment_highlight_before_) ||
+         (!segment_highlight_after_ && !segment_highlight_before_));
+
+  if (segment_highlight_after_ || segment_highlight_before_)
+    return;
+
+  // The timeline element has a shadow root with the following
+  // structure:
+  //
+  // #shadow-root
+  //   - div
+  //     - div::-webkit-slider-runnable-track#track
+  ShadowRoot& shadow_root = Shadow()->OldestShadowRoot();
+  Element* track = shadow_root.getElementById(AtomicString("track"));
+  DCHECK(track);
+  track->setAttribute("class", "-internal-media-controls-segmented-track");
+
+  // Add the following structure to #track.
+  //
+  // div.-internal-track-segment-background (container)
+  //   - div.-internal-track-segment-highlight-before (blue highlight)
+  //   - div.-internal-track-segment-highlight-after (dark gray highlight)
+  HTMLDivElement* background = HTMLDivElement::Create(GetDocument());
+  background->setAttribute("class", "-internal-track-segment-background");
+  track->appendChild(background);
+
+  segment_highlight_before_ = HTMLDivElement::Create(GetDocument());
+  segment_highlight_before_->setAttribute(
+      "class", "-internal-track-segment-highlight-before");
+  background->appendChild(segment_highlight_before_);
+
+  segment_highlight_after_ = HTMLDivElement::Create(GetDocument());
+  segment_highlight_after_->setAttribute(
+      "class", "-internal-track-segment-highlight-after");
+  background->appendChild(segment_highlight_after_);
+}
+
+void MediaControlSliderElement::SetBeforeSegmentPosition(int left, int width) {
+  DCHECK(segment_highlight_before_);
+  SetSegmentDivPosition(segment_highlight_before_, left, width);
+}
+
+void MediaControlSliderElement::SetAfterSegmentPosition(int left, int width) {
+  DCHECK(segment_highlight_after_);
+  SetSegmentDivPosition(segment_highlight_after_, left, width);
+}
+
+DEFINE_TRACE(MediaControlSliderElement) {
+  visitor->Trace(segment_highlight_before_);
+  visitor->Trace(segment_highlight_after_);
+  MediaControlInputElement::Trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h
new file mode 100644
index 0000000..d73f51d
--- /dev/null
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h
@@ -0,0 +1,37 @@
+// 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 MediaControlSliderElement_h
+#define MediaControlSliderElement_h
+
+#include "modules/ModulesExport.h"
+#include "modules/media_controls/elements/MediaControlInputElement.h"
+
+namespace blink {
+
+class MediaControlsImpl;
+
+// MediaControlInputElement with additional logic for sliders.
+class MODULES_EXPORT MediaControlSliderElement
+    : public MediaControlInputElement {
+  USING_GARBAGE_COLLECTED_MIXIN(MediaControlSliderElement);
+
+ public:
+  DECLARE_VIRTUAL_TRACE();
+
+ protected:
+  MediaControlSliderElement(MediaControlsImpl&, MediaControlElementType);
+
+  void SetupBarSegments();
+  void SetBeforeSegmentPosition(int left, int width);
+  void SetAfterSegmentPosition(int left, int width);
+
+ private:
+  Member<HTMLDivElement> segment_highlight_before_;
+  Member<HTMLDivElement> segment_highlight_after_;
+};
+
+}  // namespace blink
+
+#endif  // MediaControlSliderElement_h
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp
index dd3e7d7..7a4b43b 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp
@@ -5,7 +5,6 @@
 #include "modules/media_controls/elements/MediaControlTimelineElement.h"
 
 #include "core/HTMLNames.h"
-#include "core/InputTypeNames.h"
 #include "core/dom/events/Event.h"
 #include "core/events/KeyboardEvent.h"
 #include "core/events/PointerEvent.h"
@@ -19,14 +18,17 @@
 #include "public/platform/Platform.h"
 #include "public/platform/WebScreenInfo.h"
 
+namespace {
+
+const double kCurrentTimeBufferedDelta = 1.0;
+
+}  // namespace.
+
 namespace blink {
 
 MediaControlTimelineElement::MediaControlTimelineElement(
     MediaControlsImpl& media_controls)
-    : MediaControlInputElement(media_controls, kMediaSlider) {
-  EnsureUserAgentShadowRoot();
-  setType(InputTypeNames::range);
-  setAttribute(HTMLNames::stepAttr, "any");
+    : MediaControlSliderElement(media_controls, kMediaSlider) {
   SetShadowPseudoId(AtomicString("-webkit-media-controls-timeline"));
 }
 
@@ -36,17 +38,15 @@
 
 void MediaControlTimelineElement::SetPosition(double current_time) {
   setValue(String::Number(current_time));
-
-  if (LayoutObject* layout_object = this->GetLayoutObject())
-    layout_object->SetShouldDoFullPaintInvalidation();
+  current_time_ = current_time;
+  RenderBarSegments();
 }
 
 void MediaControlTimelineElement::SetDuration(double duration) {
   SetFloatingPointAttribute(HTMLNames::maxAttr,
                             std::isfinite(duration) ? duration : 0);
-
-  if (LayoutObject* layout_object = this->GetLayoutObject())
-    layout_object->SetShouldDoFullPaintInvalidation();
+  duration_ = duration;
+  RenderBarSegments();
 }
 
 void MediaControlTimelineElement::OnPlaying() {
@@ -136,4 +136,56 @@
   return 0;
 }
 
+void MediaControlTimelineElement::RenderBarSegments() {
+  SetupBarSegments();
+
+  // Draw the buffered range. Since the element may have multiple buffered
+  // ranges and it'd be distracting/'busy' to show all of them, show only the
+  // buffered range containing the current play head.
+  TimeRanges* buffered_time_ranges = MediaElement().buffered();
+  DCHECK(buffered_time_ranges);
+  if (std::isnan(duration_) || std::isinf(duration_) || !duration_ ||
+      std::isnan(current_time_)) {
+    SetBeforeSegmentPosition(0, 0);
+    SetAfterSegmentPosition(0, 0);
+    return;
+  }
+
+  int current_position = int((current_time_ / duration_) * 100);
+  for (unsigned i = 0; i < buffered_time_ranges->length(); ++i) {
+    float start = buffered_time_ranges->start(i, ASSERT_NO_EXCEPTION);
+    float end = buffered_time_ranges->end(i, ASSERT_NO_EXCEPTION);
+    // The delta is there to avoid corner cases when buffered
+    // ranges is out of sync with current time because of
+    // asynchronous media pipeline and current time caching in
+    // HTMLMediaElement.
+    // This is related to https://www.w3.org/Bugs/Public/show_bug.cgi?id=28125
+    // FIXME: Remove this workaround when WebMediaPlayer
+    // has an asynchronous pause interface.
+    if (std::isnan(start) || std::isnan(end) ||
+        start > current_time_ + kCurrentTimeBufferedDelta ||
+        end < current_time_) {
+      continue;
+    }
+
+    int start_position = int((start / duration_) * 100);
+    int end_position = int((end / duration_) * 100);
+
+    // Draw highlight before current time.
+    if (current_position > start_position)
+      SetBeforeSegmentPosition(start_position, current_position);
+
+    // Draw dark grey highlight after current time.
+    if (end_position > current_position) {
+      SetAfterSegmentPosition(current_position,
+                              end_position - current_position);
+    }
+    return;
+  }
+
+  // Reset the widths to hide the segments.
+  SetBeforeSegmentPosition(0, 0);
+  SetAfterSegmentPosition(0, 0);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h
index 2ad8a7ac..f05c823f 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h
@@ -5,7 +5,7 @@
 #ifndef MediaControlTimelineElement_h
 #define MediaControlTimelineElement_h
 
-#include "modules/media_controls/elements/MediaControlInputElement.h"
+#include "modules/media_controls/elements/MediaControlSliderElement.h"
 #include "modules/media_controls/elements/MediaControlTimelineMetrics.h"
 
 namespace blink {
@@ -13,7 +13,7 @@
 class Event;
 class MediaControlsImpl;
 
-class MediaControlTimelineElement final : public MediaControlInputElement {
+class MediaControlTimelineElement final : public MediaControlSliderElement {
  public:
   explicit MediaControlTimelineElement(MediaControlsImpl&);
 
@@ -40,7 +40,12 @@
   // simplicity; deliberately ignores pinch zoom's pageScaleFactor).
   int TimelineWidth();
 
+  void RenderBarSegments();
+
   MediaControlTimelineMetrics metrics_;
+
+  double current_time_;
+  double duration_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlToggleClosedCaptionsButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlToggleClosedCaptionsButtonElement.cpp
index 6d17362a..1a8b828 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlToggleClosedCaptionsButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlToggleClosedCaptionsButtonElement.cpp
@@ -31,6 +31,7 @@
   bool captions_visible = MediaElement().TextTracksVisible();
   SetDisplayType(captions_visible ? kMediaHideClosedCaptionsButton
                                   : kMediaShowClosedCaptionsButton);
+  SetClass("visible", captions_visible);
 }
 
 WebLocalizedString::Name
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.cpp
index 16956ff1..ecd583e8 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.cpp
@@ -5,7 +5,6 @@
 #include "modules/media_controls/elements/MediaControlVolumeSliderElement.h"
 
 #include "core/HTMLNames.h"
-#include "core/InputTypeNames.h"
 #include "core/dom/events/Event.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/layout/LayoutObject.h"
@@ -17,12 +16,10 @@
 
 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(
     MediaControlsImpl& media_controls)
-    : MediaControlInputElement(media_controls, kMediaVolumeSlider) {
-  EnsureUserAgentShadowRoot();
-  setType(InputTypeNames::range);
-  setAttribute(HTMLNames::stepAttr, "any");
+    : MediaControlSliderElement(media_controls, kMediaVolumeSlider) {
   setAttribute(HTMLNames::maxAttr, "1");
   SetShadowPseudoId(AtomicString("-webkit-media-controls-volume-slider"));
+  SetVolumeInternal(MediaElement().volume());
 }
 
 void MediaControlVolumeSliderElement::SetVolume(double volume) {
@@ -30,8 +27,7 @@
     return;
 
   setValue(String::Number(volume));
-  if (LayoutObject* layout_object = this->GetLayoutObject())
-    layout_object->SetShouldDoFullPaintInvalidation();
+  SetVolumeInternal(volume);
 }
 
 bool MediaControlVolumeSliderElement::WillRespondToMouseMoveEvents() {
@@ -77,11 +73,15 @@
     double volume = value().ToDouble();
     MediaElement().setVolume(volume);
     MediaElement().setMuted(false);
-    if (LayoutObject* layout_object = this->GetLayoutObject())
-      layout_object->SetShouldDoFullPaintInvalidation();
+    SetVolumeInternal(volume);
   }
 }
 
+void MediaControlVolumeSliderElement::SetVolumeInternal(double volume) {
+  SetupBarSegments();
+  SetBeforeSegmentPosition(0, int(volume * 100));
+}
+
 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) {
   return MediaControlElementsHelper::IsUserInteractionEventForSlider(
       event, GetLayoutObject());
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.h
index b7dc4ed8..29d4f96 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.h
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlVolumeSliderElement.h
@@ -5,14 +5,14 @@
 #ifndef MediaControlVolumeSliderElement_h
 #define MediaControlVolumeSliderElement_h
 
-#include "modules/media_controls/elements/MediaControlInputElement.h"
+#include "modules/media_controls/elements/MediaControlSliderElement.h"
 
 namespace blink {
 
 class Event;
 class MediaControlsImpl;
 
-class MediaControlVolumeSliderElement final : public MediaControlInputElement {
+class MediaControlVolumeSliderElement final : public MediaControlSliderElement {
  public:
   explicit MediaControlVolumeSliderElement(MediaControlsImpl&);
 
@@ -31,6 +31,7 @@
  private:
   void DefaultEventHandler(Event*) override;
   bool KeepEventInNode(Event*) override;
+  void SetVolumeInternal(double);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/mediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/mediaControls.css
index 5df35b7..e770228 100644
--- a/third_party/WebKit/Source/modules/media_controls/resources/mediaControls.css
+++ b/third_party/WebKit/Source/modules/media_controls/resources/mediaControls.css
@@ -106,8 +106,14 @@
     bottom: 0px;
 }
 
-audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
-    -webkit-appearance: media-mute-button;
+audio::-webkit-media-controls-mute-button,
+video::-webkit-media-controls-mute-button {
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_sound_not_muted.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -119,6 +125,12 @@
     color: inherit;
 }
 
+audio::-webkit-media-controls-mute-button.muted,
+video::-webkit-media-controls-mute-button.muted {
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_sound_muted.png) 1x);
+}
+
 audio::-webkit-media-controls-overlay-enclosure {
     display: none;
 }
@@ -141,7 +153,12 @@
 }
 
 video::-webkit-media-controls-overlay-play-button {
-    -webkit-appearance: media-overlay-play-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_overlay_play.png) 1x);
+    background-size: 48px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     position: absolute;
     top: 0;
@@ -186,7 +203,13 @@
 }
 
 video::-internal-media-remoting-cast-icon {
-    -webkit-appearance: -internal-media-remoting-cast-icon;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaremoting_cast.png) 1x,
+      url(default_200_percent/mediaremoting_cast.png) 2x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     position: absolute;
     margin: 0px;
@@ -243,7 +266,12 @@
 }
 
 video::-internal-media-controls-overlay-cast-button {
-    -webkit-appearance: -internal-media-overlay-cast-off-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_overlay_cast_off.png) 1x);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     position: absolute;
     top: 8px;
@@ -258,8 +286,19 @@
     transition: opacity 0.3s;
 }
 
-audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
-    -webkit-appearance: media-play-button;
+video::-internal-media-controls-overlay-cast-button.on {
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_overlay_cast_on.png) 1x);
+}
+
+audio::-webkit-media-controls-play-button,
+video::-webkit-media-controls-play-button {
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_pause.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -271,6 +310,12 @@
     color: inherit;
 }
 
+audio::-webkit-media-controls-play-button.pause,
+video::-webkit-media-controls-play-button.pause {
+  background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_play.png) 1x);
+}
+
 audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container {
     -webkit-appearance: media-controls-background;
     display: flex;
@@ -331,8 +376,9 @@
     text-decoration: none;
 }
 
-audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
-    -webkit-appearance: media-slider;
+audio::-webkit-media-controls-timeline,
+video::-webkit-media-controls-timeline {
+    -webkit-appearance: none;
     display: flex;
     flex: 1 1 auto;
     height: 2px;
@@ -340,16 +386,16 @@
     /* Leave 6px on either side for the thumb.  Use margin so that
      * the slider doesn't extend into it.  We also add 12px border.
      */
-    padding: 0;
-    margin: 0 18px 0 18px;
+    margin: 0 18px;
     background-color: transparent;
     min-width: 25px;
     border: initial;
     color: inherit;
 }
 
-audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider {
-    -webkit-appearance: media-volume-slider;
+audio::-webkit-media-controls-volume-slider,
+video::-webkit-media-controls-volume-slider {
+    -webkit-appearance: none;
     display: flex;
     /* The 1.9 value was empirically chosen to match old-flexbox behaviour
      * and be aesthetically pleasing.
@@ -361,44 +407,83 @@
      * than padding so that the slider doesn't extend into it.  We also
      * leave an addition 12px margin.
      */
-    padding: 0;
-    margin: 0 18px 0 18px;
+    margin: 0 18px;
     background-color: transparent;
     min-width: 25px;
     border: initial;
     color: inherit;
+    box-sizing: border-box;
 }
 
-/* FIXME these shouldn't use special pseudoShadowIds, but nicer rules.
-   https://code.google.com/p/chromium/issues/detail?id=112508
-   https://bugs.webkit.org/show_bug.cgi?id=62218
-*/
-input[type="range" i]::-webkit-media-slider-container {
-    display: flex;
-    align-items: center;
-    flex-direction: row; /* This property is updated by C++ code. */
-    box-sizing: border-box;
-    /** this positions the slider thumb for both time and volume. */
+/**
+ * Segmented Track
+ */
+
+div.-internal-media-controls-segmented-track {
+    margin: 0 -18px 0 -18px;
+    position: relative;
+}
+
+div.-internal-media-controls-segmented-track .-internal-track-segment-background {
+    width: auto;
+    position: absolute;
+    background: #dadada;
     height: 2px;
-    width: 100%;
-    background-color: transparent; /* Background drawing is managed by C++ code to draw ranges. */
+    margin-top: -1px;
+    left: 18px;
+    right: 18px;
+    top: 50%;
 }
 
-/* The negative right margin causes the track to overflow its container. */
-input[type="range" i]::-webkit-media-slider-container > div {
-    margin-right: -18px;  /* box is 36px wide, get to the middle */
-    margin-left:  -18px;
+div.-internal-media-controls-segmented-track .-internal-track-segment-highlight-before,
+div.-internal-media-controls-segmented-track .-internal-track-segment-highlight-after {
+    height: auto;
+    position: absolute;
+    top: 50%;
+    bottom: 0;
+    z-index: 1;
+    height: 2px;
+    margin-top: -1px;
 }
 
-input[type="range" i]::-webkit-media-slider-thumb {
-    box-sizing: border-box;
-    width: 48px;
-    height: 48px;
-    padding: 0px;
+div.-internal-media-controls-segmented-track .-internal-track-segment-highlight-before {
+    background-color: #4285f4;
 }
 
-audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button {
-    -webkit-appearance: media-enter-fullscreen-button;
+div.-internal-media-controls-segmented-track .-internal-track-segment-highlight-after {
+    background-color: #5a5a5a;
+}
+
+/**
+ * Track Thumb
+ */
+
+input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-webkit-slider-thumb {
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_slider_thumb.png) 1x);
+    background-size: 12px;
+    background-repeat: no-repeat;
+    background-position: center center;
+
+    height: 36px;
+    z-index: 2;
+    width: 36px;
+    margin: 0;
+    padding: 0;
+    top: -18px;
+    position: absolute;
+}
+
+audio::-webkit-media-controls-fullscreen-button,
+video::-webkit-media-controls-fullscreen-button {
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_enter_fullscreen.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     overflow: hidden;
@@ -411,8 +496,19 @@
     color: inherit;
 }
 
+audio::-webkit-media-controls-fullscreen-button.fullscreen,
+video::-webkit-media-controls-fullscreen-button.fullscreen {
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_exit_fullscreen.png) 1x);
+}
+
 audio::-internal-media-controls-cast-button, video::-internal-media-controls-cast-button {
-    -webkit-appearance: -internal-media-cast-off-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_cast_off.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -426,12 +522,23 @@
     color: inherit;
 }
 
+audio::-internal-media-controls-cast-button.on,
+video::-internal-media-controls-cast-button.on {
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_cast_on.png) 1x);
+}
+
 audio::-webkit-media-controls-toggle-closed-captions-button {
     display: none;
 }
 
 video::-webkit-media-controls-toggle-closed-captions-button {
-    -webkit-appearance: media-toggle-closed-captions-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_closedcaption_disabled.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -445,6 +552,11 @@
     color: inherit;
 }
 
+video::-webkit-media-controls-toggle-closed-captions-button.visible {
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_closedcaption.png) 1x);
+}
+
 video::-internal-media-controls-text-track-list, video::-internal-media-controls-overflow-menu-list, audio::-internal-media-controls-overflow-menu-list {
     position: absolute;
     bottom: 4px;
@@ -477,7 +589,12 @@
 }
 
 video::-internal-media-controls-text-track-list-item-input {
-    -webkit-appearance: -internal-media-track-selection-checkmark;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_trackselection_checkmark.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     visibility: hidden;
     left: 0;
     vertical-align: middle;
@@ -492,7 +609,12 @@
 }
 
 video::-internal-media-controls-text-track-list-kind-captions {
-    -webkit-appearance: -internal-media-closed-captions-icon;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_closedcaptions_icon.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     height: 20px;
     width: 20px;
     margin-left: 10px;
@@ -500,7 +622,12 @@
 }
 
 video::-internal-media-controls-text-track-list-kind-subtitles {
-    -webkit-appearance: -internal-media-subtitles-icon;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_subtitles_icon.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     height: 20px;
     width: 20px;
     margin-left: 10px;
@@ -508,7 +635,12 @@
 }
 
 video::-internal-media-controls-overflow-button, audio::-internal-media-controls-overflow-button {
-    -webkit-appearance: -internal-media-overflow-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_overflow_menu.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -523,7 +655,12 @@
 }
 
 video::-internal-media-controls-download-button, audio::-internal-media-controls-download-button {
-    -webkit-appearance: -internal-media-download-button;
+    -webkit-appearance: none;
+    background-image: -webkit-image-set(
+      url(default_100_percent/mediaplayer_download.png) 1x);
+    background-size: 32px;
+    background-repeat: no-repeat;
+    background-position: center center;
     display: flex;
     flex: none;
     box-sizing: border-box;
@@ -618,3 +755,18 @@
 video::cue(i) {
     font-style: italic;
 }
+
+.not-loaded input[pseudo="-webkit-media-controls-play-button"],
+.not-loaded input[pseudo="-webkit-media-controls-mute-button"],
+.not-loaded input[pseudo="-webkit-media-controls-overlay-play-button"],
+.not-loaded input[pseudo="-webkit-media-controls-fullscreen-button"],
+.not-loaded input[pseudo="-internal-media-controls-download-button"],
+.not-loaded input[pseudo="-webkit-media-controls-timeline" i],
+.not-loaded input[pseudo="-webkit-media-controls-volume-slider" i] {
+    opacity: 0.4;
+}
+
+.not-loaded input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb,
+.not-loaded input[pseudo="-webkit-media-controls-volume-slider" i]::-webkit-slider-thumb {
+    display: none;
+}
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/media_controls_resources.grd b/third_party/WebKit/Source/modules/media_controls/resources/media_controls_resources.grd
index ec3c11b..c0e1c82 100644
--- a/third_party/WebKit/Source/modules/media_controls/resources/media_controls_resources.grd
+++ b/third_party/WebKit/Source/modules/media_controls/resources/media_controls_resources.grd
@@ -30,10 +30,10 @@
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_OVERFLOW_MENU_ICON" file="mediaplayer_overflow_menu.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_DOWNLOAD_ICON" file="mediaplayer_download.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_SUBTITLES_ICON" file="mediaplayer_subtitles_icon.png" />
+      <structure type="chrome_html" name="IDR_UASTYLE_MEDIA_CONTROLS_CSS" file="mediaControls.css" flattenhtml="true" />
     </structures>
     <includes>
-      <include name="IDR_UASTYLE_MEDIA_CONTROLS_ANDROID_CSS" file="mediaControlsAndroid.css" type="chrome_html" compress="gzip" />
-      <include name="IDR_UASTYLE_MEDIA_CONTROLS_CSS" file="mediaControls.css" type="chrome_html" compress="gzip" />
+      <include name="IDR_UASTYLE_MEDIA_CONTROLS_ANDROID_CSS" file="mediaControlsAndroid.css" type="BINDATA" compress="gzip" />
     </includes>
   </release>
 </grit>
diff --git a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
index 27acb31..f7e7d8c 100644
--- a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
+++ b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
@@ -32,6 +32,7 @@
 
 #include <memory>
 #include "core/dom/ExecutionContext.h"
+#include "core/dom/TaskRunnerHelper.h"
 #include "core/fileapi/Blob.h"
 #include "core/loader/ThreadableLoadingContext.h"
 #include "core/typed_arrays/DOMArrayBuffer.h"
diff --git a/third_party/WebKit/Source/platform/audio/Reverb.cpp b/third_party/WebKit/Source/platform/audio/Reverb.cpp
index 70a2843..a2c011c03 100644
--- a/third_party/WebKit/Source/platform/audio/Reverb.cpp
+++ b/third_party/WebKit/Source/platform/audio/Reverb.cpp
@@ -38,10 +38,6 @@
 #include "platform/wtf/MathExtras.h"
 #include "platform/wtf/PtrUtil.h"
 
-#if defined(OS_MACOSX)
-using namespace std;
-#endif
-
 namespace blink {
 
 using namespace VectorMath;
diff --git a/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h b/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h
index 9942dd7..e05c8d3 100644
--- a/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h
+++ b/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h
@@ -56,6 +56,14 @@
 
   template <typename S>
   const TraceWrapperV8Reference<S>& Cast() const {
+    static_assert(std::is_base_of<S, T>::value, "T must inherit from S");
+    return reinterpret_cast<const TraceWrapperV8Reference<S>&>(
+        const_cast<const TraceWrapperV8Reference<T>&>(*this));
+  }
+  // TODO(mlippautz): Support TraceWrappers(const
+  // TraceWrapperV8Reference<v8::Module>&) and remove UnsafeCast.
+  template <typename S>
+  const TraceWrapperV8Reference<S>& UnsafeCast() const {
     return reinterpret_cast<const TraceWrapperV8Reference<S>&>(
         const_cast<const TraceWrapperV8Reference<T>&>(*this));
   }
@@ -63,7 +71,7 @@
  private:
   inline void InternalSet(v8::Isolate* isolate, v8::Local<T> handle) {
     handle_.Reset(isolate, handle);
-    ScriptWrappableVisitor::WriteBarrier(isolate, &Cast<v8::Value>());
+    ScriptWrappableVisitor::WriteBarrier(isolate, &UnsafeCast<v8::Value>());
   }
 
   v8::Persistent<T> handle_;
diff --git a/third_party/WebKit/Source/platform/fonts/FontDescription.cpp b/third_party/WebKit/Source/platform/fonts/FontDescription.cpp
index a56a3b8..26dc849 100644
--- a/third_party/WebKit/Source/platform/fonts/FontDescription.cpp
+++ b/third_party/WebKit/Source/platform/fonts/FontDescription.cpp
@@ -32,6 +32,7 @@
 #include "platform/Language.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/wtf/Assertions.h"
+#include "platform/wtf/HashFunctions.h"
 #include "platform/wtf/StringHasher.h"
 #include "platform/wtf/text/AtomicStringHash.h"
 #include "platform/wtf/text/StringHash.h"
@@ -274,14 +275,6 @@
     fields_.typesetting_features_ |= blink::kCaps;
 }
 
-static inline void AddToHash(unsigned& hash, unsigned key) {
-  hash = ((hash << 5) + hash) + key;  // Djb2
-}
-
-static inline void AddFloatToHash(unsigned& hash, float value) {
-  AddToHash(hash, StringHasher::HashMemory(&value, sizeof(value)));
-}
-
 unsigned FontDescription::StyleHashWithoutFamilyList() const {
   unsigned hash = 0;
   StringHasher string_hasher;
@@ -292,29 +285,29 @@
       const AtomicString& tag = settings->at(i).Tag();
       for (unsigned j = 0; j < tag.length(); j++)
         string_hasher.AddCharacter(tag[j]);
-      AddToHash(hash, settings->at(i).Value());
+      WTF::AddIntToHash(hash, settings->at(i).Value());
     }
   }
 
   if (VariationSettings())
-    AddToHash(hash, VariationSettings()->GetHash());
+    WTF::AddIntToHash(hash, VariationSettings()->GetHash());
 
   if (locale_) {
     const AtomicString& locale = locale_->LocaleString();
     for (unsigned i = 0; i < locale.length(); i++)
       string_hasher.AddCharacter(locale[i]);
   }
-  AddToHash(hash, string_hasher.GetHash());
+  WTF::AddIntToHash(hash, string_hasher.GetHash());
 
-  AddFloatToHash(hash, specified_size_);
-  AddFloatToHash(hash, computed_size_);
-  AddFloatToHash(hash, adjusted_size_);
-  AddFloatToHash(hash, size_adjust_);
-  AddFloatToHash(hash, letter_spacing_);
-  AddFloatToHash(hash, word_spacing_);
-  AddToHash(hash, fields_as_unsigned_.parts[0]);
-  AddToHash(hash, fields_as_unsigned_.parts[1]);
-  AddToHash(hash, font_selection_request_.GetHash());
+  WTF::AddFloatToHash(hash, specified_size_);
+  WTF::AddFloatToHash(hash, computed_size_);
+  WTF::AddFloatToHash(hash, adjusted_size_);
+  WTF::AddFloatToHash(hash, size_adjust_);
+  WTF::AddFloatToHash(hash, letter_spacing_);
+  WTF::AddFloatToHash(hash, word_spacing_);
+  WTF::AddIntToHash(hash, fields_as_unsigned_.parts[0]);
+  WTF::AddIntToHash(hash, fields_as_unsigned_.parts[1]);
+  WTF::AddIntToHash(hash, font_selection_request_.GetHash());
 
   return hash;
 }
diff --git a/third_party/WebKit/Source/platform/fonts/opentype/FontSettings.cpp b/third_party/WebKit/Source/platform/fonts/opentype/FontSettings.cpp
index 05d2e36..309dccf8 100644
--- a/third_party/WebKit/Source/platform/fonts/opentype/FontSettings.cpp
+++ b/third_party/WebKit/Source/platform/fonts/opentype/FontSettings.cpp
@@ -16,14 +16,6 @@
   return (((tag[0]) << 24) | ((tag[1]) << 16) | ((tag[2]) << 8) | (tag[3]));
 }
 
-static inline void AddToHash(unsigned& hash, unsigned key) {
-  hash = ((hash << 5) + hash) + key;  // Djb2
-};
-
-static inline void AddFloatToHash(unsigned& hash, float value) {
-  AddToHash(hash, WTF::FloatHash<float>::GetHash(value));
-};
-
 unsigned FontVariationSettings::GetHash() const {
   unsigned computed_hash = size() ? 5381 : 0;
   unsigned num_features = size();
@@ -33,8 +25,8 @@
     for (unsigned j = 0; j < tag.length(); j++) {
       string_hasher.AddCharacter(tag[j]);
     }
-    AddToHash(computed_hash, string_hasher.GetHash());
-    AddFloatToHash(computed_hash, at(i).Value());
+    WTF::AddIntToHash(computed_hash, string_hasher.GetHash());
+    WTF::AddFloatToHash(computed_hash, at(i).Value());
   }
   return computed_hash;
 }
diff --git a/third_party/WebKit/Source/platform/geometry/FloatPoint.cpp b/third_party/WebKit/Source/platform/geometry/FloatPoint.cpp
index 1d2cc9c5..85f9edd 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatPoint.cpp
+++ b/third_party/WebKit/Source/platform/geometry/FloatPoint.cpp
@@ -32,16 +32,12 @@
 #include "platform/geometry/DoublePoint.h"
 #include "platform/geometry/LayoutPoint.h"
 #include "platform/geometry/LayoutSize.h"
+#include "platform/graphics/skia/SkiaUtils.h"
 #include "platform/wtf/MathExtras.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
-// Skia has problems when passed infinite, etc floats, filter them to 0.
-static inline SkScalar WebCoreFloatToSkScalar(float f) {
-  return SkFloatToScalar(std::isfinite(f) ? f : 0);
-}
-
 FloatPoint::FloatPoint(const IntPoint& p) : x_(p.X()), y_(p.Y()) {}
 
 FloatPoint::FloatPoint(const DoublePoint& p) : x_(p.X()), y_(p.Y()) {}
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/GraphicsContext3DUtils.h b/third_party/WebKit/Source/platform/graphics/gpu/GraphicsContext3DUtils.h
index d5c273f..bfb3039 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/GraphicsContext3DUtils.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/GraphicsContext3DUtils.h
@@ -10,6 +10,7 @@
 #include "platform/PlatformExport.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/WeakPtr.h"
+#include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/gpu/GrTexture.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index 85b9c1cc..09eece73 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -358,7 +358,7 @@
 
 void ThreadHeap::WeakProcessing(Visitor* visitor) {
   TRACE_EVENT0("blink_gc", "ThreadHeap::weakProcessing");
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
 
   // Weak processing may access unmarked objects but are forbidden from
   // ressurecting them.
@@ -373,7 +373,8 @@
   // callback phase, so the marking stack should still be empty here.
   DCHECK(marking_stack_->IsEmpty());
 
-  double time_for_weak_processing = WTF::CurrentTimeMS() - start_time;
+  double time_for_weak_processing =
+      WTF::MonotonicallyIncreasingTimeMS() - start_time;
   DEFINE_THREAD_SAFE_STATIC_LOCAL(
       CustomCountHistogram, weak_processing_time_histogram,
       ("BlinkGC.TimeForGlobalWeakProcessing", 1, 10 * 1000, 50));
diff --git a/third_party/WebKit/Source/platform/heap/HeapCompact.cpp b/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
index f7ef8ef..8b925d1 100644
--- a/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
@@ -414,7 +414,7 @@
     return;
 
   if (!start_compaction_time_ms_)
-    start_compaction_time_ms_ = WTF::CurrentTimeMS();
+    start_compaction_time_ms_ = WTF::MonotonicallyIncreasingTimeMS();
 }
 
 void HeapCompact::FinishThreadCompaction() {
@@ -429,7 +429,7 @@
   do_compact_ = false;
 
   double time_for_heap_compaction =
-      WTF::CurrentTimeMS() - start_compaction_time_ms_;
+      WTF::MonotonicallyIncreasingTimeMS() - start_compaction_time_ms_;
   DEFINE_THREAD_SAFE_STATIC_LOCAL(
       CustomCountHistogram, time_for_heap_compaction_histogram,
       ("BlinkGC.TimeForHeapCompaction", 1, 10 * 1000, 50));
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 962a2765..00fe5cd 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -262,9 +262,10 @@
   ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState());
   ScriptForbiddenIfMainThreadScope script_forbidden;
 
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
   Address result = LazySweepPages(allocation_size, gc_info_index);
-  GetThreadState()->AccumulateSweepingTime(WTF::CurrentTimeMS() - start_time);
+  GetThreadState()->AccumulateSweepingTime(
+      WTF::MonotonicallyIncreasingTimeMS() - start_time);
   ThreadHeap::ReportMemoryUsageForTracing();
 
   return result;
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 49f94e32..2cd1653 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -633,7 +633,7 @@
   SweepForbiddenScope scope(this);
   ScriptForbiddenIfMainThreadScope script_forbidden_scope;
 
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
   bool sweep_completed = true;
   for (int i = 0; i < BlinkGC::kNumberOfArenas; i++) {
     // lazySweepWithDeadline() won't check the deadline until it sweeps
@@ -650,7 +650,7 @@
       break;
     }
   }
-  AccumulateSweepingTime(WTF::CurrentTimeMS() - start_time);
+  AccumulateSweepingTime(WTF::MonotonicallyIncreasingTimeMS() - start_time);
 
   if (sweep_completed)
     PostSweep();
@@ -964,9 +964,9 @@
   SweepForbiddenScope scope(this);
   ScriptForbiddenIfMainThreadScope script_forbidden_scope;
 
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
   arenas_[BlinkGC::kEagerSweepArenaIndex]->CompleteSweep();
-  AccumulateSweepingTime(WTF::CurrentTimeMS() - start_time);
+  AccumulateSweepingTime(WTF::MonotonicallyIncreasingTimeMS() - start_time);
 }
 
 void ThreadState::CompleteSweep() {
@@ -985,14 +985,15 @@
   ScriptForbiddenIfMainThreadScope script_forbidden_scope;
 
   TRACE_EVENT0("blink_gc,devtools.timeline", "ThreadState::completeSweep");
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
 
   static_assert(BlinkGC::kEagerSweepArenaIndex == 0,
                 "Eagerly swept arenas must be processed first.");
   for (int i = 0; i < BlinkGC::kNumberOfArenas; i++)
     arenas_[i]->CompleteSweep();
 
-  double time_for_complete_sweep = WTF::CurrentTimeMS() - start_time;
+  double time_for_complete_sweep =
+      WTF::MonotonicallyIncreasingTimeMS() - start_time;
   AccumulateSweepingTime(time_for_complete_sweep);
 
   if (IsMainThread()) {
@@ -1307,7 +1308,7 @@
   // ressurecting them.
   ObjectResurrectionForbiddenScope object_resurrection_forbidden(this);
 
-  double start_time = WTF::CurrentTimeMS();
+  double start_time = WTF::MonotonicallyIncreasingTimeMS();
   if (!ordered_pre_finalizers_.IsEmpty()) {
     // Call the prefinalizers in the opposite order to their registration.
     //
@@ -1327,7 +1328,8 @@
     } while (!done);
   }
   if (IsMainThread()) {
-    double time_for_invoking_pre_finalizers = WTF::CurrentTimeMS() - start_time;
+    double time_for_invoking_pre_finalizers =
+        WTF::MonotonicallyIncreasingTimeMS() - start_time;
     DEFINE_STATIC_LOCAL(
         CustomCountHistogram, pre_finalizers_histogram,
         ("BlinkGC.TimeForInvokingPreFinalizers", 1, 10 * 1000, 50));
@@ -1504,7 +1506,7 @@
     TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping",
                  gc_type == BlinkGC::kGCWithoutSweep, "gcReason",
                  GcReasonString(reason));
-    double start_time = WTF::CurrentTimeMS();
+    double start_time = WTF::MonotonicallyIncreasingTimeMS();
 
     if (gc_type == BlinkGC::kTakeSnapshot)
       BlinkGCMemoryDumpProvider::Instance()->ClearProcessDumpForCurrentGC();
@@ -1543,7 +1545,8 @@
       Heap().WeakProcessing(visitor.get());
     }
 
-    double marking_time_in_milliseconds = WTF::CurrentTimeMS() - start_time;
+    double marking_time_in_milliseconds =
+        WTF::MonotonicallyIncreasingTimeMS() - start_time;
     Heap().HeapStats().SetEstimatedMarkingTimePerByte(
         total_object_size
             ? (marking_time_in_milliseconds / 1000 / total_object_size)
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index 38a2a61..6b16f61 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -42,8 +42,6 @@
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/Platform.h"
 
-using namespace blink;
-
 namespace {
 
 bool SupportsUIStateTransitionProgress() {
@@ -70,15 +68,15 @@
   return global_supports_content_area_scrolled_in_direction;
 }
 
-ScrollbarThemeMac* MacOverlayScrollbarTheme() {
-  ScrollbarTheme& scrollbar_theme = ScrollbarTheme::GetTheme();
+blink::ScrollbarThemeMac* MacOverlayScrollbarTheme() {
+  blink::ScrollbarTheme& scrollbar_theme = blink::ScrollbarTheme::GetTheme();
   return !scrollbar_theme.IsMockTheme()
-             ? static_cast<ScrollbarThemeMac*>(&scrollbar_theme)
+             ? static_cast<blink::ScrollbarThemeMac*>(&scrollbar_theme)
              : nil;
 }
 
-ScrollbarPainter ScrollbarPainterForScrollbar(Scrollbar& scrollbar) {
-  if (ScrollbarThemeMac* scrollbar_theme = MacOverlayScrollbarTheme())
+ScrollbarPainter ScrollbarPainterForScrollbar(blink::Scrollbar& scrollbar) {
+  if (blink::ScrollbarThemeMac* scrollbar_theme = MacOverlayScrollbarTheme())
     return scrollbar_theme->PainterForScrollbar(scrollbar);
 
   return nil;
@@ -136,7 +134,7 @@
   if (!_animator)
     return;
   _animator->ImmediateScrollToOffsetForScrollAnimation(
-      ToScrollOffset(newPosition));
+      blink::ToScrollOffset(newPosition));
 }
 
 - (NSPoint)_pixelAlignProposedScrollPosition:(NSPoint)newOrigin {
@@ -177,14 +175,14 @@
 @end
 
 @interface BlinkScrollbarPainterControllerDelegate : NSObject {
-  ScrollableArea* _scrollableArea;
+  blink::ScrollableArea* _scrollableArea;
 }
-- (id)initWithScrollableArea:(ScrollableArea*)scrollableArea;
+- (id)initWithScrollableArea:(blink::ScrollableArea*)scrollableArea;
 @end
 
 @implementation BlinkScrollbarPainterControllerDelegate
 
-- (id)initWithScrollableArea:(ScrollableArea*)scrollableArea {
+- (id)initWithScrollableArea:(blink::ScrollableArea*)scrollableArea {
   self = [super init];
   if (!self)
     return nil;
@@ -274,7 +272,7 @@
 
   [scrollerImpPair setScrollerStyle:newRecommendedScrollerStyle];
 
-  static_cast<ScrollAnimatorMac&>(_scrollableArea->GetScrollAnimator())
+  static_cast<blink::ScrollAnimatorMac&>(_scrollableArea->GetScrollAnimator())
       .UpdateScrollerStyle();
 }
 
@@ -344,14 +342,14 @@
 }  // namespace blink
 
 @interface BlinkScrollbarPartAnimation : NSObject {
-  Scrollbar* _scrollbar;
-  std::unique_ptr<BlinkScrollbarPartAnimationTimer> _timer;
+  blink::Scrollbar* _scrollbar;
+  std::unique_ptr<blink::BlinkScrollbarPartAnimationTimer> _timer;
   RetainPtr<ScrollbarPainter> _scrollbarPainter;
   FeatureToAnimate _featureToAnimate;
   CGFloat _startValue;
   CGFloat _endValue;
 }
-- (id)initWithScrollbar:(Scrollbar*)scrollbar
+- (id)initWithScrollbar:(blink::Scrollbar*)scrollbar
        featureToAnimate:(FeatureToAnimate)featureToAnimate
             animateFrom:(CGFloat)startValue
               animateTo:(CGFloat)endValue
@@ -360,7 +358,7 @@
 
 @implementation BlinkScrollbarPartAnimation
 
-- (id)initWithScrollbar:(Scrollbar*)scrollbar
+- (id)initWithScrollbar:(blink::Scrollbar*)scrollbar
        featureToAnimate:(FeatureToAnimate)featureToAnimate
             animateFrom:(CGFloat)startValue
               animateTo:(CGFloat)endValue
@@ -369,8 +367,8 @@
   if (!self)
     return nil;
 
-  _timer =
-      WTF::WrapUnique(new BlinkScrollbarPartAnimationTimer(self, duration));
+  _timer = WTF::WrapUnique(
+      new blink::BlinkScrollbarPartAnimationTimer(self, duration));
   _scrollbar = scrollbar;
   _featureToAnimate = featureToAnimate;
   _startValue = startValue;
@@ -411,22 +409,22 @@
   else
     currentValue = progress;
 
-  ScrollbarPart invalidParts = kNoPart;
+  blink::ScrollbarPart invalidParts = blink::kNoPart;
   switch (_featureToAnimate) {
     case ThumbAlpha:
       [_scrollbarPainter.Get() setKnobAlpha:currentValue];
       break;
     case TrackAlpha:
       [_scrollbarPainter.Get() setTrackAlpha:currentValue];
-      invalidParts = static_cast<ScrollbarPart>(~kThumbPart);
+      invalidParts = static_cast<blink::ScrollbarPart>(~blink::kThumbPart);
       break;
     case UIStateTransition:
       [_scrollbarPainter.Get() setUiStateTransitionProgress:currentValue];
-      invalidParts = kAllParts;
+      invalidParts = blink::kAllParts;
       break;
     case ExpansionTransition:
       [_scrollbarPainter.Get() setExpansionTransitionProgress:currentValue];
-      invalidParts = kThumbPart;
+      invalidParts = blink::kThumbPart;
       break;
   }
 
@@ -481,8 +479,8 @@
   END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-- (ScrollAnimatorMac&)scrollAnimator {
-  return static_cast<ScrollAnimatorMac&>(
+- (blink::ScrollAnimatorMac&)scrollAnimator {
+  return static_cast<blink::ScrollAnimatorMac&>(
       _scrollbar->GetScrollableArea()->GetScrollAnimator());
 }
 
@@ -534,19 +532,19 @@
   }
 
   if (part == blink::kThumbPart &&
-      _scrollbar->Orientation() == kVerticalScrollbar) {
+      _scrollbar->Orientation() == blink::kVerticalScrollbar) {
     if (newAlpha == 1) {
-      IntRect thumbRect = IntRect([scrollerPainter rectForPart:NSScrollerKnob]);
+      blink::IntRect thumbRect([scrollerPainter rectForPart:NSScrollerKnob]);
       [self scrollAnimator].SetVisibleScrollerThumbRect(thumbRect);
     } else
-      [self scrollAnimator].SetVisibleScrollerThumbRect(IntRect());
+      [self scrollAnimator].SetVisibleScrollerThumbRect(blink::IntRect());
   }
 
   scrollbarPartAnimation.AdoptNS([[BlinkScrollbarPartAnimation alloc]
       initWithScrollbar:_scrollbar
-       featureToAnimate:part == kThumbPart ? ThumbAlpha : TrackAlpha
-            animateFrom:part == kThumbPart ? [scrollerPainter knobAlpha]
-                                           : [scrollerPainter trackAlpha]
+       featureToAnimate:part == blink::kThumbPart ? ThumbAlpha : TrackAlpha
+            animateFrom:part == blink::kThumbPart ? [scrollerPainter knobAlpha]
+                                                  : [scrollerPainter trackAlpha]
               animateTo:newAlpha
                duration:duration]);
   [scrollbarPartAnimation.Get() startAnimation];
@@ -673,7 +671,7 @@
     _hasExpandedSinceInvisible = YES;
   } else if (newOverlayScrollerState != NSScrollerStateInvisible &&
              _hasExpandedSinceInvisible) {
-    _scrollbar->SetNeedsPaintInvalidation(kThumbPart);
+    _scrollbar->SetNeedsPaintInvalidation(blink::kThumbPart);
     _hasExpandedSinceInvisible = NO;
   }
 }
@@ -693,11 +691,11 @@
 namespace blink {
 
 ScrollAnimatorBase* ScrollAnimatorBase::Create(
-    ScrollableArea* scrollable_area) {
+    blink::ScrollableArea* scrollable_area) {
   return new ScrollAnimatorMac(scrollable_area);
 }
 
-ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollable_area)
+ScrollAnimatorMac::ScrollAnimatorMac(blink::ScrollableArea* scrollable_area)
     : ScrollAnimatorBase(scrollable_area),
       task_runner_(
           Platform::Current()->CurrentThread()->Scheduler()->TimerTaskRunner()),
@@ -964,7 +962,7 @@
     return;
   }
 
-  ScrollbarThemeMac* mac_theme = MacOverlayScrollbarTheme();
+  blink::ScrollbarThemeMac* mac_theme = MacOverlayScrollbarTheme();
   if (!mac_theme) {
     needs_scroller_style_update_ = false;
     return;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
index 508b42c..c810983 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
@@ -47,8 +47,6 @@
 // FIXME: There are repainting problems due to Aqua scroll bar buttons' visual
 // overflow.
 
-using namespace blink;
-
 @interface NSColor (WebNSColorDetails)
 + (NSImage*)_linenPatternImage;
 @end
diff --git a/third_party/WebKit/Source/platform/scroll/WebScrollbarTheme.mm b/third_party/WebKit/Source/platform/scroll/WebScrollbarTheme.mm
index 3f54fdb..e3f47bb 100644
--- a/third_party/WebKit/Source/platform/scroll/WebScrollbarTheme.mm
+++ b/third_party/WebKit/Source/platform/scroll/WebScrollbarTheme.mm
@@ -35,8 +35,6 @@
 #include "platform/mac/NSScrollerImpDetails.h"
 #include "platform/scroll/ScrollbarThemeMac.h"
 
-using namespace blink;
-
 namespace blink {
 
 static_assert(static_cast<NSScrollerStyle>(kScrollerStyleLegacy) ==
diff --git a/third_party/WebKit/Source/platform/wtf/HashFunctions.h b/third_party/WebKit/Source/platform/wtf/HashFunctions.h
index 6dc9939..f1c27b3 100644
--- a/third_party/WebKit/Source/platform/wtf/HashFunctions.h
+++ b/third_party/WebKit/Source/platform/wtf/HashFunctions.h
@@ -57,32 +57,6 @@
 
 // Thomas Wang's 32 Bit Mix Function:
 // http://www.cris.com/~Ttwang/tech/inthash.htm
-inline unsigned HashInt(uint8_t key8) {
-  unsigned key = key8;
-  key += ~(key << 15);
-  key ^= (key >> 10);
-  key += (key << 3);
-  key ^= (key >> 6);
-  key += ~(key << 11);
-  key ^= (key >> 16);
-  return key;
-}
-
-// Thomas Wang's 32 Bit Mix Function:
-// http://www.cris.com/~Ttwang/tech/inthash.htm
-inline unsigned HashInt(uint16_t key16) {
-  unsigned key = key16;
-  key += ~(key << 15);
-  key ^= (key >> 10);
-  key += (key << 3);
-  key ^= (key >> 6);
-  key += ~(key << 11);
-  key ^= (key >> 16);
-  return key;
-}
-
-// Thomas Wang's 32 Bit Mix Function:
-// http://www.cris.com/~Ttwang/tech/inthash.htm
 inline unsigned HashInt(uint32_t key) {
   key += ~(key << 15);
   key ^= (key >> 10);
@@ -93,6 +67,16 @@
   return key;
 }
 
+inline unsigned HashInt(uint16_t key16) {
+  uint32_t key = key16;
+  return HashInt(key);
+}
+
+inline unsigned HashInt(uint8_t key8) {
+  uint32_t key = key8;
+  return HashInt(key);
+}
+
 // Thomas Wang's 64 bit Mix Function:
 // http://www.cris.com/~Ttwang/tech/inthash.htm
 inline unsigned HashInt(uint64_t key) {
@@ -195,6 +179,15 @@
   }
 };
 
+// Useful compounding hash functions.
+inline void AddIntToHash(unsigned& hash, unsigned key) {
+  hash = ((hash << 5) + hash) + key;  // Djb2
+};
+
+inline void AddFloatToHash(unsigned& hash, float value) {
+  AddIntToHash(hash, FloatHash<float>::GetHash(value));
+};
+
 // Default hash function for each type.
 template <typename T>
 struct DefaultHash;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
index d73c30d..3ca5a7e 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
@@ -16,7 +16,7 @@
 from webkitpy.common.memoized import memoized
 from webkitpy.common.net.git_cl import GitCL
 from webkitpy.common.path_finder import PathFinder
-from webkitpy.layout_tests.models.test_expectations import TestExpectationLine, TestExpectations
+from webkitpy.layout_tests.models.test_expectations import TestExpectationLine
 from webkitpy.w3c.wpt_manifest import WPTManifest
 
 _log = logging.getLogger(__name__)
@@ -334,7 +334,9 @@
         for name in sorted(port_names):
             specifiers.append(self.host.builders.version_specifier_for_port_name(name))
 
-        specifiers.extend(self.skipped_specifiers(test_name))
+        if self.specifiers_can_extend_to_all_platforms(specifiers, test_name):
+            return ''
+
         specifiers = self.simplify_specifiers(specifiers, self.port.configuration_specifier_macros())
         if not specifiers:
             return ''
@@ -347,6 +349,16 @@
             return list(tuple_or_value)
         return [tuple_or_value]
 
+    def specifiers_can_extend_to_all_platforms(self, specifiers, test_name):
+        """Tests whether a list of specifiers can be extended to all platforms.
+
+        Tries to add skipped platform specifiers to the list and tests if the
+        extended list covers all platforms.
+        """
+        extended_specifiers = specifiers + self.skipped_specifiers(test_name)
+        # If the list is simplified to empty, then all platforms are covered.
+        return not self.simplify_specifiers(extended_specifiers, self.port.configuration_specifier_macros())
+
     def skipped_specifiers(self, test_name):
         """Returns a list of platform specifiers for which the test is skipped."""
         specifiers = []
@@ -361,7 +373,7 @@
         return [self.host.port_factory.get_from_builder_name(name) for name in self._get_try_bots()]
 
     @staticmethod
-    def simplify_specifiers(specifiers, configuration_specifier_macros):  # pylint: disable=unused-argument
+    def simplify_specifiers(specifiers, configuration_specifier_macros):
         """Converts some collection of specifiers to an equivalent and maybe shorter list.
 
         The input strings are all case-insensitive, but the strings in the
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
index 3558ee6..5c28bcf 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
@@ -329,6 +329,19 @@
         updater = WPTExpectationsUpdater(host)
         self.assertEqual(updater.skipped_specifiers('external/wpt/test.html'), ['Precise', 'Trusty'])
 
+    def test_specifiers_can_extend_to_all_platforms(self):
+        host = self.mock_host()
+        expectations_path = '/test.checkout/LayoutTests/NeverFixTests'
+        host.filesystem.write_text_file(
+            expectations_path,
+            'crbug.com/111 [ Linux ] external/wpt/test.html [ WontFix ]\n')
+        host.filesystem.write_text_file('/test.checkout/LayoutTests/external/wpt/test.html', '')
+        updater = WPTExpectationsUpdater(host)
+        self.assertTrue(updater.specifiers_can_extend_to_all_platforms(
+            ['Mac10.10', 'Mac10.11', 'Win7', 'Win10'], 'external/wpt/test.html'))
+        self.assertFalse(updater.specifiers_can_extend_to_all_platforms(
+            ['Mac10.10', 'Win7', 'Win10'], 'external/wpt/test.html'))
+
     def test_simplify_specifiers(self):
         macros = {
             'mac': ['Mac10.10', 'mac10.11'],
@@ -353,6 +366,8 @@
         self.assertEqual(
             updater.specifier_part(['test-mac-mac10.10', 'test-win-win7', 'test-win-win10'], 'external/wpt/test.html'), '')
         self.assertEqual(
+            updater.specifier_part(['test-win-win7', 'test-win-win10'], 'external/wpt/test.html'), '[ Win ]')
+        self.assertEqual(
             updater.specifier_part(['test-win-win7', 'test-win-win10'], 'external/wpt/another.html'), '[ Win ]')
 
     def test_merge_dicts_with_conflict_raise_exception(self):
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index dc49b87..a2cb1f9 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -124,6 +124,7 @@
     "platform/Platform.h",
     "platform/PointerProperties.h",
     "platform/ShapeProperties.h",
+    "platform/TaskType.h",
     "platform/URLConversion.h",
     "platform/UserMetricsAction.h",
     "platform/WebAddressSpace.h",
diff --git a/third_party/WebKit/public/platform/TaskType.h b/third_party/WebKit/public/platform/TaskType.h
new file mode 100644
index 0000000..f02af53
--- /dev/null
+++ b/third_party/WebKit/public/platform/TaskType.h
@@ -0,0 +1,121 @@
+// 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 TaskType_h
+#define TaskType_h
+
+namespace blink {
+
+// A list of task sources known to Blink according to the spec.
+enum class TaskType : unsigned {
+  // Speced tasks and related internal tasks should be posted to one of
+  // the following task runners. These task runners may be throttled.
+
+  // https://html.spec.whatwg.org/multipage/webappapis.html#generic-task-sources
+  //
+  // This task source is used for features that react to DOM manipulations, such
+  // as things that happen in a non-blocking fashion when an element is inserted
+  // into the document.
+  kDOMManipulation,
+  // This task source is used for features that react to user interaction, for
+  // example keyboard or mouse input. Events sent in response to user input
+  // (e.g. click events) must be fired using tasks queued with the user
+  // interaction task source.
+  kUserInteraction,
+  // This task source is used for features that trigger in response to network
+  // activity.
+  kNetworking,
+  // This task source is used for control messages between kNetworking tasks.
+  kNetworkingControl,
+  // This task source is used to queue calls to history.back() and similar APIs.
+  kHistoryTraversal,
+
+  // https://html.spec.whatwg.org/multipage/embedded-content.html#the-embed-element
+  // This task source is used for the embed element setup steps.
+  kEmbed,
+
+  // https://html.spec.whatwg.org/multipage/embedded-content.html#media-elements
+  // This task source is used for all tasks queued in the [Media elements]
+  // section and subsections of the spec unless explicitly specified otherwise.
+  kMediaElementEvent,
+
+  // https://html.spec.whatwg.org/multipage/scripting.html#the-canvas-element
+  // This task source is used to invoke the result callback of
+  // HTMLCanvasElement.toBlob().
+  kCanvasBlobSerialization,
+
+  // https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
+  // This task source is used when an algorithm requires a microtask to be
+  // queued.
+  kMicrotask,
+
+  // https://html.spec.whatwg.org/multipage/webappapis.html#timers
+  // This task source is used to queue tasks queued by setInterval() and similar
+  // APIs.
+  kTimer,
+
+  // https://html.spec.whatwg.org/multipage/comms.html#sse-processing-model
+  // This task source is used for any tasks that are queued by EventSource
+  // objects.
+  kRemoteEvent,
+
+  // https://html.spec.whatwg.org/multipage/comms.html#feedback-from-the-protocol
+  // The task source for all tasks queued in the [WebSocket] section of the
+  // spec.
+  kWebSocket,
+
+  // https://html.spec.whatwg.org/multipage/comms.html#web-messaging
+  // This task source is used for the tasks in cross-document messaging.
+  kPostedMessage,
+
+  // https://html.spec.whatwg.org/multipage/comms.html#message-ports
+  kUnshippedPortMessage,
+
+  // https://www.w3.org/TR/FileAPI/#blobreader-task-source
+  // This task source is used for all tasks queued in the FileAPI spec to read
+  // byte sequences associated with Blob and File objects.
+  kFileReading,
+
+  // https://www.w3.org/TR/IndexedDB/#request-api
+  kDatabaseAccess,
+
+  // https://w3c.github.io/presentation-api/#common-idioms
+  // This task source is used for all tasks in the Presentation API spec.
+  kPresentation,
+
+  // https://www.w3.org/TR/2016/WD-generic-sensor-20160830/#sensor-task-source
+  // This task source is used for all tasks in the Sensor API spec.
+  kSensor,
+
+  // https://w3c.github.io/performance-timeline/#performance-timeline
+  kPerformanceTimeline,
+
+  // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
+  // This task source is used for all tasks in the WebGL spec.
+  kWebGL,
+
+  // Use MiscPlatformAPI for a task that is defined in the spec but is not yet
+  // associated with any specific task runner in the spec. MiscPlatformAPI is
+  // not encouraged for stable and matured APIs. The spec should define the task
+  // runner explicitly.
+  // The task runner may be throttled.
+  kMiscPlatformAPI,
+
+  // Other internal tasks that cannot fit any of the above task runners
+  // can be posted here, but the usage is not encouraged. The task runner
+  // may be throttled.
+  //
+  // UnspecedLoading type should be used for all tasks associated with
+  // loading page content, UnspecedTimer should be used for all other purposes.
+  kUnspecedTimer,
+  kUnspecedLoading,
+
+  // Tasks that must not be throttled should be posted here, but the usage
+  // should be very limited.
+  kUnthrottled,
+};
+
+}  // namespace blink
+
+#endif
diff --git a/tools/battor_agent/battor_agent.cc b/tools/battor_agent/battor_agent.cc
index 0ad10b82..cdae1f5 100644
--- a/tools/battor_agent/battor_agent.cc
+++ b/tools/battor_agent/battor_agent.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 #include "tools/battor_agent/battor_agent.h"
 
+#include <algorithm>
 #include <iomanip>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -102,6 +104,19 @@
 }
 }  // namespace
 
+BattOrResults::BattOrResults() {}
+
+BattOrResults::BattOrResults(std::string details,
+                             std::vector<float> power_samples_W,
+                             uint32_t sample_rate)
+    : details_(std::move(details)),
+      power_samples_W_(std::move(power_samples_W)),
+      sample_rate_(sample_rate) {}
+
+BattOrResults::BattOrResults(const BattOrResults&) = default;
+
+BattOrResults::~BattOrResults() {}
+
 BattOrAgent::BattOrAgent(
     const std::string& path,
     Listener* listener,
@@ -541,7 +556,7 @@
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
           base::Bind(&Listener::OnStopTracingComplete,
-                     base::Unretained(listener_), SamplesToString(), error));
+                     base::Unretained(listener_), SamplesToResults(), error));
       break;
     case Command::RECORD_CLOCK_SYNC_MARKER:
       base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -569,9 +584,9 @@
   num_command_attempts_ = 0;
 }
 
-std::string BattOrAgent::SamplesToString() {
+BattOrResults BattOrAgent::SamplesToResults() {
   if (calibration_frame_.empty() || samples_.empty() || !battor_eeprom_)
-    return "";
+    return BattOrResults();
 
   BattOrSampleConverter converter(*battor_eeprom_, calibration_frame_);
 
@@ -606,7 +621,13 @@
     trace_stream << std::endl;
   }
 
-  return trace_stream.str();
+  // Convert to a vector of power in watts.
+  std::vector<float> samples(samples_.size());
+  for (size_t i = 0; i < samples_.size(); i++)
+    samples[i] = converter.ToWatts(samples_[i]);
+
+  return BattOrResults(trace_stream.str(), samples,
+                       battor_eeprom_->sd_sample_rate);
 }
 
 void BattOrAgent::SetActionTimeout(uint16_t timeout_seconds) {
diff --git a/tools/battor_agent/battor_agent.h b/tools/battor_agent/battor_agent.h
index fa39fee..afce63e 100644
--- a/tools/battor_agent/battor_agent.h
+++ b/tools/battor_agent/battor_agent.h
@@ -6,6 +6,7 @@
 #define TOOLS_BATTOR_AGENT_BATTOR_AGENT_H_
 
 #include <map>
+#include <vector>
 
 #include "base/cancelable_callback.h"
 #include "base/macros.h"
@@ -18,6 +19,29 @@
 
 namespace battor {
 
+// A BattOrResults object contains the results of BattOr tracing, including a
+// summary and sample data in watts.
+class BattOrResults {
+ public:
+  BattOrResults();
+  BattOrResults(std::string details,
+                std::vector<float> power_samples_W,
+                uint32_t sample_rate);
+  BattOrResults(const BattOrResults&);
+  ~BattOrResults();
+
+  // Get a detailed textual representation of the data recorded.
+  const std::string& ToString() const { return details_; }
+  // Returns a vector of power samples (in watts).
+  const std::vector<float>& GetPowerSamples() const { return power_samples_W_; }
+  uint32_t GetSampleRate() const { return sample_rate_; }
+
+ private:
+  std::string details_;
+  std::vector<float> power_samples_W_;
+  uint32_t sample_rate_ = 0;
+};
+
 // A BattOrAgent is a class used to asynchronously communicate with a BattOr for
 // the purpose of collecting power samples. A BattOr is an external USB device
 // that's capable of recording accurate, high-frequency (2000Hz) power samples.
@@ -41,7 +65,7 @@
   class Listener {
    public:
     virtual void OnStartTracingComplete(BattOrError error) = 0;
-    virtual void OnStopTracingComplete(const std::string& trace,
+    virtual void OnStopTracingComplete(const BattOrResults& trace,
                                        BattOrError error) = 0;
     virtual void OnRecordClockSyncMarkerComplete(BattOrError error) = 0;
     virtual void OnGetFirmwareGitHashComplete(const std::string& version,
@@ -141,7 +165,7 @@
   void CompleteCommand(BattOrError error);
 
   // Returns a formatted version of samples_ with timestamps and real units.
-  std::string SamplesToString();
+  BattOrResults SamplesToResults();
 
   // Sets and restarts the action timeout timer.
   void SetActionTimeout(uint16_t timeout_seconds);
diff --git a/tools/battor_agent/battor_agent_bin.cc b/tools/battor_agent/battor_agent_bin.cc
index 487799ec..a9f11c5 100644
--- a/tools/battor_agent/battor_agent_bin.cc
+++ b/tools/battor_agent/battor_agent_bin.cc
@@ -34,15 +34,18 @@
 #include <stdint.h>
 
 #include <fstream>
+#include <iomanip>
 #include <iostream>
 
 #include "base/at_exit.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_tokenizer.h"
@@ -289,25 +292,97 @@
         base::Bind(&BattOrAgent::StopTracing, base::Unretained(agent_.get())));
   }
 
-  void OnStopTracingComplete(const std::string& trace,
+  std::string BattOrResultsToSummary(const BattOrResults& results) {
+    const uint32_t samples_per_second = results.GetSampleRate();
+
+    // Print a summary of a BattOr trace. These summaries are intended for human
+    // consumption and are subject to change at any moment. The summary is
+    // printed when using interactive mode.
+    std::stringstream trace_summary;
+    // Display floating-point numbers without exponents, in a five-character
+    // field, with two digits of precision. ie;
+    // 12.39
+    //  8.40
+    trace_summary << std::fixed << std::setw(5) << std::setprecision(2);
+
+    // Scan through the sample data to summarize it. Report on average power and
+    // second-by-second power including min-second, median-second, and
+    // max-second.
+    double total_power = 0.0;
+    int num_seconds = 0;
+    std::vector<double> power_by_seconds;
+    const std::vector<float>& samples = results.GetPowerSamples();
+    for (size_t i = 0; i < samples.size(); i += samples_per_second) {
+      size_t loop_count = samples.size() - i;
+      if (loop_count > samples_per_second)
+        loop_count = samples_per_second;
+
+      double second_power = 0.0;
+      for (size_t j = i; j < i + loop_count; ++j) {
+        total_power += samples[i];
+        second_power += samples[i];
+      }
+
+      // Print/store results for full seconds.
+      if (loop_count == samples_per_second) {
+        // Calculate power for one second in watts.
+        second_power /= samples_per_second;
+        trace_summary << "Second " << std::setw(2) << num_seconds
+                      << " average power: " << std::setw(5) << second_power
+                      << " W" << std::endl;
+        ++num_seconds;
+        power_by_seconds.push_back(second_power);
+      }
+    }
+    // Calculate average power in watts.
+    const double average_power_W = total_power / samples.size();
+    const double duration_sec =
+        static_cast<double>(samples.size()) / samples_per_second;
+    trace_summary << "Average power over " << duration_sec
+                  << " s : " << average_power_W << " W" << std::endl;
+    std::sort(power_by_seconds.begin(), power_by_seconds.end());
+    if (power_by_seconds.size() >= 3) {
+      trace_summary << "Summary of power-by-seconds:" << std::endl
+                    << "Minimum: " << power_by_seconds[0] << std::endl
+                    << "Median:  "
+                    << power_by_seconds[power_by_seconds.size() / 2]
+                    << std::endl
+                    << "Maximum: "
+                    << power_by_seconds[power_by_seconds.size() - 1]
+                    << std::endl;
+    } else {
+      trace_summary << "Too short a trace to generate per-second summary.";
+    }
+
+    return trace_summary.str();
+  }
+
+  void OnStopTracingComplete(const BattOrResults& results,
                              BattOrError error) override {
     if (error == BATTOR_ERROR_NONE) {
+      std::string output_file = trace_output_file_;
       if (trace_output_file_.empty()) {
-        if (interactive_) {
-          // Printing of summary statistics will happen here.
-          std::cout << trace.size() << " bytes of output collected." << endl;
-        } else {
-          std::cout << trace;
-        }
-      } else {
-        std::ofstream trace_stream(trace_output_file_);
-        if (!trace_stream.is_open()) {
-          std::cout << "Tracing output file could not be opened." << endl;
-          exit(1);
-        }
-        trace_stream << trace;
-        trace_stream.close();
+        // Save the detailed results in case they are needed.
+        base::FilePath default_path;
+        PathService::Get(base::DIR_USER_DESKTOP, &default_path);
+        default_path = default_path.Append(FILE_PATH_LITERAL("trace_data.txt"));
+        output_file = default_path.AsUTF8Unsafe().c_str();
+        std::cout << "Saving detailed results to " << output_file << std::endl;
       }
+
+      if (interactive_) {
+        // Print a summary of the trace.
+        std::cout << BattOrResultsToSummary(results) << endl;
+      }
+
+      std::ofstream trace_stream(output_file);
+      if (!trace_stream.is_open()) {
+        std::cout << "Tracing output file \"" << output_file
+                  << "\" could not be opened." << endl;
+        exit(1);
+      }
+      trace_stream << results.ToString();
+      trace_stream.close();
       std::cout << "Done." << endl;
     } else {
       HandleError(error);
diff --git a/tools/battor_agent/battor_agent_unittest.cc b/tools/battor_agent/battor_agent_unittest.cc
index d5f882b..7b940e32 100644
--- a/tools/battor_agent/battor_agent_unittest.cc
+++ b/tools/battor_agent/battor_agent_unittest.cc
@@ -107,11 +107,11 @@
     command_error_ = error;
   }
 
-  void OnStopTracingComplete(const std::string& trace,
+  void OnStopTracingComplete(const BattOrResults& results,
                              BattOrError error) override {
     is_command_complete_ = true;
     command_error_ = error;
-    trace_ = trace;
+    trace_ = results.ToString();
   }
 
   void OnRecordClockSyncMarkerComplete(BattOrError error) override {
diff --git a/tools/battor_agent/battor_sample_converter.cc b/tools/battor_agent/battor_sample_converter.cc
index e13afa17..bcee95b 100644
--- a/tools/battor_agent/battor_sample_converter.cc
+++ b/tools/battor_agent/battor_sample_converter.cc
@@ -91,6 +91,12 @@
   return BattOrSample{time_ms, voltage, current};
 }
 
+float BattOrSampleConverter::ToWatts(const RawBattOrSample& raw_sample) const {
+  BattOrSample sample = ToSample(raw_sample, 0);
+
+  return sample.current_mA * sample.voltage_mV * 1e-6f;
+}
+
 BattOrSample BattOrSampleConverter::MinSample() const {
   // Create a minimum raw sample.
   RawBattOrSample sample_raw = {kAnalogDigitalConverterMinValue,
diff --git a/tools/battor_agent/battor_sample_converter.h b/tools/battor_agent/battor_sample_converter.h
index 89e312c..23915e9 100644
--- a/tools/battor_agent/battor_sample_converter.h
+++ b/tools/battor_agent/battor_sample_converter.h
@@ -33,6 +33,9 @@
   BattOrSample ToSample(const RawBattOrSample& sample,
                         size_t sample_number) const;
 
+  // Converts a raw sample to watts.
+  float ToWatts(const RawBattOrSample& sample) const;
+
   // Returns the lowest magnitude sample that the BattOr can collect.
   BattOrSample MinSample() const;
 
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 599c51d..2699d06e 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -331,6 +331,18 @@
 
   MaybeUpload(args, pdir, platform)
 
+  # Zip up llvm-code-coverage for code coverage.
+  code_coverage_dir = 'llvm-code-coverage-' + stamp
+  shutil.rmtree(code_coverage_dir, ignore_errors=True)
+  os.makedirs(os.path.join(code_coverage_dir, 'bin'))
+  for filename in ['llvm-cov', 'llvm-profdata']:
+    shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', filename + exe_ext),
+                os.path.join(code_coverage_dir, 'bin'))
+  with tarfile.open(code_coverage_dir + '.tgz', 'w:gz') as tar:
+    tar.add(os.path.join(code_coverage_dir, 'bin'), arcname='bin',
+            filter=PrintTarProgress)
+  MaybeUpload(args, code_coverage_dir, platform)
+
   # Zip up llvm-objdump for sanitizer coverage.
   objdumpdir = 'llvmobjdump-' + stamp
   shutil.rmtree(objdumpdir, ignore_errors=True)
diff --git a/tools/cygprofile/BUILD.gn b/tools/cygprofile/BUILD.gn
index f640869..fc4015a 100644
--- a/tools/cygprofile/BUILD.gn
+++ b/tools/cygprofile/BUILD.gn
@@ -35,3 +35,21 @@
     "//testing/gtest",
   ]
 }
+
+executable("cygprofile_perftests") {
+  testonly = true
+
+  sources = [
+    "cygprofile_perftest.cc",
+  ]
+
+  configs -= [ "//build/config/android:default_cygprofile_instrumentation" ]
+  configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
+
+  deps = [
+    ":cygprofile",
+    "//base",
+    "//testing/gtest",
+    "//testing/perf",
+  ]
+}
diff --git a/tools/cygprofile/cygprofile.cc b/tools/cygprofile/cygprofile.cc
index fe69196..7c04fed 100644
--- a/tools/cygprofile/cygprofile.cc
+++ b/tools/cygprofile/cygprofile.cc
@@ -201,25 +201,21 @@
 };
 
 // Single log entry recorded for each function call.
-LogEntry::LogEntry(const void* address)
-    : time(GetCurrentTime()),
-      pid(getpid()),
-      tid(GetTID()),
-      address(address) {
-}
+LogEntry::LogEntry(const void* address, pid_t pid, pid_t tid)
+    : time(GetCurrentTime()), pid(pid), tid(tid), address(address) {}
 
 ThreadLog::ThreadLog()
-  : tid_(GetTID()),
-    in_use_(false),
-    flush_callback_(
-        base::Bind(&ThreadLog::FlushInternal, base::Unretained(this))) {
-}
+    : pid_(getpid()),
+      tid_(GetTID()),
+      in_use_(false),
+      flush_callback_(
+          base::Bind(&ThreadLog::FlushInternal, base::Unretained(this))) {}
 
 ThreadLog::ThreadLog(const FlushCallback& flush_callback)
-  : tid_(GetTID()),
-    in_use_(false),
-    flush_callback_(flush_callback) {
-}
+    : pid_(getpid()),
+      tid_(GetTID()),
+      in_use_(false),
+      flush_callback_(flush_callback) {}
 
 ThreadLog::~ThreadLog() {
   PCHECK(0 == pthread_setspecific(g_tls_slot, NULL));
@@ -230,14 +226,12 @@
     return;
   in_use_ = true;
 
-  CHECK_EQ(tid_, GetTID());
-  const std::pair<base::hash_set<void*>::iterator, bool> pair =
-      called_functions_.insert(address);
-  const bool did_insert = pair.second;
+  DCHECK_EQ(tid_, GetTID());
+  bool did_insert = called_functions_.insert(address).second;
 
   if (did_insert) {
     base::AutoLock auto_lock(lock_);
-    entries_.push_back(LogEntry(address));
+    entries_.emplace_back(address, pid_, tid_);
     // Crash in a quickly understandable way instead of crashing (or maybe not
     // though) due to OOM.
     CHECK_LE(entries_.size(), kMaxBufferSize);
diff --git a/tools/cygprofile/cygprofile.h b/tools/cygprofile/cygprofile.h
index 7b25acc..97684e78 100644
--- a/tools/cygprofile/cygprofile.h
+++ b/tools/cygprofile/cygprofile.h
@@ -64,7 +64,7 @@
 
 // Single log entry recorded for each function call.
 struct LogEntry {
-  LogEntry(const void* address);
+  LogEntry(const void* address, pid_t pid, pid_t tid);
 
   const timespec time;
   const pid_t pid;
@@ -100,6 +100,9 @@
   // above.
   void FlushInternal(std::vector<LogEntry>* entries) const;
 
+  // Process ID, as returned by getpid().
+  const pid_t pid_;
+
   // Thread identifier as Linux kernel shows it.  LWP (light-weight process) is
   // a unique ID of the thread in the system, unlike pthread_self() which is the
   // same for fork()-ed threads.
diff --git a/tools/cygprofile/cygprofile_perftest.cc b/tools/cygprofile/cygprofile_perftest.cc
new file mode 100644
index 0000000..ae8fe3e7
--- /dev/null
+++ b/tools/cygprofile/cygprofile_perftest.cc
@@ -0,0 +1,67 @@
+// 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 "tools/cygprofile/cygprofile.h"
+
+#include <cstdint>
+#include <vector>
+
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace cygprofile {
+
+namespace {
+
+void AddEntryCost(int iterations, int addresses_count) {
+  // This is intentionally leaky. ThreadLog() destructor would call abort(),
+  // limiting us to a single test. Leaking ThreadLog is fine as long as we clean
+  // up the entries.
+  auto* thread_log = new ThreadLog();
+
+  auto tick = base::TimeTicks::Now();
+  for (int i = 0; i < iterations; i++) {
+    for (int address = 0; address < addresses_count; address++) {
+      thread_log->AddEntry(reinterpret_cast<void*>(address));
+    }
+  }
+  auto tock = base::TimeTicks::Now();
+  double nanos = static_cast<double>((tock - tick).InNanoseconds());
+  auto ns_per_call =
+      nanos / (iterations * static_cast<double>(addresses_count));
+  auto modifier = base::StringPrintf("_%d_%d", iterations, addresses_count);
+  perf_test::PrintResult("AddEntryCostPerCall", modifier, "", ns_per_call, "ns",
+                         true);
+
+  // Entries cleanup, see comment at the beginning of the function.
+  std::vector<LogEntry> entries;
+  thread_log->TakeEntries(&entries);
+}
+}  // namespace
+
+TEST(CygprofilePerfTest, CreateEntries_10_10000) {
+  AddEntryCost(10, 10000);
+}
+
+TEST(CygprofilePerfTest, CreateEntries_100_10000) {
+  AddEntryCost(100, 10000);
+}
+
+TEST(CygprofilePerfTest, CreateEntries_10_100000) {
+  AddEntryCost(10, 100000);
+}
+
+TEST(CygprofilePerfTest, CreateEntries_100_1000000) {
+  AddEntryCost(100, 100000);
+}
+
+}  // namespace cygprofile
+
+// Custom runner implementation since base's one requires JNI on Android.
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
index ee0116d..ce0e8ee 100644
--- a/tools/gritsettings/resource_ids
+++ b/tools/gritsettings/resource_ids
@@ -310,6 +310,7 @@
 
   "third_party/WebKit/public/blink_image_resources.grd": {
     "structures": [25300],
+    "includes": [25350],
   },
   "third_party/WebKit/public/blink_resources.grd": {
     "includes": [25400],
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index b434df5..1e0ae21 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -1015,7 +1015,7 @@
       c.Append('// static')
     maybe_namespace = '' if cpp_namespace is None else '%s::' % cpp_namespace
 
-    c.Sblock('std::string %sToString(%s enum_param) {' %
+    c.Sblock('const char* %sToString(%s enum_param) {' %
                  (maybe_namespace, classname))
     c.Sblock('switch (enum_param) {')
     for enum_value in self._type_helper.FollowRef(type_).enum_values:
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 7cf4d17..90e34d33 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -214,7 +214,7 @@
       # static. On the other hand, those declared inline (e.g. in an object) do.
       maybe_static = '' if is_toplevel else 'static '
       (c.Append()
-        .Append('%sstd::string ToString(%s as_enum);' %
+        .Append('%sconst char* ToString(%s as_enum);' %
                 (maybe_static, classname))
         .Append('%s%s Parse%s(const std::string& as_string);' %
                 (maybe_static, classname, classname))
diff --git a/tools/perf/benchmarks/rasterize_and_record_micro.py b/tools/perf/benchmarks/rasterize_and_record_micro.py
index 7686c4b8..e991e33 100644
--- a/tools/perf/benchmarks/rasterize_and_record_micro.py
+++ b/tools/perf/benchmarks/rasterize_and_record_micro.py
@@ -51,7 +51,7 @@
   """Measures rasterize and record performance on the top 25 web pages.
 
   http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
-  page_set = page_sets.Top25PageSet
+  page_set = page_sets.StaticTop25PageSet
 
   @classmethod
   def Name(cls):
@@ -60,23 +60,7 @@
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
-        self.DisableStory('http://www.cnn.com', [story.expectations.ALL],
-                          'crbug.com/528472')
-        self.DisableStory('https://mail.google.com/mail/',
-                          [story.expectations.ALL],
-                          'crbug.com/747021')
-        self.DisableStory('Wikipedia (1 tab)',
-                          [story.expectations.ALL_MAC],
-                          'crbug.com/756117')
-        self.DisableStory('Wordpress',
-                          [story.expectations.ALL_MAC],
-                          'crbug.com/756117')
-        self.DisableStory('http://news.yahoo.com',
-                          [story.expectations.ALL_MAC],
-                          'crbug.com/756117')
-        self.DisableStory('http://sports.yahoo.com/',
-                          [story.expectations.ALL_MAC],
-                          'crbug.com/756117')
+        pass # Nothing disabled.
     return StoryExpectations()
 
 
diff --git a/tools/perf/page_sets/system_health/expectations.py b/tools/perf/page_sets/system_health/expectations.py
index b9069371..d4e37dd 100644
--- a/tools/perf/page_sets/system_health/expectations.py
+++ b/tools/perf/page_sets/system_health/expectations.py
@@ -26,8 +26,6 @@
                       [expectations.MAC_10_11], 'crbug.com/760966')
     self.DisableStory('browse:news:cnn',
                       [expectations.ALL_MAC], 'crbug.com/728576')
-    self.DisableStory('browse:social:facebook_infinite_scroll',
-                      [expectations.ALL_WIN], 'crbug.com/760319')
 
 
 class SystemHealthDesktopMemoryExpectations(expectations.StoryExpectations):
@@ -57,8 +55,6 @@
                       [expectations.ALL_WIN], 'crbug.com/728464')
     self.DisableStory('multitab:misc:typical24',
                       [expectations.ALL_MAC], 'crbug.com/742475')
-    self.DisableStory('browse:social:facebook_infinite_scroll',
-                      [expectations.ALL_WIN], 'crbug.com/760319')
 
 
 class SystemHealthMobileCommonExpectations(expectations.StoryExpectations):
@@ -133,8 +129,6 @@
                       'crbug.com/759777')
     self.DisableStory('browse:news:cnn',
                       [expectations.ALL_MAC], 'crbug.com/728576')
-    self.DisableStory('browse:social:facebook_infinite_scroll',
-                      [expectations.ALL_WIN], 'crbug.com/760319')
 
 
 # Should only include browse:*:* stories.
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
index 5509131..b237dd1 100644
--- a/ui/accessibility/ax_node_data.cc
+++ b/ui/accessibility/ax_node_data.cc
@@ -550,7 +550,8 @@
   std::string result;
 
   result += "id=" + IntToString(id);
-  result += " " + ui::ToString(role);
+  result += " ";
+  result += ui::ToString(role);
 
   result += StateBitfieldToString(state);
 
@@ -663,14 +664,14 @@
         }
         break;
       case AX_ATTR_NAME_FROM:
+        result += " name_from=";
         result +=
-            " name_from=" +
             ui::ToString(static_cast<AXNameFrom>(int_attributes[i].second));
         break;
       case AX_ATTR_DESCRIPTION_FROM:
-        result += " description_from=" +
-                  ui::ToString(
-                      static_cast<AXDescriptionFrom>(int_attributes[i].second));
+        result += " description_from=";
+        result += ui::ToString(
+            static_cast<AXDescriptionFrom>(int_attributes[i].second));
         break;
       case AX_ATTR_ACTIVEDESCENDANT_ID:
         result += " activedescendant=" + value;
diff --git a/ui/accessibility/ax_tree_data.cc b/ui/accessibility/ax_tree_data.cc
index 0d15d52..4a6649d 100644
--- a/ui/accessibility/ax_tree_data.cc
+++ b/ui/accessibility/ax_tree_data.cc
@@ -67,12 +67,14 @@
   if (sel_anchor_object_id != -1) {
     result += " sel_anchor_object_id=" + IntToString(sel_anchor_object_id);
     result += " sel_anchor_offset=" + IntToString(sel_anchor_offset);
-    result += " sel_anchor_affinity=" + ui::ToString(sel_anchor_affinity);
+    result += " sel_anchor_affinity=";
+    result += ui::ToString(sel_anchor_affinity);
   }
   if (sel_focus_object_id != -1) {
     result += " sel_focus_object_id=" + IntToString(sel_focus_object_id);
     result += " sel_focus_offset=" + IntToString(sel_focus_offset);
-    result += " sel_focus_affinity=" + ui::ToString(sel_focus_affinity);
+    result += " sel_focus_affinity=";
+    result += ui::ToString(sel_focus_affinity);
   }
 
   return result;
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
index 0bcc650..f6ad71c2 100644
--- a/ui/accessibility/ax_tree_unittest.cc
+++ b/ui/accessibility/ax_tree_unittest.cc
@@ -111,18 +111,16 @@
                      AXNode* node,
                      AXRole old_role,
                      AXRole new_role) override {
-    attribute_change_log_.push_back(StringPrintf("Role changed from %s to %s",
-                                                 ToString(old_role).c_str(),
-                                                 ToString(new_role).c_str()));
+    attribute_change_log_.push_back(StringPrintf(
+        "Role changed from %s to %s", ToString(old_role), ToString(new_role)));
   }
 
   void OnStateChanged(AXTree* tree,
                       AXNode* node,
                       AXState state,
                       bool new_value) override {
-    attribute_change_log_.push_back(StringPrintf("%s changed to %s",
-                                                 ToString(state).c_str(),
-                                                 new_value ? "true" : "false"));
+    attribute_change_log_.push_back(StringPrintf(
+        "%s changed to %s", ToString(state), new_value ? "true" : "false"));
   }
 
   void OnStringAttributeChanged(AXTree* tree,
@@ -131,7 +129,7 @@
                                 const std::string& old_value,
                                 const std::string& new_value) override {
     attribute_change_log_.push_back(
-        StringPrintf("%s changed from %s to %s", ToString(attr).c_str(),
+        StringPrintf("%s changed from %s to %s", ToString(attr),
                      old_value.c_str(), new_value.c_str()));
   }
 
@@ -140,9 +138,8 @@
                              AXIntAttribute attr,
                              int32_t old_value,
                              int32_t new_value) override {
-    attribute_change_log_.push_back(StringPrintf("%s changed from %d to %d",
-                                                 ToString(attr).c_str(),
-                                                 old_value, new_value));
+    attribute_change_log_.push_back(StringPrintf(
+        "%s changed from %d to %d", ToString(attr), old_value, new_value));
   }
 
   void OnFloatAttributeChanged(AXTree* tree,
@@ -151,7 +148,7 @@
                                float old_value,
                                float new_value) override {
     attribute_change_log_.push_back(StringPrintf(
-        "%s changed from %s to %s", ToString(attr).c_str(),
+        "%s changed from %s to %s", ToString(attr),
         DoubleToString(old_value).c_str(), DoubleToString(new_value).c_str()));
   }
 
@@ -159,9 +156,8 @@
                               AXNode* node,
                               AXBoolAttribute attr,
                               bool new_value) override {
-    attribute_change_log_.push_back(StringPrintf("%s changed to %s",
-                                                 ToString(attr).c_str(),
-                                                 new_value ? "true" : "false"));
+    attribute_change_log_.push_back(StringPrintf(
+        "%s changed to %s", ToString(attr), new_value ? "true" : "false"));
   }
 
   void OnIntListAttributeChanged(
@@ -171,7 +167,7 @@
       const std::vector<int32_t>& old_value,
       const std::vector<int32_t>& new_value) override {
     attribute_change_log_.push_back(
-        StringPrintf("%s changed from %s to %s", ToString(attr).c_str(),
+        StringPrintf("%s changed from %s to %s", ToString(attr),
                      IntVectorToString(old_value).c_str(),
                      IntVectorToString(new_value).c_str()));
   }
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index a26d9af..e25c9ddf 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -391,9 +391,6 @@
   STDMETHODIMP get_relations(LONG max_relations,
                              IAccessibleRelation** relations,
                              LONG* n_relations) override;
-  //
-  // IAccessible2 methods not implemented.
-  //
 
   STDMETHODIMP get_attribute(BSTR name, VARIANT* attribute) override;
   STDMETHODIMP get_extendedRole(BSTR* extended_role) override;
diff --git a/ui/message_center/fake_message_center.cc b/ui/message_center/fake_message_center.cc
index c61176e..3a287b87 100644
--- a/ui/message_center/fake_message_center.cc
+++ b/ui/message_center/fake_message_center.cc
@@ -156,6 +156,4 @@
 
 void FakeMessageCenter::DisableTimersForTest() {}
 
-void FakeMessageCenter::EnableChangeQueueForTest(bool enabled) {}
-
 }  // namespace message_center
diff --git a/ui/message_center/fake_message_center.h b/ui/message_center/fake_message_center.h
index c489f67..d03befe 100644
--- a/ui/message_center/fake_message_center.h
+++ b/ui/message_center/fake_message_center.h
@@ -73,7 +73,6 @@
 
  protected:
   void DisableTimersForTest() override;
-  void EnableChangeQueueForTest(bool enabled) override;
 
  private:
   const NotificationList::Notifications empty_notifications_;
diff --git a/ui/message_center/message_center.h b/ui/message_center/message_center.h
index 2eebf0ff..8280ceff 100644
--- a/ui/message_center/message_center.h
+++ b/ui/message_center/message_center.h
@@ -208,19 +208,11 @@
   friend class TrayViewControllerTest;
   friend class test::MessagePopupCollectionTest;
   virtual void DisableTimersForTest() = 0;
-  virtual void EnableChangeQueueForTest(bool enabled) = 0;
 
   MessageCenter();
   virtual ~MessageCenter();
 
  private:
-  // Forces to flush the queued changes even when the message center opens. This
-  // method is a workaround of UpdateNotification not updating notifications
-  // while the message center.
-  // Note carefully: this may break the layout of message center. Shouldn't use
-  // this method if the update changes its notification size.
-  virtual void ForceNotificationFlush(const std::string& id) {}
-
   DISALLOW_COPY_AND_ASSIGN(MessageCenter);
 };
 
diff --git a/ui/message_center/message_center_impl.cc b/ui/message_center/message_center_impl.cc
index e2369ca..56602c6 100644
--- a/ui/message_center/message_center_impl.cc
+++ b/ui/message_center/message_center_impl.cc
@@ -27,309 +27,6 @@
 #include "ui/message_center/popup_timers_controller.h"
 
 namespace message_center {
-namespace internal {
-
-// ChangeQueue keeps track of all the changes that we need to make to the
-// notification list once the visibility is set to VISIBILITY_TRANSIENT.
-class ChangeQueue {
- public:
-  enum ChangeType {
-    CHANGE_TYPE_ADD = 0,
-    CHANGE_TYPE_UPDATE,
-    CHANGE_TYPE_DELETE
-  };
-
-  // Change represents an operation made on a notification.  Since it contains
-  // the final state of the notification, we only keep the last change for a
-  // particular notification that is in the notification list around.  There are
-  // two ids; |id_| is the newest notification id that has been assigned by an
-  // update, and |notification_list_id_| is the id of the notification it should
-  // be updating as it exists in the notification list.
-  class Change {
-   public:
-    Change(ChangeType type,
-           const std::string& id,
-           std::unique_ptr<Notification> notification);
-    ~Change();
-
-    // Used to transfer ownership of the contained notification.
-    std::unique_ptr<Notification> PassNotification();
-
-    Notification* notification() const { return notification_.get(); }
-    // Returns the post-update ID. It means:
-    // - ADD event: ID of the notification to be added.
-    // - UPDATE event: ID of the notification after the change. If the change
-    //   doesn't update its ID, this value is same as |notification_list_id|.
-    // - DELETE event: ID of the notification to be deleted.
-    const std::string& id() const { return id_; }
-    ChangeType type() const { return type_; }
-    bool by_user() const { return by_user_; }
-    void set_by_user(bool by_user) { by_user_ = by_user; }
-    // Returns the ID which is used in the notification list. In other word, it
-    // means the ID before the change.
-    const std::string& notification_list_id() const {
-      return notification_list_id_;
-    }
-    void set_type(const ChangeType new_type) {
-      type_ = new_type;
-    }
-    void ReplaceNotification(std::unique_ptr<Notification> new_notification);
-
-   private:
-    ChangeType type_;
-    std::string id_;
-    std::string notification_list_id_;
-    bool by_user_;
-    std::unique_ptr<Notification> notification_;
-
-    DISALLOW_COPY_AND_ASSIGN(Change);
-  };
-
-  ChangeQueue();
-  ~ChangeQueue();
-
-  // Called when the message center has appropriate visibility.  Modifies
-  // |message_center| but does not retain it.  This also causes the queue to
-  // empty itself.
-  void ApplyChanges(MessageCenterImpl* message_center);
-
-  // Applies only the changes of the given ID.
-  void ApplyChangesForId(MessageCenterImpl* message_center,
-                         const std::string& id);
-
-  // Causes a TYPE_ADD change to be added to the queue.
-  void AddNotification(std::unique_ptr<Notification> notification);
-
-  // Causes a TYPE_UPDATE change to be added to the queue.
-  void UpdateNotification(const std::string& old_id,
-                          std::unique_ptr<Notification> notification);
-
-  // Causes a TYPE_DELETE change to be added to the queue.
-  void EraseNotification(const std::string& id, bool by_user);
-
-  // Returns whether the queue matches an id.  The id given will be matched
-  // against the ID of all changes post-update, not the id of the notification
-  // as it stands in the notification list.
-  bool Has(const std::string& id) const;
-
-  // Returns a Change that can be modified by the caller.  ChangeQueue retains
-  // ownership of the Change; pointers should not be retained.
-  Notification* GetLatestNotification(const std::string& id) const;
-
- private:
-  void ApplyChangeInternal(MessageCenterImpl* message_center,
-                           std::unique_ptr<Change> change);
-
-  std::vector<std::unique_ptr<Change>> changes_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChangeQueue);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeFinder
-
-struct ChangeFinder {
-  explicit ChangeFinder(const std::string& id) : id(id) {}
-  bool operator()(const std::unique_ptr<ChangeQueue::Change>& change) {
-    return change->id() == id;
-  }
-
-  std::string id;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeQueue::Change
-
-ChangeQueue::Change::Change(ChangeType type,
-                            const std::string& id,
-                            std::unique_ptr<Notification> notification)
-    : type_(type),
-      notification_list_id_(id),
-      by_user_(false),
-      notification_(std::move(notification)) {
-  DCHECK(!id.empty());
-  DCHECK(type != CHANGE_TYPE_DELETE || !notification_);
-
-  id_ = notification_ ? notification_->id() : notification_list_id_;
-}
-
-ChangeQueue::Change::~Change() {}
-
-std::unique_ptr<Notification> ChangeQueue::Change::PassNotification() {
-  return std::move(notification_);
-}
-
-void ChangeQueue::Change::ReplaceNotification(
-    std::unique_ptr<Notification> new_notification) {
-  id_ = new_notification ? new_notification->id() : notification_list_id_;
-  notification_.swap(new_notification);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeQueue
-
-ChangeQueue::ChangeQueue() {}
-
-ChangeQueue::~ChangeQueue() {}
-
-void ChangeQueue::ApplyChanges(MessageCenterImpl* message_center) {
-  // This method is re-entrant.
-  while (!changes_.empty()) {
-    auto iter = changes_.begin();
-    std::unique_ptr<Change> change(std::move(*iter));
-    // TODO(dewittj): Replace changes_ with a deque.
-    changes_.erase(iter);
-    ApplyChangeInternal(message_center, std::move(change));
-  }
-}
-
-void ChangeQueue::ApplyChangesForId(MessageCenterImpl* message_center,
-                                    const std::string& id) {
-  std::deque<Change*> changes_for_id;
-  std::string interesting_id = id;
-
-  // Traverses the queue in reverse so shat we can track changes which change
-  // the notification's ID.
-  auto iter = changes_.end();
-  while (iter != changes_.begin()) {
-    --iter;
-    if (interesting_id != (*iter)->id())
-      continue;
-    std::unique_ptr<Change> change(std::move(*iter));
-
-    interesting_id = change->notification_list_id();
-
-    iter = changes_.erase(iter);
-    changes_for_id.push_back(change.release());
-  }
-
-  while (!changes_for_id.empty()) {
-    ApplyChangeInternal(message_center,
-                        std::unique_ptr<Change>(changes_for_id.back()));
-    changes_for_id.pop_back();
-  }
-}
-
-void ChangeQueue::AddNotification(std::unique_ptr<Notification> notification) {
-  std::string id = notification->id();
-  changes_.push_back(
-      base::MakeUnique<Change>(CHANGE_TYPE_ADD, id, std::move(notification)));
-}
-
-void ChangeQueue::UpdateNotification(
-    const std::string& old_id,
-    std::unique_ptr<Notification> notification) {
-  auto iter =
-      std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(old_id));
-  if (iter == changes_.rend()) {
-    changes_.push_back(base::MakeUnique<Change>(CHANGE_TYPE_UPDATE, old_id,
-                                                std::move(notification)));
-    return;
-  }
-
-  Change* change = iter->get();
-  switch (change->type()) {
-    case CHANGE_TYPE_ADD: {
-      std::string id = notification->id();
-      // Needs to add the change at the last, because if this change updates
-      // its ID, some previous changes may affect new ID.
-      // (eg. Add A, Update B->C, and This update A->B).
-      changes_.erase(--(iter.base()));
-      changes_.push_back(base::MakeUnique<Change>(CHANGE_TYPE_ADD, id,
-                                                  std::move(notification)));
-      break;
-    }
-    case CHANGE_TYPE_UPDATE:
-      if (notification->id() == old_id) {
-        // Safe to place the change at the previous place.
-        change->ReplaceNotification(std::move(notification));
-      } else if (change->id() == change->notification_list_id()) {
-        std::string id = notification->id();
-        // Safe to place the change at the last.
-        changes_.erase(--(iter.base()));
-        changes_.push_back(base::MakeUnique<Change>(CHANGE_TYPE_ADD, id,
-                                                    std::move(notification)));
-      } else {
-        // Complex case: gives up to optimize.
-        changes_.push_back(base::MakeUnique<Change>(CHANGE_TYPE_UPDATE, old_id,
-                                                    std::move(notification)));
-      }
-      break;
-    case CHANGE_TYPE_DELETE:
-      // DELETE -> UPDATE. Something is wrong. Treats the UPDATE as ADD.
-      changes_.push_back(base::MakeUnique<Change>(CHANGE_TYPE_ADD, old_id,
-                                                  std::move(notification)));
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-void ChangeQueue::EraseNotification(const std::string& id, bool by_user) {
-  auto iter =
-      std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(id));
-  if (iter == changes_.rend()) {
-    auto change = base::MakeUnique<Change>(CHANGE_TYPE_DELETE, id, nullptr);
-    change->set_by_user(by_user);
-    changes_.push_back(std::move(change));
-    return;
-  }
-
-  Change* change = iter->get();
-  switch (change->type()) {
-    case CHANGE_TYPE_ADD:
-      // ADD -> DELETE. Just removes both.
-      changes_.erase(--(iter.base()));
-      break;
-    case CHANGE_TYPE_UPDATE:
-      // UPDATE -> DELETE. Changes the previous UPDATE to DELETE.
-      change->set_type(CHANGE_TYPE_DELETE);
-      change->set_by_user(by_user);
-      change->ReplaceNotification(nullptr);
-      break;
-    case CHANGE_TYPE_DELETE:
-      // DELETE -> DELETE. Something is wrong. Combines them with overriding
-      // the |by_user| flag.
-      change->set_by_user(!change->by_user() && by_user);
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-bool ChangeQueue::Has(const std::string& id) const {
-  auto iter = std::find_if(changes_.begin(), changes_.end(), ChangeFinder(id));
-  return iter != changes_.end();
-}
-
-Notification* ChangeQueue::GetLatestNotification(const std::string& id) const {
-  auto iter = std::find_if(changes_.begin(), changes_.end(), ChangeFinder(id));
-  if (iter == changes_.end())
-    return NULL;
-
-  return (*iter)->notification();
-}
-
-void ChangeQueue::ApplyChangeInternal(MessageCenterImpl* message_center,
-                                      std::unique_ptr<Change> change) {
-  switch (change->type()) {
-    case CHANGE_TYPE_ADD:
-      message_center->AddNotificationImmediately(change->PassNotification());
-      break;
-    case CHANGE_TYPE_UPDATE:
-      message_center->UpdateNotificationImmediately(
-          change->notification_list_id(), change->PassNotification());
-      break;
-    case CHANGE_TYPE_DELETE:
-      message_center->RemoveNotificationImmediately(
-          change->notification_list_id(), change->by_user());
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-}  // namespace internal
 
 ////////////////////////////////////////////////////////////////////////////////
 // MessageCenterImpl::NotificationCache
@@ -361,19 +58,6 @@
       popup_timers_controller_(new PopupTimersController(this)),
       settings_provider_(NULL) {
   notification_list_.reset(new NotificationList(this));
-
-  bool enable_message_center_changes_while_open = true;  // enable by default
-  std::string arg = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-      switches::kMessageCenterChangesWhileOpen);
-  if (!arg.empty()) {
-    if (arg == "enabled")
-      enable_message_center_changes_while_open = true;
-    else if (arg == "disabled")
-      enable_message_center_changes_while_open = false;
-  }
-
-  if (!enable_message_center_changes_while_open)
-    notification_queue_.reset(new internal::ChangeQueue());
 }
 
 MessageCenterImpl::~MessageCenterImpl() {
@@ -466,11 +150,6 @@
     }
   }
 
-  if (notification_queue_ &&
-      visibility == VISIBILITY_TRANSIENT) {
-    notification_queue_->ApplyChanges(this);
-  }
-
   for (auto& observer : observer_list_)
     observer.OnCenterVisibilityChanged(visibility);
 }
@@ -531,12 +210,6 @@
   return notification_list_->GetPopupNotifications(blockers_, NULL);
 }
 
-void MessageCenterImpl::ForceNotificationFlush(const std::string& id) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (notification_queue_)
-    notification_queue_->ApplyChangesForId(this, id);
-}
-
 //------------------------------------------------------------------------------
 // Client code interface.
 void MessageCenterImpl::AddNotification(
@@ -547,11 +220,6 @@
   for (size_t i = 0; i < blockers_.size(); ++i)
     blockers_[i]->CheckState();
 
-  if (notification_queue_ && visible_) {
-    notification_queue_->AddNotification(std::move(notification));
-    return;
-  }
-
   AddNotificationImmediately(std::move(notification));
 }
 
@@ -584,30 +252,6 @@
   for (size_t i = 0; i < blockers_.size(); ++i)
     blockers_[i]->CheckState();
 
-  if (notification_queue_ && visible_) {
-    // We will allow notifications that are progress types (and stay progress
-    // types) to be updated even if the message center is open.  There are 3
-    // requirements here:
-    //  * Notification of type PROGRESS exists with same ID in the center
-    //  * There are no queued updates for this notification (they imply a change
-    //    that violates the PROGRESS invariant
-    //  * The new notification is type PROGRESS.
-    // TODO(dewittj): Ensure this works when the ID is changed by the caller.
-    // This shouldn't be an issue in practice since only W3C notifications
-    // change the ID on update, and they don't have progress type notifications.
-    bool update_keeps_progress_type =
-        new_notification->type() == NOTIFICATION_TYPE_PROGRESS &&
-        !notification_queue_->Has(old_id) &&
-        notification_list_->HasNotificationOfType(old_id,
-                                                  NOTIFICATION_TYPE_PROGRESS);
-    if (!update_keeps_progress_type) {
-      // Updates are allowed only for progress notifications.
-      notification_queue_->UpdateNotification(old_id,
-                                              std::move(new_notification));
-      return;
-    }
-  }
-
   UpdateNotificationImmediately(old_id, std::move(new_notification));
 }
 
@@ -634,11 +278,6 @@
 void MessageCenterImpl::RemoveNotification(const std::string& id,
                                            bool by_user) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (notification_queue_ && !by_user && visible_) {
-    notification_queue_->EraseNotification(id, by_user);
-    return;
-  }
-
   RemoveNotificationImmediately(id, by_user);
 }
 
@@ -717,20 +356,7 @@
 void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
                                             const gfx::Image& image) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  bool updated = false;
-  Notification* queue_notification =
-      notification_queue_
-          ? notification_queue_->GetLatestNotification(notification_id)
-          : NULL;
-
-  if (queue_notification) {
-    queue_notification->set_icon(image);
-    updated = true;
-  } else {
-    updated = notification_list_->SetNotificationIcon(notification_id, image);
-  }
-
-  if (updated) {
+  if (notification_list_->SetNotificationIcon(notification_id, image)) {
     for (auto& observer : observer_list_)
       observer.OnNotificationUpdated(notification_id);
   }
@@ -739,20 +365,7 @@
 void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
                                              const gfx::Image& image) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  bool updated = false;
-  Notification* queue_notification =
-      notification_queue_
-          ? notification_queue_->GetLatestNotification(notification_id)
-          : NULL;
-
-  if (queue_notification) {
-    queue_notification->set_image(image);
-    updated = true;
-  } else {
-    updated = notification_list_->SetNotificationImage(notification_id, image);
-  }
-
-  if (updated) {
+  if (notification_list_->SetNotificationImage(notification_id, image)) {
     for (auto& observer : observer_list_)
       observer.OnNotificationUpdated(notification_id);
   }
@@ -762,21 +375,8 @@
     const std::string& notification_id, int button_index,
     const gfx::Image& image) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  bool updated = false;
-  Notification* queue_notification =
-      notification_queue_
-          ? notification_queue_->GetLatestNotification(notification_id)
-          : NULL;
-
-  if (queue_notification) {
-    queue_notification->SetButtonIcon(button_index, image);
-    updated = true;
-  } else {
-    updated = notification_list_->SetNotificationButtonIcon(
-        notification_id, button_index, image);
-  }
-
-  if (updated) {
+  if (notification_list_->SetNotificationButtonIcon(notification_id,
+                                                    button_index, image)) {
     for (auto& observer : observer_list_)
       observer.OnNotificationUpdated(notification_id);
   }
@@ -957,11 +557,4 @@
   popup_timers_controller_.reset();
 }
 
-void MessageCenterImpl::EnableChangeQueueForTest(bool enable) {
-  if (enable)
-    notification_queue_.reset(new internal::ChangeQueue());
-  else
-    notification_queue_.reset();
-}
-
 }  // namespace message_center
diff --git a/ui/message_center/message_center_impl.h b/ui/message_center/message_center_impl.h
index ea4348a3..4c176c5 100644
--- a/ui/message_center/message_center_impl.h
+++ b/ui/message_center/message_center_impl.h
@@ -24,11 +24,6 @@
 #include "ui/message_center/popup_timers_controller.h"
 
 namespace message_center {
-class MessageCenterImpl;
-
-namespace internal {
-class ChangeQueue;
-}
 
 // The default implementation of MessageCenter.
 class MessageCenterImpl : public MessageCenter,
@@ -86,7 +81,6 @@
   void PausePopupTimers() override;
   const base::string16& GetProductOSName() const override;
   void SetProductOSName(const base::string16& product_os_name) override;
-  void ForceNotificationFlush(const std::string& id) override;
 
   // NotificationBlocker::Observer overrides:
   void OnBlockingStateChanged(NotificationBlocker* blocker) override;
@@ -107,7 +101,6 @@
 
  protected:
   void DisableTimersForTest() override;
-  void EnableChangeQueueForTest(bool enable) override;
 
  private:
   struct NotificationCache {
@@ -135,10 +128,6 @@
   bool locked_ = false;
   bool visible_ = false;
 
-  // Queue for the notifications to delay the addition/updates when the message
-  // center is visible.
-  std::unique_ptr<internal::ChangeQueue> notification_queue_;
-
   base::string16 product_os_name_;
 
   DISALLOW_COPY_AND_ASSIGN(MessageCenterImpl);
diff --git a/ui/message_center/message_center_impl_unittest.cc b/ui/message_center/message_center_impl_unittest.cc
index 3ed12ed..9b299b1 100644
--- a/ui/message_center/message_center_impl_unittest.cc
+++ b/ui/message_center/message_center_impl_unittest.cc
@@ -97,10 +97,6 @@
                             optional_fields, NULL);
   }
 
-  void ForceNotificationFlush(const std::string& id) {
-    message_center()->ForceNotificationFlush(id);
-  }
-
  private:
   MessageCenter* message_center_;
   std::unique_ptr<base::MessageLoop> loop_;
@@ -110,34 +106,6 @@
   DISALLOW_COPY_AND_ASSIGN(MessageCenterImplTest);
 };
 
-class MessageCenterImplTestWithChangeQueue : public MessageCenterImplTest {
- public:
-  MessageCenterImplTestWithChangeQueue() {}
-  ~MessageCenterImplTestWithChangeQueue() override {}
-
-  void SetUp() override {
-    MessageCenterImplTest::SetUp();
-    message_center()->EnableChangeQueueForTest(true);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageCenterImplTestWithChangeQueue);
-};
-
-class MessageCenterImplTestWithoutChangeQueue : public MessageCenterImplTest {
- public:
-  MessageCenterImplTestWithoutChangeQueue() {}
-  ~MessageCenterImplTestWithoutChangeQueue() override {}
-
-  void SetUp() override {
-    MessageCenterImplTest::SetUp();
-    message_center()->EnableChangeQueueForTest(false);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageCenterImplTestWithoutChangeQueue);
-};
-
 namespace {
 
 class ToggledNotificationBlocker : public NotificationBlocker {
@@ -707,39 +675,6 @@
 }
 #endif  // OS_CHROMEOS
 
-TEST_F(MessageCenterImplTest, ForceNotificationFlush_InconsistentUpdate) {
-  std::string id1("id1");
-  std::string id2("id2");
-  std::string id3("id3");
-
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // Add -> Update (with ID change)
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id1));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->UpdateNotification(id1, std::move(notification));
-
-  // Add (although the same ID exists) -> Update (with ID change) -> Remove
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(id3));
-  message_center()->UpdateNotification(id2, std::move(notification));
-  message_center()->RemoveNotification(id3, false);
-
-  // Remove (although the ID has already removed)
-  message_center()->RemoveNotification(id3, false);
-
-  // Notification is not added since the message center has opened.
-  ASSERT_EQ(0u, message_center()->NotificationCount());
-
-  // Forced to update.
-  ForceNotificationFlush(id3);
-
-  // Confirms the chagnes are applied.
-  ASSERT_EQ(0u, message_center()->NotificationCount());
-}
-
 TEST_F(MessageCenterImplTest, DisableNotificationsByNotifier) {
   ASSERT_EQ(0u, message_center()->NotificationCount());
   message_center()->AddNotification(std::unique_ptr<Notification>(
@@ -806,413 +741,7 @@
   ASSERT_EQ(0u, message_center()->NotificationCount());
 }
 
-TEST_F(MessageCenterImplTestWithChangeQueue, QueueUpdatesWithCenterVisible) {
-  std::string id("id1");
-  std::string id2("id2");
-  NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
-  // First, add and update a notification to ensure updates happen
-  // normally.
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->UpdateNotification(id, std::move(notification));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
-  // Then open the message center.
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // Then update a notification; nothing should have happened.
-  notification.reset(CreateSimpleNotification(id));
-  message_center()->UpdateNotification(id2, std::move(notification));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
-  // Close the message center; then the update should have propagated.
-  message_center()->SetVisibility(VISIBILITY_TRANSIENT);
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue, ComplexQueueing) {
-  std::string ids[6] = {"0", "1", "2", "3", "4p", "5"};
-  NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
-  std::unique_ptr<Notification> notification;
-  // Add some notifications
-  int i = 0;
-  for (; i < 3; i++) {
-    notification.reset(CreateSimpleNotification(ids[i]));
-    message_center()->AddNotification(std::move(notification));
-  }
-  for (i = 0; i < 3; i++) {
-    EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
-  }
-  for (; i < 6; i++) {
-    EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
-  }
-
-  notification.reset(CreateNotification(ids[4], NOTIFICATION_TYPE_PROGRESS));
-  message_center()->AddNotification(std::move(notification));
-
-  // Now start queueing.
-  // NL: ["0", "1", "2", "4p"]
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // This should update notification "1" to have id "3".
-  notification.reset(CreateSimpleNotification(ids[3]));
-  message_center()->UpdateNotification(ids[1], std::move(notification));
-
-  // Change the ID: "4p" -> "5", "5" -> "1", "1" -> "4p". They shouldn't
-  // override the previous change ("1" -> "3") nor the next one ("3" -> "5").
-  notification.reset(CreateSimpleNotification(ids[5]));
-  message_center()->UpdateNotification(ids[4], std::move(notification));
-  notification.reset(CreateSimpleNotification(ids[1]));
-  message_center()->UpdateNotification(ids[5], std::move(notification));
-  notification.reset(CreateNotification(ids[4], NOTIFICATION_TYPE_PROGRESS));
-  message_center()->UpdateNotification(ids[1], std::move(notification));
-
-  // This should update notification "3" to "5" after we go TRANSIENT.
-  notification.reset(CreateSimpleNotification(ids[5]));
-  message_center()->UpdateNotification(ids[3], std::move(notification));
-
-  // This should create a new "3", that doesn't overwrite the update to 3
-  // before.
-  notification.reset(CreateSimpleNotification(ids[3]));
-  message_center()->AddNotification(std::move(notification));
-
-  // The NL should still be the same: ["0", "1", "2", "4p"]
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[3]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[5]));
-  EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 4u);
-  message_center()->SetVisibility(VISIBILITY_TRANSIENT);
-
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
-  EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue, UpdateWhileQueueing) {
-  std::string ids[11] =
-      {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10p"};
-  NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
-  std::unique_ptr<Notification> notification;
-  // Add some notifications
-  int i = 0;
-  for (; i < 6; i++) {
-    notification.reset(CreateSimpleNotification(ids[i]));
-    notification->set_title(base::ASCIIToUTF16("ORIGINAL TITLE"));
-    message_center()->AddNotification(std::move(notification));
-  }
-  for (i = 0; i < 6; i++) {
-    EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
-  }
-  for (; i < 8; i++) {
-    EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
-  }
-
-  notification.reset(CreateNotification(ids[10], NOTIFICATION_TYPE_PROGRESS));
-  notification->set_progress(10);
-  message_center()->AddNotification(std::move(notification));
-
-  // Now start queueing.
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // Notification 0: (Exists) -> Removed
-  message_center()->RemoveNotification(ids[0], false);
-
-  // Notification 1: (Exists) -> Removed (by user)
-  message_center()->RemoveNotification(ids[1], true);  // removed immediately
-
-  // Notification 2: (Exists) -> Removed -> Added
-  message_center()->RemoveNotification(ids[2], false);
-  notification.reset(CreateSimpleNotification(ids[2]));
-  notification->set_title(base::ASCIIToUTF16("NEW TITLE 2"));
-  message_center()->UpdateNotification(ids[2], std::move(notification));
-
-  // Notification 3: (Exists) -> Removed -> Updated
-  message_center()->RemoveNotification(ids[3], false);
-  notification.reset(CreateSimpleNotification(ids[3]));
-  notification->set_title(base::ASCIIToUTF16("NEW TITLE 3"));
-  message_center()->UpdateNotification(ids[3], std::move(notification));
-
-  // Notification 4: (Exists) -> Removed -> Added -> Removed
-  message_center()->RemoveNotification(ids[4], false);
-  notification.reset(CreateSimpleNotification(ids[4]));
-  message_center()->AddNotification(std::move(notification));
-  message_center()->RemoveNotification(ids[4], false);
-
-  // Notification 5: (Exists) -> Updated
-  notification.reset(CreateSimpleNotification(ids[5]));
-  notification->set_title(base::ASCIIToUTF16("NEW TITLE 5"));
-  message_center()->UpdateNotification(ids[5], std::move(notification));
-
-  // Notification 6: Updated
-  notification.reset(CreateSimpleNotification(ids[6]));
-  message_center()->UpdateNotification(ids[6], std::move(notification));
-
-  // Notification 7: Updated -> Removed
-  notification.reset(CreateSimpleNotification(ids[7]));
-  message_center()->UpdateNotification(ids[7], std::move(notification));
-  message_center()->RemoveNotification(ids[7], false);
-
-  // Notification 8: Added -> Updated
-  notification.reset(CreateSimpleNotification(ids[8]));
-  notification->set_title(base::ASCIIToUTF16("UPDATING 8-1"));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(ids[8]));
-  notification->set_title(base::ASCIIToUTF16("NEW TITLE 8"));
-  message_center()->UpdateNotification(ids[8], std::move(notification));
-
-  // Notification 9: Added -> Updated -> Removed
-  notification.reset(CreateSimpleNotification(ids[9]));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(ids[9]));
-  message_center()->UpdateNotification(ids[9], std::move(notification));
-  message_center()->RemoveNotification(ids[9], false);
-
-  // Notification 10 (TYPE_PROGRESS): Updated -> Removed -> Added -> Updated
-  // Step 1) Progress is updated immediately before removed.
-  notification.reset(CreateNotification(ids[10], NOTIFICATION_TYPE_PROGRESS));
-  notification->set_progress(20);
-  message_center()->UpdateNotification(ids[10], std::move(notification));
-  EXPECT_EQ(20,
-            message_center()->FindVisibleNotificationById(ids[10])->progress());
-  message_center()->RemoveNotification(ids[10], false);
-  // Step 2) Progress isn't updated after removed.
-  notification.reset(CreateSimpleNotification(ids[10]));
-  message_center()->AddNotification(std::move(notification));
-  EXPECT_EQ(20,
-            message_center()->FindVisibleNotificationById(ids[10])->progress());
-  notification.reset(CreateSimpleNotification(ids[10]));
-  notification->set_progress(40);
-  message_center()->UpdateNotification(ids[10], std::move(notification));
-  EXPECT_EQ(20,
-            message_center()->FindVisibleNotificationById(ids[10])->progress());
-
-  // All changes except the notification 1 and 10 are not refrected.
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
-  EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
-            message_center()->FindVisibleNotificationById(ids[0])->title());
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
-  EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
-            message_center()->FindVisibleNotificationById(ids[2])->title());
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
-  EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
-            message_center()->FindVisibleNotificationById(ids[3])->title());
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
-  EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
-            message_center()->FindVisibleNotificationById(ids[4])->title());
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
-  EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
-            message_center()->FindVisibleNotificationById(ids[5])->title());
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[6]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[7]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[8]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[9]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[10]));
-  EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 6u);
-
-  message_center()->SetVisibility(VISIBILITY_TRANSIENT);
-
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[0]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
-  EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 2"),
-            message_center()->FindVisibleNotificationById(ids[2])->title());
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
-  EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 3"),
-            message_center()->FindVisibleNotificationById(ids[3])->title());
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[4]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
-  EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 5"),
-            message_center()->FindVisibleNotificationById(ids[5])->title());
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[6]));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[7]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[8]));
-  EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 8"),
-            message_center()->FindVisibleNotificationById(ids[8])->title());
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[9]));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[10]));
-  EXPECT_EQ(40,
-            message_center()->FindVisibleNotificationById(ids[10])->progress());
-  EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue, QueuedDirectUpdates) {
-  std::string id("id1");
-  std::string id2("id2");
-  NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
-  gfx::Size original_size(0, 0);
-  // Open the message center to prevent adding notifications
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // Create new notification to be added to the queue; images all have the same
-  // original size.
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
-
-  // Double-check that sizes all match.
-  const std::vector<ButtonInfo>& original_buttons = notification->buttons();
-  ASSERT_EQ(2u, original_buttons.size());
-
-  EXPECT_EQ(original_size, notification->icon().Size());
-  EXPECT_EQ(original_size, notification->image().Size());
-  EXPECT_EQ(original_size, original_buttons[0].icon.Size());
-  EXPECT_EQ(original_size, original_buttons[1].icon.Size());
-
-  message_center()->AddNotification(std::move(notification));
-
-  // The notification should be in the queue.
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
-  // Now try setting the icon to a different size.
-  gfx::Size new_size(16, 16);
-  EXPECT_NE(original_size, new_size);
-
-  SkBitmap bitmap;
-  bitmap.allocN32Pixels(new_size.width(), new_size.height(), true);
-  SkCanvas canvas(bitmap);
-  canvas.drawColor(SK_ColorBLUE);
-  gfx::Image test_image(
-      gfx::Image(gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, 1.f))));
-  message_center()->SetNotificationIcon(id, test_image);
-  message_center()->SetNotificationImage(id, test_image);
-  message_center()->SetNotificationButtonIcon(id, 0, test_image);
-  message_center()->SetNotificationButtonIcon(id, 1, test_image);
-
-  // The notification should be in the queue.
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
-  // Close the message center; then the update should have propagated.
-  message_center()->SetVisibility(VISIBILITY_TRANSIENT);
-  // The notification should no longer be in the queue.
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-
-  Notification* mc_notification =
-      *(message_center()->GetVisibleNotifications().begin());
-  const std::vector<ButtonInfo>& buttons = mc_notification->buttons();
-  ASSERT_EQ(2u, buttons.size());
-
-  EXPECT_EQ(new_size, mc_notification->icon().Size());
-  EXPECT_EQ(new_size, mc_notification->image().Size());
-  EXPECT_EQ(new_size, buttons[0].icon.Size());
-  EXPECT_EQ(new_size, buttons[1].icon.Size());
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue, ForceNotificationFlushAdd) {
-  std::string id("id1");
-
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-  message_center()->AddNotification(
-      std::unique_ptr<Notification>(CreateSimpleNotification(id)));
-
-  // Notification is not added yet.
-  ASSERT_EQ(0u, message_center()->NotificationCount());
-  // Forced to update.
-  ForceNotificationFlush(id);
-  // Notification is added.
-  ASSERT_EQ(1u, message_center()->NotificationCount());
-}
-
-
-TEST_F(MessageCenterImplTestWithChangeQueue, ForceNotificationFlushUpdate) {
-  std::string id("id1");
-  std::string id2("id2");
-
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
-  message_center()->AddNotification(std::move(notification));
-
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->UpdateNotification(id, std::move(notification));
-
-  // Nothing is changed.
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-
-  // Forced to update ID1.
-  ForceNotificationFlush(id);
-
-  // Nothing is changed, since the ID is changed.
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-
-  // Forced to update ID2.
-  ForceNotificationFlush(id2);
-
-  // The ID is changed.
-  EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
-  EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
-  // Makes sure if there is only one notification.
-  ASSERT_EQ(1u, message_center()->NotificationCount());
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue, ForceNotificationFlushRemove) {
-  std::string id("id1");
-
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
-  message_center()->AddNotification(std::move(notification));
-
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-  message_center()->RemoveNotification(id, false);
-
-  // Notification is not removed yet.
-  ASSERT_EQ(1u, message_center()->NotificationCount());
-
-  // Forced to update.
-  ForceNotificationFlush(id);
-
-  // Notification is removed.
-  ASSERT_EQ(0u, message_center()->NotificationCount());
-}
-
-TEST_F(MessageCenterImplTestWithChangeQueue,
-       ForceNotificationFlush_ComplexUpdate) {
-  std::string id1("id1");
-  std::string id2("id2");
-  std::string id3("id3");
-
-  message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
-
-  // Add -> Update (with ID change) -> Remove
-  std::unique_ptr<Notification> notification(CreateSimpleNotification(id1));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->UpdateNotification(id1, std::move(notification));
-  message_center()->RemoveNotification(id2, false);
-
-  // Add -> Update (with ID change)
-  notification.reset(CreateSimpleNotification(id2));
-  message_center()->AddNotification(std::move(notification));
-  notification.reset(CreateSimpleNotification(id3));
-  message_center()->UpdateNotification(id2, std::move(notification));
-
-  // Notification is not added since the message center has opened.
-  ASSERT_EQ(0u, message_center()->NotificationCount());
-
-  // Forced to update.
-  ForceNotificationFlush(id3);
-
-  // Confirms the chagnes are applied.
-  ASSERT_EQ(1u, message_center()->NotificationCount());
-}
-
-TEST_F(MessageCenterImplTestWithoutChangeQueue,
-       UpdateWhileMessageCenterVisible) {
+TEST_F(MessageCenterImplTest, UpdateWhileMessageCenterVisible) {
   std::string id("id1");
   std::string id2("id2");
   NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
@@ -1236,7 +765,7 @@
   EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
 }
 
-TEST_F(MessageCenterImplTestWithoutChangeQueue, AddWhileMessageCenterVisible) {
+TEST_F(MessageCenterImplTest, AddWhileMessageCenterVisible) {
   std::string id("id1");
 
   // Then open the message center.
@@ -1248,8 +777,7 @@
   EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
 }
 
-TEST_F(MessageCenterImplTestWithoutChangeQueue,
-       RemoveWhileMessageCenterVisible) {
+TEST_F(MessageCenterImplTest, RemoveWhileMessageCenterVisible) {
   std::string id("id1");
 
   // First, add a notification to ensure updates happen normally.
diff --git a/ui/message_center/message_center_switches.cc b/ui/message_center/message_center_switches.cc
index 44f45888..9dd2d74 100644
--- a/ui/message_center/message_center_switches.cc
+++ b/ui/message_center/message_center_switches.cc
@@ -12,11 +12,6 @@
 const char kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval[] =
     "enable-message-center-always-scroll-up-upon-notification-removal";
 
-// Flag to enable or disable notification changes while the message center
-// opens. This flag will be removed once the feature gets stable.
-const char kMessageCenterChangesWhileOpen[] =
-    "message-center-changes-while-open";
-
 // Flag to enable or disable new-style notification. This flag will be removed
 // once the feature gets stable.
 const char kEnableMessageCenterNewStyleNotification[] =
diff --git a/ui/message_center/message_center_switches.h b/ui/message_center/message_center_switches.h
index 8093b6c..3f3401ee 100644
--- a/ui/message_center/message_center_switches.h
+++ b/ui/message_center/message_center_switches.h
@@ -13,11 +13,6 @@
 MESSAGE_CENTER_EXPORT extern const char
     kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval[];
 
-// Flag to enable or disable notification changes while the message center
-// opens.  Possible values are "" (meant default), "enabled" or "disabled".
-// This flag will be removed once the feature gets stable.
-MESSAGE_CENTER_EXPORT extern const char kMessageCenterChangesWhileOpen[];
-
 MESSAGE_CENTER_EXPORT extern const char
     kEnableMessageCenterNewStyleNotification[];
 MESSAGE_CENTER_EXPORT extern const char
diff --git a/ui/message_center/message_center_tray_unittest.cc b/ui/message_center/message_center_tray_unittest.cc
index 6c4212d8..e8ddd923 100644
--- a/ui/message_center/message_center_tray_unittest.cc
+++ b/ui/message_center/message_center_tray_unittest.cc
@@ -75,10 +75,6 @@
     AddNotification(id, DummyNotifierId());
   }
 
-  void EnableChangeQueue(bool enabled) {
-    message_center_->EnableChangeQueueForTest(enabled);
-  }
-
   void AddNotification(const std::string& id, NotifierId notifier_id) {
     std::unique_ptr<Notification> notification(new Notification(
         message_center::NOTIFICATION_TYPE_SIMPLE, id,
@@ -143,8 +139,6 @@
 }
 
 TEST_F(MessageCenterTrayTest, MessageCenterClosesPopups) {
-  EnableChangeQueue(false);
-
   ASSERT_FALSE(message_center_tray_->popups_visible());
   ASSERT_FALSE(message_center_tray_->message_center_visible());
 
@@ -179,44 +173,6 @@
   ASSERT_FALSE(message_center_tray_->message_center_visible());
 }
 
-// TODO(yoshiki): Remove this test after no-change-queue mode gets stable.
-TEST_F(MessageCenterTrayTest, MessageCenterClosesPopupsWithChangeQueue) {
-  EnableChangeQueue(true);
-
-  ASSERT_FALSE(message_center_tray_->popups_visible());
-  ASSERT_FALSE(message_center_tray_->message_center_visible());
-
-  AddNotification("MessageCenterClosesPopups");
-
-  ASSERT_TRUE(message_center_tray_->popups_visible());
-  ASSERT_FALSE(message_center_tray_->message_center_visible());
-
-  bool shown = message_center_tray_->ShowMessageCenterBubble();
-  EXPECT_TRUE(shown);
-
-  ASSERT_FALSE(message_center_tray_->popups_visible());
-  ASSERT_TRUE(message_center_tray_->message_center_visible());
-
-  // The notification is queued if it's added when message center is visible.
-  AddNotification("MessageCenterClosesPopups2");
-
-  message_center_tray_->ShowPopupBubble();
-
-  ASSERT_FALSE(message_center_tray_->popups_visible());
-  ASSERT_TRUE(message_center_tray_->message_center_visible());
-
-  message_center_tray_->HideMessageCenterBubble();
-
-  // The queued notification appears as a popup.
-  ASSERT_TRUE(message_center_tray_->popups_visible());
-  ASSERT_FALSE(message_center_tray_->message_center_visible());
-
-  message_center_tray_->ShowMessageCenterBubble();
-  message_center_tray_->HideMessageCenterBubble();
-  ASSERT_FALSE(message_center_tray_->popups_visible());
-  ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
 TEST_F(MessageCenterTrayTest, MessageCenterReopenPopupsForSystemPriority) {
   ASSERT_FALSE(message_center_tray_->popups_visible());
   ASSERT_FALSE(message_center_tray_->message_center_visible());