diff --git a/DEPS b/DEPS
index fda3638..aafd160 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '3261eb219f2cbb027d6876bc99b243fe0b3c7ee3',
+  'skia_revision': 'a8e5744afadd20e217a7c70099a79a222d2e7e4f',
   # 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': '3233811b2cc7bc0291685d865801a12b8af346fd',
+  'v8_revision': '6bdbb1f107c74e442f7ce11d281643c1632ababa',
   # 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.
@@ -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': 'c59db25d81163ca4f159fbbcdaedad459d6f2a0d',
+  'catapult_revision': 'd5df04f53ce84b12550e46a8a9d5ff496d73bb01',
   # 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/chrome/VERSION b/chrome/VERSION
index 8df4841..906bad2 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=63
 MINOR=0
-BUILD=3213
+BUILD=3214
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java
index 799da81..ff1bffb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java
@@ -11,7 +11,7 @@
  * Basic factory that creates and returns an {@link OfflineContentProvider} that is attached
  * natively to {@link Profile}.
  */
-class OfflineContentAggregatorFactory {
+public class OfflineContentAggregatorFactory {
     private OfflineContentAggregatorFactory() {}
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
index 3e98b21..0333286 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
@@ -22,17 +22,23 @@
 import org.chromium.chrome.browser.download.DownloadItem;
 import org.chromium.chrome.browser.download.DownloadSharedPreferenceHelper;
 import org.chromium.chrome.browser.download.DownloadUtils;
+import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
 import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate;
 import org.chromium.chrome.browser.download.ui.BackendProvider.OfflinePageDelegate;
 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.DownloadItemWrapper;
+import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflineItemWrapper;
 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflinePageItemWrapper;
 import org.chromium.chrome.browser.download.ui.DownloadManagerUi.DownloadUiObserver;
 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge;
 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.widget.DateDividedAdapter;
 import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
 import org.chromium.components.offline_items_collection.ContentId;
+import org.chromium.components.offline_items_collection.OfflineContentProvider;
+import org.chromium.components.offline_items_collection.OfflineItem;
+import org.chromium.components.offline_items_collection.OfflineItemState;
 import org.chromium.content_public.browser.DownloadState;
 
 import java.util.ArrayList;
@@ -47,13 +53,16 @@
 
 /** Bridges the user's download history and the UI used to display it. */
 public class DownloadHistoryAdapter extends DateDividedAdapter
-        implements DownloadUiObserver, DownloadSharedPreferenceHelper.Observer {
+        implements DownloadUiObserver, DownloadSharedPreferenceHelper.Observer,
+                   OfflineContentProvider.Observer {
     private static final String TAG = "DownloadAdapter";
 
     /** Alerted about changes to internal state. */
     static interface TestObserver {
         abstract void onDownloadItemCreated(DownloadItem item);
         abstract void onDownloadItemUpdated(DownloadItem item);
+        abstract void onOfflineItemCreated(OfflineItem item);
+        abstract void onOfflineItemUpdated(OfflineItem item);
     }
 
     private class BackendItemsImpl extends BackendItems {
@@ -150,6 +159,7 @@
     private final BackendItems mRegularDownloadItems = new BackendItemsImpl();
     private final BackendItems mIncognitoDownloadItems = new BackendItemsImpl();
     private final BackendItems mOfflinePageItems = new BackendItemsImpl();
+    private final BackendItems mOfflineItems = new BackendItemsImpl();
 
     private final FilePathsToDownloadItemsMap mFilePathsToItemsMap =
             new FilePathsToDownloadItemsMap();
@@ -205,12 +215,19 @@
 
         initializeOfflinePageBridge();
 
+        getOfflineContentProvider().addObserver(this);
+
         sDeletedFileTracker.incrementInstanceCount();
         mShouldShowStorageInfoHeader = ContextUtils.getAppSharedPreferences().getBoolean(
                 PREF_SHOW_STORAGE_INFO_HEADER,
                 ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_HOME_SHOW_STORAGE_INFO));
     }
 
+    private OfflineContentProvider getOfflineContentProvider() {
+        return OfflineContentAggregatorFactory.forProfile(
+                Profile.getLastUsedProfile().getOriginalProfile());
+    }
+
     /** Called when the user's regular or incognito download history has been loaded. */
     public void onAllDownloadsRetrieved(List<DownloadItem> result, boolean isOffTheRecord) {
         if (isOffTheRecord && !mShowOffTheRecord) return;
@@ -303,6 +320,7 @@
         totalSize += mRegularDownloadItems.getTotalBytes();
         totalSize += mIncognitoDownloadItems.getTotalBytes();
         totalSize += mOfflinePageItems.getTotalBytes();
+        totalSize += mOfflineItems.getTotalBytes();
         return totalSize;
     }
 
@@ -573,6 +591,7 @@
         List<TimedItem> filteredTimedItems = new ArrayList<>();
         mRegularDownloadItems.filter(mFilter, mSearchQuery, filteredTimedItems);
         mIncognitoDownloadItems.filter(mFilter, mSearchQuery, filteredTimedItems);
+        mOfflineItems.filter(mFilter, mSearchQuery, filteredTimedItems);
 
         if (TextUtils.isEmpty(mSearchQuery)) {
             filterOfflinePageItems(filteredTimedItems);
@@ -778,4 +797,90 @@
     public SpaceDisplay getSpaceDisplayForTests() {
         return mSpaceDisplay;
     }
+
+    @Override
+    public void onItemsAvailable() {
+        List<OfflineItem> offlineItems = getOfflineContentProvider().getAllItems();
+        for (OfflineItem item : offlineItems) {
+            DownloadHistoryItemWrapper wrapper = createDownloadHistoryItemWrapper(item);
+            addDownloadHistoryItemWrapper(wrapper);
+        }
+    }
+
+    @Override
+    public void onItemsAdded(ArrayList<OfflineItem> items) {
+        boolean wasAdded = false;
+        boolean visible = false;
+        for (OfflineItem item : items) {
+            assert mOfflineItems.findItemIndex(item.id.id) == BackendItems.INVALID_INDEX;
+
+            DownloadHistoryItemWrapper wrapper = createDownloadHistoryItemWrapper(item);
+            wasAdded |= addDownloadHistoryItemWrapper(wrapper);
+            visible |= wrapper.isVisibleToUser(mFilter);
+            for (TestObserver observer : mObservers) observer.onOfflineItemCreated(item);
+        }
+
+        if (wasAdded && visible) filter(mFilter);
+    }
+
+    @Override
+    public void onItemRemoved(ContentId id) {
+        if (mOfflineItems.removeItem(id.id) != null) {
+            filter(mFilter);
+        }
+    }
+
+    @Override
+    public void onItemUpdated(OfflineItem item) {
+        DownloadHistoryItemWrapper newWrapper = createDownloadHistoryItemWrapper(item);
+        if (newWrapper.isOffTheRecord() && !mShowOffTheRecord) return;
+
+        // Check if the item has already been deleted.
+        if (updateDeletedFileMap(newWrapper)) return;
+
+        BackendItems list = mOfflineItems;
+        int index = list.findItemIndex(newWrapper.getId());
+        if (index == BackendItems.INVALID_INDEX) {
+            assert false : "Tried to update DownloadItem that didn't exist.";
+            return;
+        }
+
+        // Update the old one.
+        DownloadHistoryItemWrapper existingWrapper = list.get(index);
+        boolean isUpdated = existingWrapper.replaceItem(item);
+
+        // Re-add the file mapping once it finishes downloading. This accounts for the backend
+        // creating DownloadItems with a null file path, then updating it after the download starts.
+        // Doing it once after completion instead of at every update is a compromise that prevents
+        // us from rapidly and repeatedly updating the map with the same info.
+        if (item.state == OfflineItemState.COMPLETE) {
+            mFilePathsToItemsMap.addItem(existingWrapper);
+        }
+
+        if (item.state == OfflineItemState.CANCELLED) {
+            // The old one is being removed.
+            filter(mFilter);
+        } else if (existingWrapper.isVisibleToUser(mFilter)) {
+            if (existingWrapper.getPosition() == TimedItem.INVALID_POSITION) {
+                filter(mFilter);
+                for (TestObserver observer : mObservers) observer.onOfflineItemUpdated(item);
+            } else if (isUpdated) {
+                // Directly alert DownloadItemViews displaying information about the item that it
+                // has changed instead of notifying the RecyclerView that a particular item has
+                // changed.  This prevents the RecyclerView from detaching and immediately
+                // reattaching the same view, causing janky animations.
+                for (DownloadItemView view : mViews) {
+                    if (TextUtils.equals(item.id.id, view.getItem().getId())) {
+                        view.displayItem(mBackendProvider, existingWrapper);
+                    }
+                }
+
+                for (TestObserver observer : mObservers) observer.onOfflineItemUpdated(item);
+            }
+        }
+    }
+
+    private DownloadHistoryItemWrapper createDownloadHistoryItemWrapper(OfflineItem item) {
+        return new OfflineItemWrapper(item, mBackendProvider, mParentComponent);
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
index c00f5f5..4c3efd1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
@@ -16,10 +16,16 @@
 import org.chromium.chrome.browser.download.DownloadItem;
 import org.chromium.chrome.browser.download.DownloadNotificationService;
 import org.chromium.chrome.browser.download.DownloadUtils;
+import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.widget.DateDividedAdapter.TimedItem;
+import org.chromium.components.offline_items_collection.OfflineContentProvider;
+import org.chromium.components.offline_items_collection.OfflineItem;
 import org.chromium.components.offline_items_collection.OfflineItem.Progress;
+import org.chromium.components.offline_items_collection.OfflineItemFilter;
 import org.chromium.components.offline_items_collection.OfflineItemProgressUnit;
+import org.chromium.components.offline_items_collection.OfflineItemState;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.content_public.browser.DownloadState;
 import org.chromium.ui.widget.Toast;
@@ -163,6 +169,12 @@
     /** @return Whether this download is associated with the off the record profile. */
     abstract boolean isOffTheRecord();
 
+    /** @return Whether the item is an offline page. */
+    public abstract boolean isOfflinePage();
+
+    /** @return Whether this item is to be shown in the suggested reading section. */
+    abstract boolean isSuggested();
+
     /** @return Whether the item has been completely downloaded. */
     abstract boolean isComplete();
 
@@ -369,6 +381,16 @@
         }
 
         @Override
+        public boolean isOfflinePage() {
+            return false;
+        }
+
+        @Override
+        public boolean isSuggested() {
+            return false;
+        }
+
+        @Override
         public boolean isComplete() {
             return mItem.getDownloadInfo().state() == DownloadState.COMPLETE;
         }
@@ -558,7 +580,12 @@
             return false;
         }
 
-        /** @return Whether this page is to be shown in the suggested reading section. */
+        @Override
+        public boolean isOfflinePage() {
+            return true;
+        }
+
+        @Override
         public boolean isSuggested() {
             return mItem.isSuggested();
         }
@@ -575,4 +602,156 @@
                     == org.chromium.components.offlinepages.downloads.DownloadState.PAUSED;
         }
     }
+
+    /** Wraps a {@link OfflineItem}. */
+    public static class OfflineItemWrapper extends DownloadHistoryItemWrapper {
+        private OfflineItem mItem;
+
+        OfflineItemWrapper(OfflineItem item, BackendProvider provider, ComponentName component) {
+            super(provider, component);
+            mItem = item;
+        }
+
+        @Override
+        public OfflineItem getItem() {
+            return mItem;
+        }
+
+        @Override
+        public boolean replaceItem(Object item) {
+            assert item instanceof OfflineItem;
+            OfflineItem newItem = (OfflineItem) item;
+            assert mItem.id.equals(newItem.id);
+
+            mItem = newItem;
+            mFile = null;
+            return true;
+        }
+
+        @Override
+        public String getId() {
+            return mItem.id.id;
+        }
+
+        @Override
+        public long getTimestamp() {
+            return mItem.creationTimeMs;
+        }
+
+        @Override
+        public String getFilePath() {
+            return mItem.filePath;
+        }
+
+        @Override
+        public String getDisplayFileName() {
+            String title = mItem.title;
+            if (TextUtils.isEmpty(title)) {
+                return getDisplayHostname();
+            } else {
+                return title;
+            }
+        }
+
+        @Override
+        public long getFileSize() {
+            return mItem.totalSizeBytes;
+        }
+
+        @Override
+        public String getUrl() {
+            return mItem.pageUrl;
+        }
+
+        @Override
+        public int getFilterType() {
+            // TODO(shaktisahu): Make DownloadFilter unnecessary.
+            return isOfflinePage() ? DownloadFilter.FILTER_PAGE
+                                   : DownloadFilter.fromMimeType(mItem.mimeType);
+        }
+
+        @Override
+        public String getMimeType() {
+            return mItem.mimeType;
+        }
+
+        @Override
+        public int getFileExtensionType() {
+            // TODO(shaktisahu): Fix this.
+            return FILE_EXTENSION_OTHER;
+        }
+
+        @Override
+        public Progress getDownloadProgress() {
+            return mItem.progress;
+        }
+
+        @Override
+        public String getStatusString() {
+            // TODO(shaktisahu): Extract the status string.
+            return "";
+        }
+
+        private OfflineContentProvider getOfflineContentProvider() {
+            return OfflineContentAggregatorFactory.forProfile(
+                    Profile.getLastUsedProfile().getOriginalProfile());
+        }
+
+        @Override
+        public void open() {
+            getOfflineContentProvider().openItem(mItem.id);
+            recordOpenSuccess();
+        }
+
+        @Override
+        public void cancel() {
+            getOfflineContentProvider().cancelDownload(mItem.id);
+        }
+
+        @Override
+        public void pause() {
+            getOfflineContentProvider().pauseDownload(mItem.id);
+        }
+
+        @Override
+        public void resume() {
+            getOfflineContentProvider().resumeDownload(mItem.id, true);
+        }
+
+        @Override
+        public boolean remove() {
+            getOfflineContentProvider().removeItem(mItem.id);
+            return true;
+        }
+
+        @Override
+        boolean hasBeenExternallyRemoved() {
+            return mItem.externallyRemoved;
+        }
+
+        @Override
+        boolean isOffTheRecord() {
+            return mItem.isOffTheRecord;
+        }
+
+        @Override
+        public boolean isOfflinePage() {
+            return mItem.filter == OfflineItemFilter.FILTER_PAGE;
+        }
+
+        @Override
+        public boolean isSuggested() {
+            return mItem.isSuggested;
+        }
+
+        @Override
+        public boolean isComplete() {
+            return mItem.state == OfflineItemState.COMPLETE;
+        }
+
+        @Override
+        public boolean isPaused() {
+            return mItem.state == OfflineItemState.PAUSED;
+        }
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeviceConditions.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeviceConditions.java
index 01ed89d9..8150d71a6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeviceConditions.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeviceConditions.java
@@ -4,14 +4,12 @@
 
 package org.chromium.chrome.browser.offlinepages;
 
-import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.os.BatteryManager;
-import android.os.PowerManager;
 
 import org.chromium.base.VisibleForTesting;
 import org.chromium.net.ConnectionType;
@@ -22,7 +20,6 @@
     private final boolean mPowerConnected;
     private final int mBatteryPercentage;
     private final int mNetConnectionType;
-    private final boolean mPowerSaveOn;
 
     /**
      * Creates set of device network and power conditions.
@@ -30,12 +27,10 @@
      * @param batteryPercentage percentage (0-100) of remaining battery power
      * @param connectionType the org.chromium.net.ConnectionType value for the network connection
      */
-    public DeviceConditions(boolean powerConnected, int batteryPercentage, int netConnectionType,
-            boolean powerSaveOn) {
+    public DeviceConditions(boolean powerConnected, int batteryPercentage, int netConnectionType) {
         mPowerConnected = powerConnected;
         mBatteryPercentage = batteryPercentage;
         mNetConnectionType = netConnectionType;
-        mPowerSaveOn = powerSaveOn;
     }
 
     @VisibleForTesting
@@ -43,7 +38,6 @@
         mPowerConnected = false;
         mBatteryPercentage = 0;
         mNetConnectionType = ConnectionType.CONNECTION_NONE;
-        mPowerSaveOn = false;
     }
 
     /** Returns the current device conditions. May be overridden for testing. */
@@ -51,13 +45,62 @@
         Intent batteryStatus = getBatteryStatus(context);
         if (batteryStatus == null) return null;
 
-        return new DeviceConditions(isPowerConnected(context), getBatteryPercentage(context),
-                getNetConnectionType(context), getInPowerSaveMode(context));
+        return new DeviceConditions(isPowerConnected(batteryStatus),
+                getBatteryPercentage(batteryStatus), getConnectionType(context));
     }
 
     /** @return Whether power is connected. */
     public static boolean isPowerConnected(Context context) {
-        Intent batteryStatus = getBatteryStatus(context);
+        return isPowerConnected(getBatteryStatus(context));
+    }
+
+    /** @return Battery percentage. */
+    public static int getBatteryPercentage(Context context) {
+        return getBatteryPercentage(getBatteryStatus(context));
+    }
+
+    /**
+     * @return Network connection type, where possible values are defined by
+     *     org.chromium.net.ConnectionType.
+     */
+    public static int getNetConnectionType(Context context) {
+        return getConnectionType(context);
+    }
+
+    /** @return Whether power is connected. */
+    public boolean isPowerConnected() {
+        return mPowerConnected;
+    }
+
+    /** @return Battery percentage. */
+    public int getBatteryPercentage() {
+        return mBatteryPercentage;
+    }
+
+    /**
+     * @return Network connection type, where possible values are defined by
+     *     org.chromium.net.ConnectionType.
+     */
+    public int getNetConnectionType() {
+        return mNetConnectionType;
+    }
+    /**
+     * @return true if the active network is a metered network
+     */
+    public static boolean isActiveNetworkMetered(Context context) {
+        ConnectivityManager cm =
+                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        return cm.isActiveNetworkMetered();
+    }
+
+    private static Intent getBatteryStatus(Context context) {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        // Note this is a sticky intent, so we aren't really registering a receiver, just getting
+        // the sticky intent.  That means that we don't need to unregister the filter later.
+        return context.registerReceiver(null, filter);
+    }
+
+    private static boolean isPowerConnected(Intent batteryStatus) {
         if (batteryStatus == null) return false;
 
         int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
@@ -66,9 +109,7 @@
         return isConnected;
     }
 
-    /** @return Battery percentage. */
-    public static int getBatteryPercentage(Context context) {
-        Intent batteryStatus = getBatteryStatus(context);
+    private static int getBatteryPercentage(Intent batteryStatus) {
         if (batteryStatus == null) return 0;
 
         int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
@@ -79,21 +120,7 @@
         return percentage;
     }
 
-    /**
-     * @return true if the device is in power save mode.
-     */
-    // TODO(crbug.com/763923): Fix warning and remove suppression.
-    @SuppressLint("NewApi")
-    public static boolean getInPowerSaveMode(Context context) {
-        PowerManager powerManager = (PowerManager) context.getSystemService(context.POWER_SERVICE);
-        return powerManager.isPowerSaveMode();
-    }
-
-    /**
-     * @return Network connection type, where possible values are defined by
-     *     org.chromium.net.ConnectionType.
-     */
-    public static int getNetConnectionType(Context context) {
+    private static int getConnectionType(Context context) {
         int connectionType = ConnectionType.CONNECTION_NONE;
 
         // If we are starting in the background, native portion might not be initialized.
@@ -117,47 +144,6 @@
         return connectionType;
     }
 
-    /**
-     * @return true if the active network is a metered network
-     */
-    public static boolean isActiveNetworkMetered(Context context) {
-        ConnectivityManager cm =
-                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        return cm.isActiveNetworkMetered();
-    }
-
-    /** @return Whether power is connected. */
-    public boolean isPowerConnected() {
-        return mPowerConnected;
-    }
-
-    /** @return Battery percentage. */
-    public int getBatteryPercentage() {
-        return mBatteryPercentage;
-    }
-
-    /**
-     * @return Network connection type, where possible values are defined by
-     *     org.chromium.net.ConnectionType.
-     */
-    public int getNetConnectionType() {
-        return mNetConnectionType;
-    }
-
-    /**
-     * @return true if the device is in power save mode.
-     */
-    public boolean inPowerSaveMode() {
-        return mPowerSaveOn;
-    }
-
-    private static Intent getBatteryStatus(Context context) {
-        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-        // Note this is a sticky intent, so we aren't really registering a receiver, just getting
-        // the sticky intent.  That means that we don't need to unregister the filter later.
-        return context.registerReceiver(null, filter);
-    }
-
     /** Returns the NCN network type corresponding to the connectivity manager network type */
     private static int convertAndroidNetworkTypeToConnectionType(
             int connectivityManagerNetworkType) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
index 350e151c..d4c3d79 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
@@ -114,8 +114,7 @@
         DeviceConditions deviceConditions = DeviceConditions.getCurrentConditions(context);
 
         if (!areBatteryConditionsMet(deviceConditions)
-                || !areNetworkConditionsMet(context, deviceConditions)
-                || deviceConditions.inPowerSaveMode()) {
+                || !areNetworkConditionsMet(context, deviceConditions)) {
             return NativeBackgroundTask.RESCHEDULE;
         }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java
index e8c2eb83..2deddd3b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java
@@ -27,6 +27,7 @@
 import org.chromium.chrome.browser.download.ui.StubbedProvider.StubbedOfflinePageDelegate;
 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem;
 import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
+import org.chromium.components.offline_items_collection.OfflineItem;
 import org.chromium.content_public.browser.DownloadState;
 
 import java.util.Set;
@@ -67,6 +68,12 @@
         }
 
         @Override
+        public void onOfflineItemCreated(OfflineItem item) {}
+
+        @Override
+        public void onOfflineItemUpdated(OfflineItem item) {}
+
+        @Override
         public void onSpaceDisplayUpdated(SpaceDisplay spaceDisplay) {
             onSpaceDisplayUpdatedCallback.notifyCalled();
         }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
index 3220075..d5f72f5 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
@@ -59,7 +59,6 @@
     private static final boolean REQUIRE_POWER = true;
     private static final boolean REQUIRE_UNMETERED = true;
     private static final boolean POWER_CONNECTED = true;
-    private static final boolean POWER_SAVE_MODE_ON = true;
     private static final int MINIMUM_BATTERY_LEVEL = 33;
     private static final String IS_LOW_END_DEVICE_SWITCH =
             "--" + BaseSwitches.ENABLE_LOW_END_DEVICE_MODE;
@@ -71,8 +70,8 @@
     private long mTestTime;
     private TriggerConditions mTriggerConditions =
             new TriggerConditions(!REQUIRE_POWER, MINIMUM_BATTERY_LEVEL, REQUIRE_UNMETERED);
-    private DeviceConditions mDeviceConditions = new DeviceConditions(!POWER_CONNECTED,
-            MINIMUM_BATTERY_LEVEL + 5, ConnectionType.CONNECTION_3G, !POWER_SAVE_MODE_ON);
+    private DeviceConditions mDeviceConditions = new DeviceConditions(
+            !POWER_CONNECTED, MINIMUM_BATTERY_LEVEL + 5, ConnectionType.CONNECTION_3G);
     private Activity mTestActivity;
 
     @Mock
@@ -135,8 +134,8 @@
     @Feature({"OfflinePages"})
     public void testCheckConditions_BatteryConditions_LowBattery_NoPower() {
         // Setup low battery conditions with no power connected.
-        DeviceConditions deviceConditionsLowBattery = new DeviceConditions(!POWER_CONNECTED,
-                MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsLowBattery = new DeviceConditions(
+                !POWER_CONNECTED, MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsLowBattery, false /* unmetered */);
 
@@ -160,8 +159,8 @@
     @Feature({"OfflinePages"})
     public void testCheckConditions_BatteryConditions_LowBattery_WithPower() {
         // Set battery percentage below minimum level, but connect power.
-        DeviceConditions deviceConditionsPowerConnected = new DeviceConditions(POWER_CONNECTED,
-                MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsPowerConnected = new DeviceConditions(
+                POWER_CONNECTED, MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsPowerConnected, false /* unmetered */);
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/ShadowDeviceConditions.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/ShadowDeviceConditions.java
index 57bd411..1179a1a1 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/ShadowDeviceConditions.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/ShadowDeviceConditions.java
@@ -48,9 +48,4 @@
     public static boolean isActiveNetworkMetered(Context context) {
         return sMetered;
     }
-
-    @Implementation
-    public static boolean getInPowerSaveMode(Context context) {
-        return sDeviceConditions.inPowerSaveMode();
-    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
index 1f35bfd6..21735b0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
@@ -87,7 +87,6 @@
         }
     }
     public static final boolean POWER_CONNECTED = true;
-    public static final boolean POWER_SAVE_MODE_ON = true;
     public static final int HIGH_BATTERY_LEVEL = 75;
     public static final int LOW_BATTERY_LEVEL = 25;
 
@@ -172,8 +171,8 @@
         when(params.getTaskId()).thenReturn(TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID);
 
         // Setup battery conditions with no power connected.
-        DeviceConditions deviceConditions = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditions = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(deviceConditions, false /* metered */);
 
         mPrefetchBackgroundTask.onStartTask(null, params, new TaskFinishedCallback() {
@@ -191,8 +190,8 @@
     @Test
     public void testBatteryLow() throws Exception {
         // Setup low battery conditions with no power connected.
-        DeviceConditions deviceConditionsLowBattery = new DeviceConditions(!POWER_CONNECTED,
-                LOW_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsLowBattery = new DeviceConditions(
+                !POWER_CONNECTED, LOW_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(deviceConditionsLowBattery, true /* metered */);
 
         // Check impact on starting before native loaded.
@@ -212,8 +211,8 @@
     @Test
     public void testBatteryHigh() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, false /* metered */);
 
@@ -234,8 +233,8 @@
     @Test
     public void testNoNetwork() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_NONE, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_NONE);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, false /* metered */);
 
@@ -256,8 +255,8 @@
     @Test
     public void testUnmeteredWifiNetwork() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, false /* metered */);
 
@@ -278,8 +277,8 @@
     @Test
     public void testMeteredWifiNetwork() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, true /* metered */);
 
@@ -300,8 +299,8 @@
     @Test
     public void testMetered2GNetwork() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_2G, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_2G);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, false /* metered */);
 
@@ -322,8 +321,8 @@
     @Test
     public void testBluetoothNetwork() throws Exception {
         // Setup high battery conditions with no power connected.
-        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_BLUETOOTH, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditionsHighBattery = new DeviceConditions(
+                !POWER_CONNECTED, HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_BLUETOOTH);
         ShadowDeviceConditions.setCurrentConditions(
                 deviceConditionsHighBattery, false /* metered */);
 
@@ -348,8 +347,8 @@
         when(params.getTaskId()).thenReturn(TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID);
 
         // Conditions should be appropriate for running the task.
-        DeviceConditions deviceConditions = new DeviceConditions(POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI, !POWER_SAVE_MODE_ON);
+        DeviceConditions deviceConditions = new DeviceConditions(
+                POWER_CONNECTED, HIGH_BATTERY_LEVEL - 1, ConnectionType.CONNECTION_WIFI);
         ShadowDeviceConditions.setCurrentConditions(deviceConditions, false /* metered */);
 
         mPrefetchBackgroundTask.onStartTask(null, params, new TaskFinishedCallback() {
@@ -364,25 +363,4 @@
         assertEquals(1, reschedules.size());
         assertEquals(false, reschedules.get(0));
     }
-
-    @Test
-    public void testPowerSaverOn() throws Exception {
-        // Setup power save mode, battery is high, wifi, not plugged in.
-        DeviceConditions deviceConditionsPowerSave = new DeviceConditions(!POWER_CONNECTED,
-                HIGH_BATTERY_LEVEL, ConnectionType.CONNECTION_WIFI, POWER_SAVE_MODE_ON);
-        ShadowDeviceConditions.setCurrentConditions(deviceConditionsPowerSave, false /* metered */);
-
-        // Check impact on starting before native loaded.
-        TaskParameters params =
-                TaskParameters.create(TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID).build();
-
-        int result = mPrefetchBackgroundTask.onStartTaskBeforeNativeLoaded(
-                RuntimeEnvironment.application, params, new TaskFinishedCallback() {
-                    @Override
-                    public void taskFinished(boolean needsReschedule) {
-                        fail("Finished callback should not be run, battery conditions not met.");
-                    }
-                });
-        assertEquals(NativeBackgroundTask.RESCHEDULE, result);
-    }
 }
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
index 6236660..6c9aecd 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -318,7 +318,7 @@
     return;
 
   context->StartServiceWorkerForNavigationHint(destination_url,
-                                               base::Bind(&NoopCallback));
+                                               base::BindOnce(&NoopCallback));
 }
 
 void ChromeAutocompleteProviderClient::OnAutocompleteControllerResultReady(
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
index 4e7d8b4..10e3ec2 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
@@ -4,19 +4,18 @@
 
 #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
 
+#include <memory>
+
 #include "base/memory/ptr_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
-#include "content/public/test/mock_service_worker_context.h"
+#include "content/public/test/fake_service_worker_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_storage_partition.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-using ::testing::_;
-
 class ChromeAutocompleteProviderClientTest : public testing::Test {
  public:
   void SetUp() override {
@@ -40,7 +39,7 @@
 
   std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<ChromeAutocompleteProviderClient> client_;
-  content::MockServiceWorkerContext service_worker_context_;
+  content::FakeServiceWorkerContext service_worker_context_;
 
  private:
   content::TestStoragePartition storage_partition_;
@@ -49,10 +48,9 @@
 TEST_F(ChromeAutocompleteProviderClientTest, StartServiceWorker) {
   GURL destination_url("https://google.com/search?q=puppies");
 
-  EXPECT_CALL(service_worker_context_,
-              StartServiceWorkerForNavigationHint(destination_url, _))
-      .Times(1);
   client_->StartServiceWorker(destination_url);
+  EXPECT_TRUE(service_worker_context_
+                  .start_service_worker_for_navigation_hint_called());
 }
 
 TEST_F(ChromeAutocompleteProviderClientTest,
@@ -60,10 +58,9 @@
   GURL destination_url("https://google.com/search?q=puppies");
 
   GoOffTheRecord();
-  EXPECT_CALL(service_worker_context_,
-              StartServiceWorkerForNavigationHint(destination_url, _))
-      .Times(0);
   client_->StartServiceWorker(destination_url);
+  EXPECT_FALSE(service_worker_context_
+                   .start_service_worker_for_navigation_hint_called());
 }
 
 TEST_F(ChromeAutocompleteProviderClientTest,
@@ -71,8 +68,7 @@
   GURL destination_url("https://google.com/search?q=puppies");
 
   profile_->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
-  EXPECT_CALL(service_worker_context_,
-              StartServiceWorkerForNavigationHint(destination_url, _))
-      .Times(0);
   client_->StartServiceWorker(destination_url);
+  EXPECT_FALSE(service_worker_context_
+                   .start_service_worker_for_navigation_hint_called());
 }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 0a5f1ff..d5c51e7 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -149,8 +149,6 @@
           </then>
           <else>
             <include name="IDR_MD_DOWNLOADS_DOWNLOADS_HTML" file="resources\md_downloads\downloads.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-            <include name="IDR_MD_DOWNLOADS_ACTION_SERVICE_HTML" file="resources\md_downloads\action_service.html" type="BINDATA" />
-            <include name="IDR_MD_DOWNLOADS_ACTION_SERVICE_JS" file="resources\md_downloads\action_service.js" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_BROWSER_PROXY_HTML" file="resources\md_downloads\browser_proxy.html" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_BROWSER_PROXY_JS" file="resources\md_downloads\browser_proxy.js" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_CONSTANTS_HTML" file="resources\md_downloads\constants.html" type="BINDATA" />
@@ -162,6 +160,8 @@
             <include name="IDR_MD_DOWNLOADS_ITEM_JS" file="resources\md_downloads\item.js" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_MANAGER_HTML" file="resources\md_downloads\manager.html" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_MANAGER_JS" file="resources\md_downloads\manager.js" type="BINDATA" />
+            <include name="IDR_MD_DOWNLOADS_SEARCH_SERVICE_HTML" file="resources\md_downloads\search_service.html" type="BINDATA" />
+            <include name="IDR_MD_DOWNLOADS_SEARCH_SERVICE_JS" file="resources\md_downloads\search_service.js" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_TOOLBAR_HTML" file="resources\md_downloads\toolbar.html" type="BINDATA" />
             <include name="IDR_MD_DOWNLOADS_TOOLBAR_JS" file="resources\md_downloads\toolbar.js" type="BINDATA" />
           </else>
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc
index aa8b0fc..4e1dccf8 100644
--- a/chrome/browser/chrome_service_worker_browsertest.cc
+++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -615,9 +615,9 @@
     base::RunLoop run_loop;
     GetServiceWorkerContext()->StartServiceWorkerForNavigationHint(
         embedded_test_server()->GetURL(scope),
-        base::Bind(&ExpectResultAndRun<
-                       content::StartServiceWorkerForNavigationHintResult>,
-                   expected_result, run_loop.QuitClosure()));
+        base::BindOnce(&ExpectResultAndRun<
+                           content::StartServiceWorkerForNavigationHintResult>,
+                       expected_result, run_loop.QuitClosure()));
     run_loop.Run();
     if (expected_started) {
       histogram_tester_.ExpectBucketCount(
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc
index 7df20e9..9104ca1 100644
--- a/chrome/browser/chromeos/arc/arc_service_launcher.cc
+++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -49,6 +49,7 @@
 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
 #include "components/arc/lock_screen/arc_lock_screen_bridge.h"
 #include "components/arc/metrics/arc_metrics_service.h"
+#include "components/arc/midis/arc_midis_bridge.h"
 #include "components/arc/net/arc_net_host_impl.h"
 #include "components/arc/obb_mounter/arc_obb_mounter_bridge.h"
 #include "components/arc/power/arc_power_bridge.h"
@@ -146,6 +147,7 @@
   ArcKioskBridge::GetForBrowserContext(profile);
   ArcLockScreenBridge::GetForBrowserContext(profile);
   ArcMetricsService::GetForBrowserContext(profile);
+  ArcMidisBridge::GetForBrowserContext(profile);
   ArcNetHostImpl::GetForBrowserContext(profile);
   ArcNotificationManager::GetForBrowserContext(profile);
   ArcObbMounterBridge::GetForBrowserContext(profile);
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
index eacd28e7..ef72a22a 100644
--- a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
+++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h"
 
+#include <memory>
 #include <string>
 
-#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/feedback/feedback_uploader_chrome.h"
@@ -41,7 +41,7 @@
     content::BrowserContext* browser_context,
     bool from_crash) const {
   std::unique_ptr<base::DictionaryValue> dict =
-      base::MakeUnique<base::DictionaryValue>();
+      std::make_unique<base::DictionaryValue>();
 
 #define SET_STRING(id, idr) dict->SetString(id, l10n_util::GetStringUTF16(idr))
   SET_STRING("page-title", from_crash
@@ -115,25 +115,43 @@
   switch (source_type) {
     // These map to SupportedLogFileSources.
     case api::feedback_private::LOG_SOURCE_MESSAGES:
-      return base::MakeUnique<system_logs::SingleLogFileLogSource>(
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
           SupportedLogFileSource::kMessages);
     case api::feedback_private::LOG_SOURCE_UILATEST:
-      return base::MakeUnique<system_logs::SingleLogFileLogSource>(
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
           SupportedLogFileSource::kUiLatest);
     case api::feedback_private::LOG_SOURCE_ATRUSLOG:
-      return base::MakeUnique<system_logs::SingleLogFileLogSource>(
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
           SupportedLogFileSource::kAtrusLog);
     case api::feedback_private::LOG_SOURCE_NETLOG:
-      return base::MakeUnique<system_logs::SingleLogFileLogSource>(
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
           SupportedLogFileSource::kNetLog);
+    case api::feedback_private::LOG_SOURCE_EVENTLOG:
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
+          SupportedLogFileSource::kEventLog);
+    case api::feedback_private::LOG_SOURCE_UPDATEENGINELOG:
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
+          SupportedLogFileSource::kUpdateEngineLog);
+    case api::feedback_private::LOG_SOURCE_POWERMANAGERLATEST:
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
+          SupportedLogFileSource::kPowerManagerLatest);
+    case api::feedback_private::LOG_SOURCE_POWERMANAGERPREVIOUS:
+      return std::make_unique<system_logs::SingleLogFileLogSource>(
+          SupportedLogFileSource::kPowerManagerPrevious);
 
     // These map to SupportedDebugDaemonSources.
     case api::feedback_private::LOG_SOURCE_DRMMODETEST:
-      return base::MakeUnique<system_logs::SingleDebugDaemonLogSource>(
+      return std::make_unique<system_logs::SingleDebugDaemonLogSource>(
           SupportedDebugDaemonSource::kModetest);
     case api::feedback_private::LOG_SOURCE_LSUSB:
-      return base::MakeUnique<system_logs::SingleDebugDaemonLogSource>(
+      return std::make_unique<system_logs::SingleDebugDaemonLogSource>(
           SupportedDebugDaemonSource::kLsusb);
+    case api::feedback_private::LOG_SOURCE_LSPCI:
+      return std::make_unique<system_logs::SingleDebugDaemonLogSource>(
+          SupportedDebugDaemonSource::kLspci);
+    case api::feedback_private::LOG_SOURCE_IFCONFIG:
+      return std::make_unique<system_logs::SingleDebugDaemonLogSource>(
+          SupportedDebugDaemonSource::kIfconfig);
 
     case api::feedback_private::LOG_SOURCE_NONE:
     default:
diff --git a/chrome/browser/resources/chromeos/login/md_top_header_bar.css b/chrome/browser/resources/chromeos/login/md_top_header_bar.css
index fb88a5b..6a453e5 100644
--- a/chrome/browser/resources/chromeos/login/md_top_header_bar.css
+++ b/chrome/browser/resources/chromeos/login/md_top_header_bar.css
@@ -4,10 +4,13 @@
  */
 
 #top-header-bar {
+  z-index: 1;
+}
+
+.top-header-bar-strip {
   display: flex;
   justify-content: flex-end;
   width: 100%;
-  z-index: 1;
 }
 
 #top-header-bar.version-labels-unset  #version-labels {
@@ -25,20 +28,6 @@
   z-index: 1;
 }
 
-.new-note-action-container-activated {
-  bottom: 0;
-  height: 100%;
-  left: 0;
-  position: absolute;
-  right: 0;
-  top: 0;
-  width: 100%;
-}
-
-.new-note-action-above-login-header {
-  z-index: 5;
-}
-
 .new-note-action {
   -webkit-tap-highlight-color: transparent;
   background-color: rgba(0, 0, 0, 0.2);
@@ -47,20 +36,12 @@
   display: flex;
   height: 44px;
   justify-content: flex-end;
-  transition: all 300ms ease-in;
+  transition-duration: 300ms;
+  transition-property: border-radius, height, width;
   width: 44px;
   z-index: 1;
 }
 
-.new-note-action.disabled {
-  cursor: default;
-  pointer-events: none;
-}
-
-.new-note-action {
-  transition: all 300ms;
-}
-
 html[dir=rtl] .new-note-action {
   border-radius: 0 0 44px 0;
 }
@@ -78,19 +59,6 @@
   border-radius: 0 0 48px 0;
 }
 
-.new-note-action-container-activated > .new-note-action {
-  bottom: auto;
-  left: auto;
-  position: absolute;
-  right: 0;
-  top: 0;
-}
-
-html[dir=rtl] .new-note-action-container-activated > .new-note-action {
-  left: 0;
-  right: auto;
-}
-
 .new-note-action-icon {
   -webkit-padding-end: 11px;
   height: 16px;
@@ -98,3 +66,35 @@
   width: 16px;
 }
 
+.new-note-background {
+  background-color: black;
+  border-radius: 0 0 0 100%;
+  bottom: auto;
+  display: none;
+  left: auto;
+  position: absolute;
+  right: 0;
+  top: 0;
+  transform-origin: top right;
+  z-index: 1;
+}
+
+.new-note-background.new-note-action-above-login-header {
+  z-index: 5;
+}
+
+html[dir=rtl] .new-note-background {
+  border-radius: 0 0 100% 0;
+  left: 0;
+  right: auto;
+  transform-origin: top left;
+}
+
+#top-header-bar.new-note-activated .new-note-background {
+  display: block;
+}
+
+.new-note-background-animated {
+  transition-duration: 300ms;
+  transition-property: opacity, transform;
+}
diff --git a/chrome/browser/resources/chromeos/login/md_top_header_bar.html b/chrome/browser/resources/chromeos/login/md_top_header_bar.html
index 056bc034..8132014 100644
--- a/chrome/browser/resources/chromeos/login/md_top_header_bar.html
+++ b/chrome/browser/resources/chromeos/login/md_top_header_bar.html
@@ -10,17 +10,21 @@
 </iron-iconset-svg>
 
 <div id="top-header-bar">
-  <div id="version-labels" hidden>
-    <div id="version"></div>
-    <div id="asset-id"></div>
-    <div id="bluetooth-name" hidden></div>
-  </div>
-  <div hidden id="new-note-action-container" class="new-note-action-container">
-    <div role="button" id="new-note-action" class="new-note-action"
-        tabindex="0" i18n-values="aria-label:newLockScreenNoteButton">
-      <iron-icon icon="new-note-action:action-icon"
-          id="new-note-action-icon" class="new-note-action-icon">
-      </iron-icon>
+  <div class="top-header-bar-strip">
+    <div id="version-labels" hidden>
+      <div id="version"></div>
+      <div id="asset-id"></div>
+      <div id="bluetooth-name" hidden></div>
+    </div>
+    <div hidden id="new-note-action-container"
+        class="new-note-action-container">
+      <div role="button" id="new-note-action" class="new-note-action"
+          tabindex="0" i18n-values="aria-label:newLockScreenNoteButton">
+        <iron-icon icon="new-note-action:action-icon"
+            id="new-note-action-icon" class="new-note-action-icon">
+        </iron-icon>
+      </div>
     </div>
   </div>
+  <div id="new-note-background" class="new-note-background"></div>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/md_top_header_bar.js b/chrome/browser/resources/chromeos/login/md_top_header_bar.js
index f969021..9718838 100644
--- a/chrome/browser/resources/chromeos/login/md_top_header_bar.js
+++ b/chrome/browser/resources/chromeos/login/md_top_header_bar.js
@@ -22,6 +22,12 @@
   };
 
   /**
+   * The size of new note action element.
+   * @const {number}
+   */
+  var NEW_NOTE_ACTION_ELEMENT_SIZE = 44;
+
+  /**
    * Calculates diagonal length of a rectangle with the provided sides.
    * @param {!number} x The rectangle width.
    * @param {!number} y The rectangle height.
@@ -347,6 +353,12 @@
     /** @private {SwipeDetector} */
     swipeDetector_: null,
 
+    /**
+     * Expected size of fully expanded new note action background.
+     * @private {number}
+     */
+    fullBackgroundSize_: 0,
+
     set lockScreenAppsState(state) {
       if (this.lockScreenAppsState_ == state)
         return;
@@ -386,38 +398,26 @@
           this.lockScreenAppsState_ != LOCK_SCREEN_APPS_STATE.AVAILABLE &&
           this.lockScreenAppsState_ != LOCK_SCREEN_APPS_STATE.FOREGROUND;
 
-      var newNoteActionEnabled =
-          this.lockScreenAppsState_ == LOCK_SCREEN_APPS_STATE.AVAILABLE;
-      $('new-note-action').classList.toggle('disabled', !newNoteActionEnabled);
-      $('new-note-action')
-          .setAttribute('tabIndex', newNoteActionEnabled ? '0' : '-1');
-      $('new-note-action-icon').hidden = !newNoteActionEnabled;
-
       // This might get set when the action is activated - reset it when the
       // lock screen action is updated.
-      $('new-note-action-container')
+      $('new-note-background')
           .classList.toggle('new-note-action-above-login-header', false);
 
-      if (this.lockScreenAppsState_ != LOCK_SCREEN_APPS_STATE.FOREGROUND) {
-        var transitionOut =
-            previousState == LOCK_SCREEN_APPS_STATE.FOREGROUND &&
-            this.lockScreenAppsState_ == LOCK_SCREEN_APPS_STATE.AVAILABLE;
-        $('new-note-action-container')
-            .classList.toggle(
-                'new-note-action-container-activated', transitionOut);
-        if (transitionOut) {
-          this.runOnNoteActionTransitionEnd_(function() {
-            $('new-note-action-container')
-                .classList.toggle('new-note-action-container-activated', false);
-          });
-        }
+      var animate = previousState == LOCK_SCREEN_APPS_STATE.FOREGROUND &&
+          this.lockScreenAppsState_ == LOCK_SCREEN_APPS_STATE.AVAILABLE;
 
-        $('new-note-action').style.removeProperty('border-bottom-left-radius');
-        $('new-note-action').style.removeProperty('border-bottom-right-radius');
-        $('new-note-action').style.removeProperty('height');
-        $('new-note-action').style.removeProperty('width');
-        $('new-note-action').style.removeProperty('background-color');
-      }
+      this.setBackgroundActive_(
+          this.lockScreenAppsState_ == LOCK_SCREEN_APPS_STATE.FOREGROUND,
+          animate, this.updateNewNoteActionVisibility_.bind(this));
+    },
+
+    /**
+     * Updates new note action element visibility state.
+     * @private
+     */
+    updateNewNoteActionVisibility_: function() {
+      $('new-note-action').hidden =
+          this.lockScreenAppsState_ != LOCK_SCREEN_APPS_STATE.AVAILABLE;
     },
 
     /**
@@ -464,37 +464,68 @@
      * @private
      */
     activateNoteAction_: function(requestType) {
-      $('new-note-action').classList.toggle('disabled', true);
-      $('new-note-action-icon').hidden = true;
+      $('new-note-action').hidden = true;
       $('top-header-bar').classList.toggle('version-labels-unset', true);
+      $('new-note-background')
+          .classList.toggle('new-note-action-above-login-header', true);
 
-      this.runOnNoteActionTransitionEnd_(
-          (function() {
-            if (this.lockScreenAppsState_ != LOCK_SCREEN_APPS_STATE.AVAILABLE)
-              return;
-            chrome.send('requestNewLockScreenNote', [requestType]);
-          }).bind(this));
+      this.setBackgroundActive_(true /*active*/, true /*animate*/, function() {
+        chrome.send('requestNewLockScreenNote', [requestType]);
+      });
+    },
 
-      var container = $('new-note-action-container');
-      container.classList.toggle('new-note-action-container-activated', true);
-      container.classList.toggle('new-note-action-above-login-header', true);
+    /**
+     * Updates the new note action element style for active note taking.
+     * @param {boolean} active Whether the note action is in active state.
+     * @param {boolean} animate Whether the UI state changes should be animated.
+     *    For example, whether the note background should be expanded or scaled
+     *    down with an animation.
+     * @param {function()=} callback Called when the UI state change is
+     *     complete.
+     * @private
+     */
+    setBackgroundActive_: function(active, animate, callback) {
+      // Cache full background size - it will be used to calculate scale
+      // transform for animating new note action background.
+      var targetSize = diag(
+          $('scroll-container').clientWidth,
+          $('scroll-container').clientHeight);
+      if (this.fullBackgroundSize_ != targetSize) {
+        $('new-note-background').style.setProperty('height', targetSize + 'px');
+        $('new-note-background').style.setProperty('width', targetSize + 'px');
+        this.fullBackgroundSize_ = targetSize;
+      }
 
-      var newNoteAction = $('new-note-action');
-      // Update new-note-action size to cover full screen - the element is a
-      // circle quadrant, intent is for the whole quadrant to cover the screen
-      // area, which means that the element size (radius) has to be set to the
-      // container diagonal. Note that, even though the final new-note-action
-      // element UI state is full-screen, the element is kept as circle quadrant
-      // for purpose of transition animation (to get the effect of the element
-      // radius increasing until it covers the whole screen).
-      var targetSize =
-          '' + diag(container.clientWidth, container.clientHeight) + 'px';
-      newNoteAction.style.setProperty('width', targetSize);
-      newNoteAction.style.setProperty('height', targetSize);
-      newNoteAction.style.setProperty(
-          isRTL() ? 'border-bottom-right-radius' : 'border-bottom-left-radius',
-          targetSize);
-      newNoteAction.style.setProperty('background-color', '#000');
+      if (active || !animate)
+        $('top-header-bar').classList.toggle('new-note-activated', active);
+
+      if (animate) {
+        $('new-note-background')
+            .style.setProperty(
+                'transition-timing-function', active ? 'ease-in' : 'ease-out');
+        $('new-note-background')
+            .classList.toggle('new-note-background-animated', true);
+
+        this.runOnNoteActionTransitionEnd_(function() {
+          $('new-note-background')
+              .classList.toggle('new-note-background-animated', false);
+          $('top-header-bar').classList.toggle('new-note-activated', active);
+
+          if (callback)
+            callback();
+        });
+      }
+
+      var newNoteBackground = $('new-note-background');
+      var scale =
+          active ? 1 : NEW_NOTE_ACTION_ELEMENT_SIZE / this.fullBackgroundSize_;
+      newNoteBackground.style.setProperty('transform', 'scale(' + scale + ')');
+      newNoteBackground.style.setProperty('opacity', active ? '1' : '0.2');
+
+      // If background is updated with animation, callback will be run when
+      // the animation finishes.
+      if (!animate && callback)
+        callback();
     },
 
     /**
@@ -505,11 +536,13 @@
      * @param {!function()} callback Closure to run on transition end.
      */
     runOnNoteActionTransitionEnd_: function(callback) {
-      $('new-note-action').addEventListener('transitionend', function listen() {
-        $('new-note-action').removeEventListener('transitionend', listen);
-        callback();
-      });
-      ensureTransitionEndEvent($('new-note-action'));
+      $('new-note-background')
+          .addEventListener('transitionend', function listen() {
+            $('new-note-background')
+                .removeEventListener('transitionend', listen);
+            callback();
+          });
+      ensureTransitionEndEvent($('new-note-background'));
     }
   };
 
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
index d9b477b..7c5d716 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
@@ -366,7 +366,7 @@
 #supervised-user-creation-image-grid {
   -webkit-user-drag: none;
   display: inline-block;
-  height: 264px;
+  height: 272px;
   margin: 0;
   outline: none;
   overflow: hidden;
@@ -428,7 +428,9 @@
   background: white;
   border: solid 1px #cacaca;
   border-radius: 4px;
+  height: 220px;
   padding: 2px;
+  width: 220px;
 }
 
 .supervised-user-creation-image-stream-area {
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
index 87422a2..069305e 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
@@ -1428,8 +1428,11 @@
 
         setDefaultImages: function(info) {
           var imageGrid = this.getScreenElement('image-grid');
-          imageGrid.setDefaultImages(info.images);
-          this.imagesData_ = info.images;
+          // Limit default images to 23 first images of current set to avoid
+          // the need to handle overflow and the additional logic that is
+          // required to handle that correctly.
+          this.imagesData_ = info.images.slice(info.first, info.first + 23);
+          imageGrid.setDefaultImages(this.imagesData_);
         },
 
 
diff --git a/chrome/browser/resources/chromeos/user_images_grid.js b/chrome/browser/resources/chromeos/user_images_grid.js
index f0ca84c4..e713eae 100644
--- a/chrome/browser/resources/chromeos/user_images_grid.js
+++ b/chrome/browser/resources/chromeos/user_images_grid.js
@@ -13,7 +13,7 @@
    * Dimensions for camera capture.
    * @const
    */
-  var CAPTURE_SIZE = {height: 480, width: 480};
+  var CAPTURE_SIZE = {height: 576, width: 576};
 
   /**
    * Path for internal URLs.
@@ -47,7 +47,7 @@
       // than actual images so there is no need in full scale on HDPI.
       var url = this.dataItem.url;
       if (url.slice(0, CHROME_THEME_PATH.length) == CHROME_THEME_PATH)
-        imageEl.src = this.dataItem.url + '@1x';
+        imageEl.src = this.dataItem.url + '[0]@1x';
       else
         imageEl.src = this.dataItem.url;
       imageEl.title = this.dataItem.title || '';
@@ -180,7 +180,7 @@
       var url = this.selectedItemUrl;
       if (url && this.previewImage_) {
         if (url.slice(0, CHROME_THEME_PATH.length) == CHROME_THEME_PATH)
-          this.previewImage_.src = url + '@' + window.devicePixelRatio + 'x';
+          this.previewImage_.src = url + '@2x';
         else
           this.previewImage_.src = url;
       }
diff --git a/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs b/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs
deleted file mode 100644
index bc3524b..0000000
--- a/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @param {!Array<string>} list
- * @return {string}
- */
-function str(list) {
-  return JSON.stringify(list);
-}
-
-var ActionServiceUnitTest = class extends testing.Test {
-  /** @override */
-  get extraLibraries() {
-    return [
-      '../../../../ui/webui/resources/js/cr.js',
-      'browser_proxy.js',
-      'action_service.js',
-    ];
-  }
-}
-
-TEST_F('ActionServiceUnitTest', 'splitTerms', function() {
-  const ActionService = downloads.ActionService;
-  assertEquals(str([]), str(ActionService.splitTerms('')));
-  assertEquals(str([]), str(ActionService.splitTerms('  ')));
-  assertEquals(str(['a']), str(ActionService.splitTerms('a')));
-  assertEquals(str(['a b']), str(ActionService.splitTerms('a b')));
-  assertEquals(str(['a', 'b']), str(ActionService.splitTerms('a "b"')));
-  assertEquals(str(['a', 'b', 'c']), str(ActionService.splitTerms('a "b" c')));
-  assertEquals(str(['a', 'b b', 'c']),
-               str(ActionService.splitTerms('a "b b" c')));
-});
-
-TEST_F('ActionServiceUnitTest', 'searchWithSimilarTerms', function() {
-  class TestActionService extends downloads.ActionService {
-    loadMore() { /* No chrome.send() for you! */ }
-  }
-
-  const actionService = new TestActionService();
-
-  assertTrue(actionService.search('a'));
-  assertFalse(actionService.search('a '));  // Same term + space should no-op.
-});
diff --git a/chrome/browser/resources/md_downloads/compiled_resources2.gyp b/chrome/browser/resources/md_downloads/compiled_resources2.gyp
index 19accde0..b9e2ca90 100644
--- a/chrome/browser/resources/md_downloads/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_downloads/compiled_resources2.gyp
@@ -4,15 +4,6 @@
 {
   'targets': [
     {
-      'target_name': 'action_service',
-      'dependencies': [
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
-        'browser_proxy',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-    {
       'target_name': 'browser_proxy',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
@@ -58,9 +49,9 @@
         '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
         '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command',
         '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-list/compiled_resources2.gyp:iron-list-extracted',
-        'action_service',
         'browser_proxy',
         'item',
+        'search_service',
         'toolbar',
         '<(EXTERNS_GYP):chrome_send',
         'externs',
@@ -68,6 +59,15 @@
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
+      'target_name': 'search_service',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
+        'browser_proxy',
+      ],
+      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'toolbar',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
@@ -76,8 +76,8 @@
         '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar',
         '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/compiled_resources2.gyp:iron-a11y-announcer-extracted',
         '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-menu/compiled_resources2.gyp:paper-menu-extracted',
-        'action_service',
         'browser_proxy',
+        'search_service',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/chrome/browser/resources/md_downloads/manager.html b/chrome/browser/resources/md_downloads/manager.html
index ef56219..15d99c4 100644
--- a/chrome/browser/resources/md_downloads/manager.html
+++ b/chrome/browser/resources/md_downloads/manager.html
@@ -7,11 +7,11 @@
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
-<link rel="import" href="chrome://downloads/action_service.html">
 <link rel="import" href="chrome://downloads/browser_proxy.html">
 <link rel="import" href="chrome://downloads/constants.html">
 <link rel="import" href="chrome://downloads/i18n_setup.html">
 <link rel="import" href="chrome://downloads/item.html">
+<link rel="import" href="chrome://downloads/search_service.html">
 <link rel="import" href="chrome://downloads/toolbar.html">
 
 <dom-module id="downloads-manager">
diff --git a/chrome/browser/resources/md_downloads/manager.js b/chrome/browser/resources/md_downloads/manager.js
index f6471eafb..54ae328 100644
--- a/chrome/browser/resources/md_downloads/manager.js
+++ b/chrome/browser/resources/md_downloads/manager.js
@@ -58,8 +58,8 @@
     /** @private {?downloads.BrowserProxy} */
     browserProxy_: null,
 
-    /** @private {?downloads.ActionService} */
-    actionService_: null,
+    /** @private {?downloads.SearchService} */
+    searchService_: null,
 
     /** @private {!PromiseResolver} */
     loaded_: new PromiseResolver,
@@ -67,7 +67,7 @@
     /** @override */
     created: function() {
       this.browserProxy_ = downloads.BrowserProxy.getInstance();
-      this.actionService_ = downloads.ActionService.getInstance();
+      this.searchService_ = downloads.SearchService.getInstance();
     },
 
     /** @override */
@@ -167,7 +167,7 @@
       const list = this.$['downloads-list'];
       if (list.scrollHeight - list.scrollTop - list.offsetHeight <= 100) {
         // Approaching the end of the scrollback. Attempt to load more items.
-        this.actionService_.loadMore();
+        this.searchService_.loadMore();
       }
       this.hasShadow_ = list.scrollTop > 0;
     },
@@ -181,13 +181,13 @@
       document.addEventListener('canExecute', this.onCanExecute_.bind(this));
       document.addEventListener('command', this.onCommand_.bind(this));
 
-      this.actionService_.loadMore();
+      this.searchService_.loadMore();
       return this.loaded_.promise;
     },
 
     /** @private */
     onSearchChanged_: function() {
-      this.inSearchMode_ = this.actionService_.isSearching();
+      this.inSearchMode_ = this.searchService_.isSearching();
     },
 
     /**
diff --git a/chrome/browser/resources/md_downloads/action_service.html b/chrome/browser/resources/md_downloads/search_service.html
similarity index 75%
rename from chrome/browser/resources/md_downloads/action_service.html
rename to chrome/browser/resources/md_downloads/search_service.html
index 7d59ba9e..f37b195 100644
--- a/chrome/browser/resources/md_downloads/action_service.html
+++ b/chrome/browser/resources/md_downloads/search_service.html
@@ -1,4 +1,4 @@
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://downloads/i18n_setup.html">
 <link rel="import" href="chrome://downloads/browser_proxy.html">
-<script src="chrome://downloads/action_service.js"></script>
+<script src="chrome://downloads/search_service.js"></script>
diff --git a/chrome/browser/resources/md_downloads/action_service.js b/chrome/browser/resources/md_downloads/search_service.js
similarity index 89%
rename from chrome/browser/resources/md_downloads/action_service.js
rename to chrome/browser/resources/md_downloads/search_service.js
index 67e515c..991c3528 100644
--- a/chrome/browser/resources/md_downloads/action_service.js
+++ b/chrome/browser/resources/md_downloads/search_service.js
@@ -3,8 +3,7 @@
 // found in the LICENSE file.
 
 cr.define('downloads', function() {
-  // TODO(dpapad): Rename to SearchService.
-  class ActionService {
+  class SearchService {
     constructor() {
       /** @private {!Array<string>} */
       this.searchTerms_ = [];
@@ -48,7 +47,7 @@
      * @return {boolean} Whether |searchText| resulted in new search terms.
      */
     search(searchText) {
-      const searchTerms = ActionService.splitTerms(searchText);
+      const searchTerms = SearchService.splitTerms(searchText);
       let sameTerms = searchTerms.length == this.searchTerms_.length;
 
       for (let i = 0; sameTerms && i < searchTerms.length; ++i) {
@@ -65,7 +64,7 @@
     }
   }
 
-  cr.addSingletonGetter(ActionService);
+  cr.addSingletonGetter(SearchService);
 
-  return {ActionService: ActionService};
+  return {SearchService: SearchService};
 });
diff --git a/chrome/browser/resources/md_downloads/search_service_unittest.gtestjs b/chrome/browser/resources/md_downloads/search_service_unittest.gtestjs
new file mode 100644
index 0000000..190c98e3
--- /dev/null
+++ b/chrome/browser/resources/md_downloads/search_service_unittest.gtestjs
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @param {!Array<string>} list
+ * @return {string}
+ */
+function str(list) {
+  return JSON.stringify(list);
+}
+
+var SearchServiceUnitTest = class extends testing.Test {
+  /** @override */
+  get extraLibraries() {
+    return [
+      '../../../../ui/webui/resources/js/cr.js',
+      'browser_proxy.js',
+      'search_service.js',
+    ];
+  }
+}
+
+TEST_F('SearchServiceUnitTest', 'splitTerms', function() {
+  const SearchService = downloads.SearchService;
+  assertEquals(str([]), str(SearchService.splitTerms('')));
+  assertEquals(str([]), str(SearchService.splitTerms('  ')));
+  assertEquals(str(['a']), str(SearchService.splitTerms('a')));
+  assertEquals(str(['a b']), str(SearchService.splitTerms('a b')));
+  assertEquals(str(['a', 'b']), str(SearchService.splitTerms('a "b"')));
+  assertEquals(str(['a', 'b', 'c']), str(SearchService.splitTerms('a "b" c')));
+  assertEquals(str(['a', 'b b', 'c']),
+               str(SearchService.splitTerms('a "b b" c')));
+});
+
+TEST_F('SearchServiceUnitTest', 'searchWithSimilarTerms', function() {
+  class TestSearchService extends downloads.SearchService {
+    loadMore() { /* No chrome.send() for you! */ }
+  }
+
+  const searchService = new TestSearchService();
+
+  assertTrue(searchService.search('a'));
+  assertFalse(searchService.search('a '));  // Same term + space should no-op.
+});
diff --git a/chrome/browser/resources/md_downloads/toolbar.html b/chrome/browser/resources/md_downloads/toolbar.html
index e53051b..2985c1d0 100644
--- a/chrome/browser/resources/md_downloads/toolbar.html
+++ b/chrome/browser/resources/md_downloads/toolbar.html
@@ -1,6 +1,6 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
-<link rel="import" href="chrome://downloads/action_service.html">
+<link rel="import" href="chrome://downloads/search_service.html">
 <link rel="import" href="chrome://downloads/browser_proxy.html">
 <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
diff --git a/chrome/browser/resources/md_downloads/toolbar.js b/chrome/browser/resources/md_downloads/toolbar.js
index a542050d..e3a2329 100644
--- a/chrome/browser/resources/md_downloads/toolbar.js
+++ b/chrome/browser/resources/md_downloads/toolbar.js
@@ -69,9 +69,9 @@
      * @private
      */
     onSearchChanged_: function(event) {
-      const actionService = downloads.ActionService.getInstance();
-      if (actionService.search(/** @type {string} */ (event.detail)))
-        this.spinnerActive = actionService.isSearching();
+      const searchService = downloads.SearchService.getInstance();
+      if (searchService.search(/** @type {string} */ (event.detail)))
+        this.spinnerActive = searchService.isSearching();
       this.updateClearAll_();
     },
 
diff --git a/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc b/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
index 702887c..7346aea9 100644
--- a/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
+++ b/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
@@ -114,10 +114,6 @@
   source->AddResourcePath("crisper.js", IDR_MD_DOWNLOADS_CRISPER_JS);
   source->SetDefaultResource(IDR_MD_DOWNLOADS_VULCANIZED_HTML);
 #else
-  source->AddResourcePath("action_service.html",
-                          IDR_MD_DOWNLOADS_ACTION_SERVICE_HTML);
-  source->AddResourcePath("action_service.js",
-                          IDR_MD_DOWNLOADS_ACTION_SERVICE_JS);
   source->AddResourcePath("browser_proxy.html",
                           IDR_MD_DOWNLOADS_BROWSER_PROXY_HTML);
   source->AddResourcePath("browser_proxy.js",
@@ -131,6 +127,10 @@
   source->AddResourcePath("item.js", IDR_MD_DOWNLOADS_ITEM_JS);
   source->AddResourcePath("manager.html", IDR_MD_DOWNLOADS_MANAGER_HTML);
   source->AddResourcePath("manager.js", IDR_MD_DOWNLOADS_MANAGER_JS);
+  source->AddResourcePath("search_service.html",
+                          IDR_MD_DOWNLOADS_SEARCH_SERVICE_HTML);
+  source->AddResourcePath("search_service.js",
+                          IDR_MD_DOWNLOADS_SEARCH_SERVICE_JS);
   source->AddResourcePath("toolbar.html", IDR_MD_DOWNLOADS_TOOLBAR_HTML);
   source->AddResourcePath("toolbar.js", IDR_MD_DOWNLOADS_TOOLBAR_JS);
   source->SetDefaultResource(IDR_MD_DOWNLOADS_DOWNLOADS_HTML);
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index d0afce3..ac904b3c 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -313,16 +313,14 @@
 }
 
 TEST_F(SiteSettingsHandlerTest, Origins) {
-  const std::string google_with_port("https://www.google.com:443");
-  // The display name won't show the port if it's default for that scheme.
-  const std::string google("https://www.google.com");
+  const std::string google("https://www.google.com:443");
   const std::string kUmaBase("WebsiteSettings.Menu.PermissionChanged");
   {
     // Test the JS -> C++ -> JS callback path for configuring origins, by
     // setting Google.com to blocked.
     base::ListValue set_args;
-    set_args.AppendString(google_with_port);  // Primary pattern.
-    set_args.AppendString(google_with_port);  // Secondary pattern.
+    set_args.AppendString(google);  // Primary pattern.
+    set_args.AppendString(google);  // Secondary pattern.
     set_args.AppendString(kNotifications);
     set_args.AppendString(
         content_settings::ContentSettingToString(CONTENT_SETTING_BLOCK));
@@ -340,15 +338,14 @@
   get_exception_list_args.AppendString(kCallbackId);
   get_exception_list_args.AppendString(kNotifications);
   handler()->HandleGetExceptionList(&get_exception_list_args);
-  ValidateOrigin(google_with_port, google_with_port, google,
-                 CONTENT_SETTING_BLOCK,
+  ValidateOrigin(google, google, google, CONTENT_SETTING_BLOCK,
                  site_settings::SiteSettingSource::kPreference, 2U);
 
   {
     // Reset things back to how they were.
     base::ListValue reset_args;
-    reset_args.AppendString(google_with_port);
-    reset_args.AppendString(google_with_port);
+    reset_args.AppendString(google);
+    reset_args.AppendString(google);
     reset_args.AppendString(kNotifications);
     reset_args.AppendBoolean(false);  // Incognito.
     base::HistogramTester histograms;
@@ -429,22 +426,25 @@
 }
 
 TEST_F(SiteSettingsHandlerTest, GetAndSetOriginPermissions) {
+  const std::string origin_with_port("https://www.example.com:443");
+  // The display name won't show the port if it's default for that scheme.
   const std::string origin("https://www.example.com");
   base::ListValue get_args;
   get_args.AppendString(kCallbackId);
-  get_args.AppendString(origin);
+  get_args.AppendString(origin_with_port);
   {
     auto category_list = base::MakeUnique<base::ListValue>();
     category_list->AppendString(kNotifications);
     get_args.Append(std::move(category_list));
   }
   handler()->HandleGetOriginPermissions(&get_args);
-  ValidateOrigin(origin, origin, origin, CONTENT_SETTING_ASK,
+  ValidateOrigin(origin_with_port, origin_with_port, origin,
+                 CONTENT_SETTING_ASK,
                  site_settings::SiteSettingSource::kDefault, 1U);
 
   // Block notifications.
   base::ListValue set_args;
-  set_args.AppendString(origin);
+  set_args.AppendString(origin_with_port);
   {
     auto category_list = base::MakeUnique<base::ListValue>();
     category_list->AppendString(kNotifications);
@@ -457,7 +457,7 @@
 
   // Reset things back to how they were.
   base::ListValue reset_args;
-  reset_args.AppendString(origin);
+  reset_args.AppendString(origin_with_port);
   auto category_list = base::MakeUnique<base::ListValue>();
   category_list->AppendString(kNotifications);
   reset_args.Append(std::move(category_list));
@@ -469,7 +469,8 @@
 
   // Verify the reset was successful.
   handler()->HandleGetOriginPermissions(&get_args);
-  ValidateOrigin(origin, origin, origin, CONTENT_SETTING_ASK,
+  ValidateOrigin(origin_with_port, origin_with_port, origin,
+                 CONTENT_SETTING_ASK,
                  site_settings::SiteSettingSource::kDefault, 4U);
 }
 
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc
index 0fe3af7..01dc403 100644
--- a/chrome/browser/ui/webui/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -227,6 +227,21 @@
   return exception;
 }
 
+std::string GetDisplayNameForExtension(
+    const GURL& url,
+    const extensions::ExtensionRegistry* extension_registry) {
+  if (extension_registry && url.SchemeIs(extensions::kExtensionScheme)) {
+    // For the extension scheme, the pattern must be a valid URL.
+    DCHECK(url.is_valid());
+    const extensions::Extension* extension =
+        extension_registry->GetExtensionById(
+            url.host(), extensions::ExtensionRegistry::EVERYTHING);
+    if (extension)
+      return extension->name();
+  }
+  return std::string();
+}
+
 // Takes |url| and converts it into an individual origin string or retrieves
 // name of the extension it belongs to.
 std::string GetDisplayNameForGURL(
@@ -236,16 +251,13 @@
   if (origin.unique())
     return url.spec();
 
-  if (extension_registry && origin.scheme() == extensions::kExtensionScheme) {
-    const extensions::Extension* extension =
-        extension_registry->GetExtensionById(
-            origin.host(), extensions::ExtensionRegistry::EVERYTHING);
-    if (extension)
-      return extension->name();
-  }
+  std::string display_name =
+      GetDisplayNameForExtension(url, extension_registry);
+  if (!display_name.empty())
+    return display_name;
 
-  // Note that using Serialize() here will chop off any default port numbers
-  // which may be confusing to users.
+  // Note that using Serialize() here will chop off default port numbers and
+  // percent encode the origin.
   return origin.Serialize();
 }
 
@@ -255,9 +267,10 @@
     const ContentSettingsPattern& pattern,
     const extensions::ExtensionRegistry* extension_registry) {
   const GURL url(pattern.ToString());
-  url::Origin origin(url);
-  if (!origin.unique())
-    return GetDisplayNameForGURL(url, extension_registry);
+  const std::string extension_display_name =
+      GetDisplayNameForExtension(url, extension_registry);
+  if (!extension_display_name.empty())
+    return extension_display_name;
   return pattern.ToString();
 }
 
diff --git a/chrome/browser/ui/webui/site_settings_helper_unittest.cc b/chrome/browser/ui/webui/site_settings_helper_unittest.cc
index da813e6..cb9a40f 100644
--- a/chrome/browser/ui/webui/site_settings_helper_unittest.cc
+++ b/chrome/browser/ui/webui/site_settings_helper_unittest.cc
@@ -122,9 +122,7 @@
                 CONTENT_SETTING_BLOCK);
   VerifySetting(exceptions, i++, star_google_com, star_google_com,
                 CONTENT_SETTING_ALLOW);
-  // The display name will always be percent-encoded.
-  VerifySetting(exceptions, i++, http_star, "http://%2A",
-                CONTENT_SETTING_BLOCK);
+  VerifySetting(exceptions, i++, http_star, "http://*", CONTENT_SETTING_BLOCK);
 }
 
 // Tests the following content setting sources: Chrome default, user-set global
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn
index 7b2ee0c3..077e52d 100644
--- a/chrome/installer/linux/BUILD.gn
+++ b/chrome/installer/linux/BUILD.gn
@@ -66,11 +66,6 @@
   ]
   script = "debian/calculate_package_deps.py"
   sources = packaging_files_binaries
-  inputs = [
-    "debian/deb_version.py",
-    "debian/dist-package-versions.json",
-    "debian/package_version_interval.py",
-  ]
   outputs = [
     "$root_out_dir/deb_{{source_name_part}}.deps",
   ]
@@ -90,8 +85,6 @@
   additional_deps = "debian/additional_deps"
   inputs = [
     additional_deps,
-    "debian/deb_version.py",
-    "debian/package_version_interval.py",
   ]
   outputs = [
     "$root_out_dir/deb_common.deps",
@@ -110,9 +103,6 @@
   ]
   script = "rpm/calculate_package_deps.py"
   sources = packaging_files_binaries
-  inputs = [
-    "rpm/dist-package-provides.json",
-  ]
   outputs = [
     "$root_out_dir/rpm_{{source_name_part}}.deps",
   ]
@@ -128,17 +118,10 @@
     ":calculate_rpm_dependencies",
   ]
   script = "rpm/merge_package_deps.py"
-  additional_deps = "rpm/additional_deps"
-  inputs = [
-    additional_deps,
-  ]
   outputs = [
     "$root_out_dir/rpm_common.deps",
   ]
-  args = [
-    "rpm_common.deps",
-    rebase_path(additional_deps, root_build_dir),
-  ]
+  args = [ "rpm_common.deps" ]
   args += rebase_path(get_target_outputs(":calculate_rpm_dependencies"),
                       root_build_dir)
 }
@@ -281,6 +264,7 @@
     sources = [
       "rpm/build.sh",
       "rpm/chrome.spec.template",
+      "rpm/expected_deps_x86_64",
     ]
     outputs = [
       "$root_out_dir/installer/rpm/{{source_file_part}}",
@@ -439,7 +423,6 @@
       }
       deps = [
         ":installer_deps",
-        ":merge_rpm_dependencies",
       ]
     }
   }
diff --git a/chrome/installer/linux/rpm/additional_deps b/chrome/installer/linux/rpm/additional_deps
deleted file mode 100644
index 8335aa7..0000000
--- a/chrome/installer/linux/rpm/additional_deps
+++ /dev/null
@@ -1,33 +0,0 @@
-# lsb implies many dependencies and on Fedora or RHEL some of these are not
-# needed at all (the most obvious one is qt3) and Chrome is usually the one
-# who pulls them to the system by requiring the whole lsb. Require only
-# lsb_release from the lsb as that's the only thing that we are using.
-#
-# nss (bundled) is optional in LSB 4.0. Also specify a more recent version
-# for security and stability updates. While we depend on libnss3.so and not
-# libssl3.so, force the dependency on libssl3 to ensure the NSS version is
-# 3.28 or later, since libssl3 should always be packaged with libnss3.
-#
-# wget is for uploading crash reports with Breakpad.
-#
-# xdg-utils is still optional in LSB 4.0.
-#
-# zlib may not need to be there. It should be included with LSB.
-# TODO(thestig): Figure out why there is an entry for zlib.
-#
-# We want to depend on the system SSL certs so wget can upload crash reports
-# securely, but there's no common capability between the distros. Bugs filed:
-# https://qa.mandriva.com/show_bug.cgi?id=55714
-# https://bugzilla.redhat.com/show_bug.cgi?id=538158
-# https://bugzilla.novell.com/show_bug.cgi?id=556248
-#
-# We want to depend on liberation-fonts as well, but there is no such package
-# for Fedora. https://bugzilla.redhat.com/show_bug.cgi?id=1252564
-# TODO(thestig): Use the liberation-fonts package once its available on all
-# supported distros.
-/usr/bin/lsb_release
-libnss3.so(NSS_3.22)(64bit)
-libssl3.so(NSS_3.28)(64bit)
-wget
-xdg-utils
-zlib
diff --git a/chrome/installer/linux/rpm/build.sh b/chrome/installer/linux/rpm/build.sh
index e96bd9a..90f0dbf 100755
--- a/chrome/installer/linux/rpm/build.sh
+++ b/chrome/installer/linux/rpm/build.sh
@@ -102,8 +102,83 @@
   ADDITIONAL_CONFLICTS="xorg-x11-libX11 < 7.6_1 libX11 < 1.4.99"
   REPLACES="$REPLACES $ADDITIONAL_CONFLICTS"
 
-  RPM_COMMON_DEPS="${BUILDDIR}/rpm_common.deps"
-  DEPENDS=$(cat "${RPM_COMMON_DEPS}" | tr '\n' ',')
+  # If we specify a dependecy of foo.so below, we would depend on both the
+  # 32 and 64-bit versions on a 64-bit machine. The current version of RPM
+  # we use is too old and doesn't provide %{_isa}, so we do this manually.
+  if [ "$ARCHITECTURE" = "x86_64" ] ; then
+    local EMPTY_VERSION="()"
+    local PKG_ARCH="(64bit)"
+  elif [ "$ARCHITECTURE" = "i386" ] ; then
+    local EMPTY_VERSION=""
+    local PKG_ARCH=""
+  fi
+
+  # Use find-requires script to make sure the dependencies are complete
+  # (especially libc versions).
+  DETECTED_DEPENDS="$(echo "${BUILDDIR}/chrome" | /usr/lib/rpm/find-requires)"
+
+  # Compare the expected dependency list to the generated list.
+  #
+  # In this comparison, we allow ld-linux.so's symbol version "GLIBC_2.3"
+  # to be present but don't require it, because it is hard to predict
+  # whether it will be generated.  Referencing a __thread
+  # (thread-local/TLS) variable *sometimes* causes the compiler to generate
+  # a reference to __tls_get_addr() (depending on compiler options such as
+  # -fPIC vs. -fPIE).  This function has symbol version "GLIBC_2.3".  The
+  # linker *sometimes* optimizes away the __tls_get_addr() call using
+  # link-time code rewriting, but it might leave the symbol dependency in
+  # place -- there are no guarantees.
+  BAD_DIFF=0
+  if [ -r "$SCRIPTDIR/expected_deps_$ARCHITECTURE" ]; then
+    diff -u "$SCRIPTDIR/expected_deps_$ARCHITECTURE" \
+        <(echo "${DETECTED_DEPENDS}" | \
+          LANG=C sort | \
+          grep -v '^ld-linux.*\(GLIBC_2\.3\)') \
+        || BAD_DIFF=1
+  fi
+  if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then
+    echo
+    echo "ERROR: Shared library dependencies changed!"
+    echo "If this is intentional, please update:"
+    echo "chrome/installer/linux/rpm/expected_deps_x86_64"
+    echo
+    exit $BAD_DIFF
+  fi
+
+  # lsb implies many dependencies and on Fedora or RHEL some of these are not
+  # needed at all (the most obvious one is qt3) and Chrome is usually the one
+  # who pulls them to the system by requiring the whole lsb. Require only
+  # lsb_release from the lsb as that's the only thing that we are using.
+  #
+  # nss (bundled) is optional in LSB 4.0. Also specify a more recent version
+  # for security and stability updates. While we depend on libnss3.so and not
+  # libssl3.so, force the dependency on libssl3 to ensure the NSS version is
+  # 3.28 or later, since libssl3 should always be packaged with libnss3.
+  #
+  # wget is for uploading crash reports with Breakpad.
+  #
+  # xdg-utils is still optional in LSB 4.0.
+  #
+  # zlib may not need to be there. It should be included with LSB.
+  # TODO(thestig): Figure out why there is an entry for zlib.
+  #
+  # We want to depend on the system SSL certs so wget can upload crash reports
+  # securely, but there's no common capability between the distros. Bugs filed:
+  # https://qa.mandriva.com/show_bug.cgi?id=55714
+  # https://bugzilla.redhat.com/show_bug.cgi?id=538158
+  # https://bugzilla.novell.com/show_bug.cgi?id=556248
+  #
+  # We want to depend on liberation-fonts as well, but there is no such package
+  # for Fedora. https://bugzilla.redhat.com/show_bug.cgi?id=1252564
+  # TODO(thestig): Use the liberation-fonts package once its available on all
+  # supported distros.
+  DEPENDS="/usr/bin/lsb_release, \
+  libnss3.so(NSS_3.22)${PKG_ARCH}, \
+  libssl3.so(NSS_3.28)${PKG_ARCH}, \
+  wget, \
+  xdg-utils, \
+  zlib, \
+  $(echo "${DETECTED_DEPENDS}" | tr '\n' ',')"
   gen_spec
 
   # Create temporary rpmbuild dirs.
diff --git a/chrome/installer/linux/rpm/calculate_package_deps.py b/chrome/installer/linux/rpm/calculate_package_deps.py
index acb9485..8056613 100755
--- a/chrome/installer/linux/rpm/calculate_package_deps.py
+++ b/chrome/installer/linux/rpm/calculate_package_deps.py
@@ -29,18 +29,16 @@
   print 'stderr was ' + stderr
   sys.exit(1)
 
-requires = set([] if stdout == '' else stdout.rstrip('\n').split('\n'))
+requires = [] if stdout == '' else stdout.rstrip('\n').split('\n')
 
 script_dir = os.path.dirname(os.path.abspath(__file__))
 provides_file = open(os.path.join(script_dir, 'dist-package-provides.json'))
 distro_package_provides = json.load(provides_file)
 
-remove_requires = set()
 ret_code = 0
 for distro in distro_package_provides:
   for requirement in requires:
     if any([requirement.startswith(shlib) for shlib in bundled_shlibs]):
-      remove_requires.add(requirement)
       continue
     if requirement not in distro_package_provides[distro]:
       print >> sys.stderr, (
@@ -49,8 +47,6 @@
       ret_code = 1
       continue
 if ret_code == 0:
-  requires = requires.difference(remove_requires)
   with open(dep_filename, 'w') as dep_file:
-    for requirement in sorted(list(requires)):
-      dep_file.write(requirement + '\n')
+    dep_file.write(stdout)
 sys.exit(ret_code)
diff --git a/chrome/installer/linux/rpm/expected_deps_x86_64 b/chrome/installer/linux/rpm/expected_deps_x86_64
new file mode 100644
index 0000000..f14195dc
--- /dev/null
+++ b/chrome/installer/linux/rpm/expected_deps_x86_64
@@ -0,0 +1,61 @@
+ld-linux-x86-64.so.2()(64bit)
+ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)
+libX11-xcb.so.1()(64bit)
+libX11.so.6()(64bit)
+libXcomposite.so.1()(64bit)
+libXcursor.so.1()(64bit)
+libXdamage.so.1()(64bit)
+libXext.so.6()(64bit)
+libXfixes.so.3()(64bit)
+libXi.so.6()(64bit)
+libXrandr.so.2()(64bit)
+libXrender.so.1()(64bit)
+libXss.so.1()(64bit)
+libXtst.so.6()(64bit)
+libasound.so.2()(64bit)
+libatk-1.0.so.0()(64bit)
+libc.so.6()(64bit)
+libc.so.6(GLIBC_2.11)(64bit)
+libc.so.6(GLIBC_2.14)(64bit)
+libc.so.6(GLIBC_2.15)(64bit)
+libc.so.6(GLIBC_2.2.5)(64bit)
+libc.so.6(GLIBC_2.3)(64bit)
+libc.so.6(GLIBC_2.3.2)(64bit)
+libc.so.6(GLIBC_2.3.3)(64bit)
+libc.so.6(GLIBC_2.3.4)(64bit)
+libc.so.6(GLIBC_2.4)(64bit)
+libc.so.6(GLIBC_2.6)(64bit)
+libc.so.6(GLIBC_2.7)(64bit)
+libc.so.6(GLIBC_2.9)(64bit)
+libcairo.so.2()(64bit)
+libcups.so.2()(64bit)
+libdbus-1.so.3()(64bit)
+libdl.so.2()(64bit)
+libdl.so.2(GLIBC_2.2.5)(64bit)
+libexpat.so.1()(64bit)
+libfontconfig.so.1()(64bit)
+libgcc_s.so.1()(64bit)
+libgcc_s.so.1(GCC_3.0)(64bit)
+libgconf-2.so.4()(64bit)
+libgdk-3.so.0()(64bit)
+libgdk_pixbuf-2.0.so.0()(64bit)
+libgio-2.0.so.0()(64bit)
+libglib-2.0.so.0()(64bit)
+libgmodule-2.0.so.0()(64bit)
+libgobject-2.0.so.0()(64bit)
+libgtk-3.so.0()(64bit)
+libm.so.6()(64bit)
+libm.so.6(GLIBC_2.2.5)(64bit)
+libnspr4.so()(64bit)
+libnss3.so()(64bit)
+libnssutil3.so()(64bit)
+libpango-1.0.so.0()(64bit)
+libpangocairo-1.0.so.0()(64bit)
+libpthread.so.0()(64bit)
+libpthread.so.0(GLIBC_2.2.5)(64bit)
+libpthread.so.0(GLIBC_2.3.2)(64bit)
+libpthread.so.0(GLIBC_2.3.3)(64bit)
+librt.so.1()(64bit)
+librt.so.1(GLIBC_2.2.5)(64bit)
+libsmime3.so()(64bit)
+libxcb.so.1()(64bit)
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index c382ce4..e0e4b65b 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -140,17 +140,17 @@
 js2gtest("unit_tests_js") {
   test_type = "unit"
   sources = [
-    "../../../browser/resources/md_downloads/action_service_unittest.gtestjs",
+    "../../../browser/resources/md_downloads/search_service_unittest.gtestjs",
     "../../../browser/resources/print_preview/data/measurement_system_unittest.gtestjs",
     "../../../browser/resources/print_preview/print_preview_utils_unittest.gtestjs",
     "../../../renderer/resources/extensions/notifications_custom_bindings.gtestjs",
     "../unit/framework_unittest.gtestjs",
   ]
   extra_js_files = [
-    "../../../browser/resources/md_downloads/action_service.js",
     "../../../browser/resources/md_downloads/browser_proxy.js",
     "../../../browser/resources/print_preview/data/measurement_system.js",
     "../../../browser/resources/print_preview/print_preview_utils.js",
+    "../../../browser/resources/md_downloads/search_service.js",
     "../../../renderer/resources/extensions/notifications_custom_bindings.js",
     "../../../renderer/resources/extensions/notifications_test_util.js",
     "//ui/webui/resources/js/cr.js",
diff --git a/chrome/test/data/webui/md_downloads/toolbar_tests.js b/chrome/test/data/webui/md_downloads/toolbar_tests.js
index 7ad60c62..4335c62 100644
--- a/chrome/test/data/webui/md_downloads/toolbar_tests.js
+++ b/chrome/test/data/webui/md_downloads/toolbar_tests.js
@@ -7,12 +7,12 @@
   let toolbar;
 
   setup(function() {
-    class TestActionService extends downloads.ActionService {
+    class TestSearchService extends downloads.SearchService {
       loadMore() { /* Prevent chrome.send(). */ }
     }
 
     toolbar = document.createElement('downloads-toolbar');
-    downloads.ActionService.instance_ = new TestActionService;
+    downloads.SearchService.instance_ = new TestSearchService;
     document.body.appendChild(toolbar);
   });
 
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 65e46991..20a8b24 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -43,6 +43,8 @@
     "lock_screen/arc_lock_screen_bridge.h",
     "metrics/arc_metrics_service.cc",
     "metrics/arc_metrics_service.h",
+    "midis/arc_midis_bridge.cc",
+    "midis/arc_midis_bridge.h",
     "net/arc_net_host_impl.cc",
     "net/arc_net_host_impl.h",
     "obb_mounter/arc_obb_mounter_bridge.cc",
@@ -150,6 +152,7 @@
     "common/kiosk.mojom",
     "common/lock_screen.mojom",
     "common/metrics.mojom",
+    "common/midis.mojom",
     "common/net.mojom",
     "common/notifications.mojom",
     "common/obb_mounter.mojom",
diff --git a/components/arc/arc_bridge_host_impl.cc b/components/arc/arc_bridge_host_impl.cc
index 872e4107..7a19c67 100644
--- a/components/arc/arc_bridge_host_impl.cc
+++ b/components/arc/arc_bridge_host_impl.cc
@@ -170,6 +170,11 @@
   OnInstanceReady(arc_bridge_service_->metrics(), std::move(metrics_ptr));
 }
 
+void ArcBridgeHostImpl::OnMidisInstanceReady(
+    mojom::MidisInstancePtr midis_ptr) {
+  OnInstanceReady(arc_bridge_service_->midis(), std::move(midis_ptr));
+}
+
 void ArcBridgeHostImpl::OnNetInstanceReady(mojom::NetInstancePtr net_ptr) {
   OnInstanceReady(arc_bridge_service_->net(), std::move(net_ptr));
 }
diff --git a/components/arc/arc_bridge_host_impl.h b/components/arc/arc_bridge_host_impl.h
index 9e79bee..bbab05e 100644
--- a/components/arc/arc_bridge_host_impl.h
+++ b/components/arc/arc_bridge_host_impl.h
@@ -64,6 +64,7 @@
   void OnLockScreenInstanceReady(
       mojom::LockScreenInstancePtr lock_screen_ptr) override;
   void OnMetricsInstanceReady(mojom::MetricsInstancePtr metrics_ptr) override;
+  void OnMidisInstanceReady(mojom::MidisInstancePtr midis_ptr) override;
   void OnNetInstanceReady(mojom::NetInstancePtr net_ptr) override;
   void OnNotificationsInstanceReady(
       mojom::NotificationsInstancePtr notifications_ptr) override;
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index 2c446c4f..c503382 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -30,6 +30,7 @@
 class KioskInstance;
 class LockScreenInstance;
 class MetricsInstance;
+class MidisInstance;
 class NetInstance;
 class NotificationsInstance;
 class ObbMounterInstance;
@@ -88,6 +89,7 @@
     return &lock_screen_;
   }
   InstanceHolder<mojom::MetricsInstance>* metrics() { return &metrics_; }
+  InstanceHolder<mojom::MidisInstance>* midis() { return &midis_; }
   InstanceHolder<mojom::NetInstance>* net() { return &net_; }
   InstanceHolder<mojom::NotificationsInstance>* notifications() {
     return &notifications_;
@@ -136,6 +138,7 @@
   InstanceHolder<mojom::KioskInstance> kiosk_;
   InstanceHolder<mojom::LockScreenInstance> lock_screen_;
   InstanceHolder<mojom::MetricsInstance> metrics_;
+  InstanceHolder<mojom::MidisInstance> midis_;
   InstanceHolder<mojom::NetInstance> net_;
   InstanceHolder<mojom::NotificationsInstance> notifications_;
   InstanceHolder<mojom::ObbMounterInstance> obb_mounter_;
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom
index 160c87bd0..86872309 100644
--- a/components/arc/common/arc_bridge.mojom
+++ b/components/arc/common/arc_bridge.mojom
@@ -20,6 +20,7 @@
 import "kiosk.mojom";
 import "lock_screen.mojom";
 import "metrics.mojom";
+import "midis.mojom";
 import "net.mojom";
 import "notifications.mojom";
 import "obb_mounter.mojom";
@@ -37,9 +38,9 @@
 import "volume_mounter.mojom";
 import "wallpaper.mojom";
 
-// Next MinVersion: 30
+// Next MinVersion: 31
 // Deprecated method IDs: 101, 105
-// Next method ID: 135
+// Next method ID: 136
 interface ArcBridgeHost {
   // Keep the entries alphabetical. In order to do so without breaking
   // compatibility with the ARC instance, explicitly assign each interface a
@@ -100,6 +101,9 @@
   // Notifies Chrome that the MetricsInstance interface is ready.
   [MinVersion=10] OnMetricsInstanceReady@116(MetricsInstance instance_ptr);
 
+  // Notifies Chrome that the MidisInstance interface is ready.
+  [MinVersion=30] OnMidisInstanceReady@135(MidisInstance instance_ptr);
+
   // Notifies Chrome that the NetInstance interface is ready.
   [MinVersion=5] OnNetInstanceReady@108(NetInstance instance_ptr);
 
diff --git a/components/arc/common/midis.mojom b/components/arc/common/midis.mojom
new file mode 100644
index 0000000..a0ca2ff9
--- /dev/null
+++ b/components/arc/common/midis.mojom
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file defines the mojo interface between Android, Chrome and the
+// Chrome OS daemon for the MIDI implementation used in ARC.
+
+module arc.mojom;
+
+// This interface is needed to get the actual MidisManager interface handle.
+// Next Method ID: 1
+interface MidisHost {
+  // This is used by a client to register with midis and is used to connect
+  // the client handle with the server and vice-versa.
+  // Once implemented, this call will have two arguments:
+  //  - a pointer to server interface handle (used to call server functions).
+  //  - a handle to the client interface (used to call client routines on
+  //    device related events like (dis)connections).
+  // It is currently a stub.
+  Connect@0();
+};
+
+// MidisInstance is implemented in the ARC MIDI JNI code that
+// runs in Android and handles the Android side of the ArcBridge connection.
+// Next Method ID: 1
+interface MidisInstance {
+  Init@0(MidisHost host_ptr);
+};
diff --git a/components/arc/midis/arc_midis_bridge.cc b/components/arc/midis/arc_midis_bridge.cc
new file mode 100644
index 0000000..2aa3d79d
--- /dev/null
+++ b/components/arc/midis/arc_midis_bridge.cc
@@ -0,0 +1,116 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/midis/arc_midis_bridge.h"
+
+#include "base/bind.h"
+#include "base/memory/singleton.h"
+#include "chromeos/dbus/arc_midis_client.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
+#include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/edk/embedder/scoped_platform_handle.h"
+
+namespace arc {
+namespace {
+
+// Singleton factory for ArcMidisBridge
+class ArcMidisBridgeFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcMidisBridge,
+          ArcMidisBridgeFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcMidisBridgeFactory";
+
+  static ArcMidisBridgeFactory* GetInstance() {
+    return base::Singleton<ArcMidisBridgeFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcMidisBridgeFactory>;
+  ArcMidisBridgeFactory() = default;
+  ~ArcMidisBridgeFactory() override = default;
+};
+
+}  // namespace
+
+// static
+ArcMidisBridge* ArcMidisBridge::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcMidisBridgeFactory::GetForBrowserContext(context);
+}
+
+ArcMidisBridge::ArcMidisBridge(content::BrowserContext* context,
+                               ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service), binding_(this), weak_factory_(this) {
+  arc_bridge_service_->midis()->AddObserver(this);
+}
+
+ArcMidisBridge::~ArcMidisBridge() {
+  arc_bridge_service_->midis()->RemoveObserver(this);
+}
+
+void ArcMidisBridge::OnInstanceReady() {
+  DVLOG(1) << "ArcMidisBridge::OnInstanceReady() called.";
+  mojom::MidisInstance* midis_instance =
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->midis(), Init);
+  DCHECK(midis_instance);
+
+  DVLOG(1) << "Calling Init on the other side of MidisInstance.";
+  mojom::MidisHostPtr host_proxy;
+  binding_.Bind(mojo::MakeRequest(&host_proxy));
+  midis_instance->Init(std::move(host_proxy));
+  binding_.set_connection_error_handler(base::Bind(
+      &mojo::Binding<MidisHost>::Close, base::Unretained(&binding_)));
+}
+
+void ArcMidisBridge::OnBootstrapMojoConnection(
+    chromeos::DBusMethodCallStatus result) {
+  if (result != chromeos::DBUS_METHOD_CALL_SUCCESS) {
+    LOG(ERROR) << "ArcMidisBridge had a failure in D-Bus with the daemon.";
+    midis_host_ptr_.reset();
+    return;
+  }
+  DVLOG(1) << "ArcMidisBridge succeeded with Mojo bootstrapping.";
+  midis_host_ptr_->Connect();
+}
+
+void ArcMidisBridge::Connect() {
+  DVLOG(1) << "ArcMidisBridge::Connect called.";
+  if (midis_host_ptr_.is_bound()) {
+    DVLOG(1) << "Re-using bootstrap connection for MidisService Connect.";
+    midis_host_ptr_->Connect();
+    return;
+  }
+  DVLOG(1) << "Bootstrapping the Midis connection via D-Bus.";
+  mojo::edk::OutgoingBrokerClientInvitation invitation;
+  mojo::edk::PlatformChannelPair channel_pair;
+  mojo::ScopedMessagePipeHandle server_pipe =
+      invitation.AttachMessagePipe("arc-midis-pipe");
+  invitation.Send(
+      base::kNullProcessHandle,
+      mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
+                                  channel_pair.PassServerHandle()));
+  mojo::edk::ScopedPlatformHandle child_handle =
+      channel_pair.PassClientHandle();
+  base::ScopedFD fd(child_handle.release().handle);
+
+  midis_host_ptr_.Bind(
+      mojo::InterfacePtrInfo<mojom::MidisHost>(std::move(server_pipe), 0u));
+  DVLOG(1) << "Bound remote MidisHost interface to pipe.";
+  midis_host_ptr_.set_connection_error_handler(
+      base::Bind(&mojo::InterfacePtr<mojom::MidisHost>::reset,
+                 base::Unretained(&midis_host_ptr_)));
+  chromeos::DBusThreadManager::Get()
+      ->GetArcMidisClient()
+      ->BootstrapMojoConnection(
+          std::move(fd), base::Bind(&ArcMidisBridge::OnBootstrapMojoConnection,
+                                    weak_factory_.GetWeakPtr()));
+}
+
+}  // namespace arc
diff --git a/components/arc/midis/arc_midis_bridge.h b/components/arc/midis/arc_midis_bridge.h
new file mode 100644
index 0000000..a816eece
--- /dev/null
+++ b/components/arc/midis/arc_midis_bridge.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_ARC_MIDIS_ARC_MIDIS_BRIDGE_H_
+#define COMPONENTS_ARC_MIDIS_ARC_MIDIS_BRIDGE_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "chromeos/dbus/dbus_method_call_status.h"
+#include "components/arc/common/midis.mojom.h"
+#include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace arc {
+
+class ArcBridgeService;
+
+class ArcMidisBridge : public KeyedService,
+                       public InstanceHolder<mojom::MidisInstance>::Observer,
+                       public mojom::MidisHost {
+ public:
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcMidisBridge* GetForBrowserContext(content::BrowserContext* context);
+
+  ArcMidisBridge(content::BrowserContext* context,
+                 ArcBridgeService* bridge_service);
+  ~ArcMidisBridge() override;
+
+  // Overridden from InstanceHolder<mojom::MidisInstance>::Observer:
+  void OnInstanceReady() override;
+
+  // Midis Mojo host interface
+  void Connect() override;
+
+ private:
+  void OnBootstrapMojoConnection(chromeos::DBusMethodCallStatus result);
+
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
+  mojo::Binding<mojom::MidisHost> binding_;
+  mojom::MidisHostPtr midis_host_ptr_;
+
+  // WeakPtrFactory to use for callbacks.
+  base::WeakPtrFactory<ArcMidisBridge> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcMidisBridge);
+};
+
+}  // namespace arc
+
+#endif  // COMPONENTS_ARC_MIDIS_ARC_MIDIS_BRIDGE_H_
diff --git a/components/history/core/browser/top_sites_impl.cc b/components/history/core/browser/top_sites_impl.cc
index a3b5149..43e0687 100644
--- a/components/history/core/browser/top_sites_impl.cc
+++ b/components/history/core/browser/top_sites_impl.cc
@@ -80,12 +80,6 @@
                      });
 }
 
-// How many non-forced top sites to store in the cache.
-const size_t kNonForcedTopSitesNumber = 20;
-
-// How many forced top sites to store in the cache.
-const size_t kForcedTopSitesNumber = 20;
-
 // Max number of temporary images we'll cache. See comment above
 // temp_images_ for details.
 const size_t kMaxTempTopImages = 8;
diff --git a/components/history/core/browser/top_sites_impl.h b/components/history/core/browser/top_sites_impl.h
index e8d1023..c60f9b4be 100644
--- a/components/history/core/browser/top_sites_impl.h
+++ b/components/history/core/browser/top_sites_impl.h
@@ -57,6 +57,12 @@
   // callable multiple time and during the whole lifetime of TopSitesImpl.
   using CanAddURLToHistoryFn = base::Callback<bool(const GURL&)>;
 
+  // How many non-forced top sites to store in the cache.
+  static constexpr size_t kNonForcedTopSitesNumber = 10;
+
+  // How many forced top sites to store in the cache.
+  static constexpr size_t kForcedTopSitesNumber = 10;
+
   TopSitesImpl(PrefService* pref_service,
                HistoryService* history_service,
                const PrepopulatedPageList& prepopulated_pages,
diff --git a/components/history/core/browser/top_sites_impl_unittest.cc b/components/history/core/browser/top_sites_impl_unittest.cc
index 3ef72e53..59134af 100644
--- a/components/history/core/browser/top_sites_impl_unittest.cc
+++ b/components/history/core/browser/top_sites_impl_unittest.cc
@@ -484,7 +484,7 @@
   AppendMostVisitedURL(gets_moved_1, &new_list);    // 3  (moved from 2)
 
   history::TopSitesDelta delta;
-  history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
+  TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
 
   ASSERT_EQ(2u, delta.added.size());
   EXPECT_TRUE(gets_added_1 == delta.added[0].url.url);
@@ -538,8 +538,8 @@
   AppendMostVisitedURL(gets_added_2, &new_list);
   AppendMostVisitedURL(gets_moved_1, &new_list);
 
-  history::TopSitesDelta delta;
-  history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
+  TopSitesDelta delta;
+  TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
 
   ASSERT_EQ(2u, delta.added.size());
   EXPECT_TRUE(gets_added_1 == delta.added[0].url.url);
@@ -1433,9 +1433,8 @@
   AppendForcedMostVisitedURL(GURL("http://oldforced/4"), 11000, &old_url_list);
   AppendForcedMostVisitedURL(GURL("http://oldforced/5"), 12000, &old_url_list);
   AppendForcedMostVisitedURL(GURL("http://oldforced/6"), 13000, &old_url_list);
-  AppendForcedMostVisitedURL(GURL("http://oldforced/7"), 18000, &old_url_list);
-  AppendForcedMostVisitedURL(GURL("http://oldforced/8"), 21000, &old_url_list);
-  const size_t kNumOldForcedURLs = 9;
+
+  const size_t kNumOldForcedURLs = old_url_list.size();
 
   // Create forced elements in new URL list.
   MostVisitedURLList new_url_list;
@@ -1448,14 +1447,12 @@
   AppendForcedMostVisitedURL(GURL("http://newforced/6"), 14000, &new_url_list);
   AppendForcedMostVisitedURL(GURL("http://newforced/7"), 15000, &new_url_list);
   AppendForcedMostVisitedURL(GURL("http://newforced/8"), 16000, &new_url_list);
-  AppendForcedMostVisitedURL(GURL("http://newforced/9"), 17000, &new_url_list);
-  AppendForcedMostVisitedURL(GURL("http://newforced/10"), 19000, &new_url_list);
-  AppendForcedMostVisitedURL(GURL("http://newforced/11"), 20000, &new_url_list);
-  AppendForcedMostVisitedURL(GURL("http://newforced/12"), 22000, &new_url_list);
+
+  const size_t kNonForcedTopSitesCount = TopSitesImpl::kNonForcedTopSitesNumber;
+  const size_t kForcedTopSitesCount = TopSitesImpl::kForcedTopSitesNumber;
 
   // Setup a number non-forced URLs in both old and new list.
-  const size_t kNumNonForcedURLs = 20;  // Maximum number of non-forced URLs.
-  for (size_t i = 0; i < kNumNonForcedURLs; ++i) {
+  for (size_t i = 0; i < kNonForcedTopSitesCount; ++i) {
     std::ostringstream url;
     url << "http://oldnonforced/" << i;
     AppendMostVisitedURL(GURL(url.str()), &old_url_list);
@@ -1466,19 +1463,20 @@
 
   // Set the initial list of URLs.
   SetTopSites(old_url_list);
-  EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, last_num_urls_changed());
+  EXPECT_EQ(kNumOldForcedURLs + kNonForcedTopSitesCount,
+            last_num_urls_changed());
 
   TopSitesQuerier querier;
   // Query only non-forced URLs first.
   querier.QueryTopSites(top_sites(), false);
-  ASSERT_EQ(kNumNonForcedURLs, querier.urls().size());
+  ASSERT_EQ(kNonForcedTopSitesCount, querier.urls().size());
 
   // Check first URL.
   EXPECT_EQ("http://oldnonforced/0", querier.urls()[0].url.spec());
 
   // Query all URLs.
   querier.QueryAllTopSites(top_sites(), false, true);
-  EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, querier.urls().size());
+  EXPECT_EQ(kNumOldForcedURLs + kNonForcedTopSitesCount, querier.urls().size());
 
   // Check first URLs.
   EXPECT_EQ("http://oldforced/0", querier.urls()[0].url.spec());
@@ -1491,57 +1489,42 @@
   // Query all URLs.
   querier.QueryAllTopSites(top_sites(), false, true);
 
-  // We should have reached the maximum of 20 forced URLs.
-  ASSERT_EQ(20 + kNumNonForcedURLs, querier.urls().size());
+  // We should have reached the maximum of forced URLs.
+  ASSERT_EQ(kForcedTopSitesCount + kNonForcedTopSitesCount,
+            querier.urls().size());
 
   // Check forced URLs. They follow the order of timestamps above, smaller
   // timestamps since they were evicted.
-  EXPECT_EQ("http://newforced/1", querier.urls()[0].url.spec());
-  EXPECT_EQ(3000, querier.urls()[0].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/1", querier.urls()[1].url.spec());
-  EXPECT_EQ(4000, querier.urls()[1].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/2", querier.urls()[2].url.spec());
-  EXPECT_EQ(5000, querier.urls()[2].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/3", querier.urls()[3].url.spec());
-  EXPECT_EQ(6000, querier.urls()[3].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/2", querier.urls()[4].url.spec());
-  EXPECT_EQ(7000, querier.urls()[4].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/4", querier.urls()[5].url.spec());
-  EXPECT_EQ(8000, querier.urls()[5].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/5", querier.urls()[6].url.spec());
-  EXPECT_EQ(9000, querier.urls()[6].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/3", querier.urls()[7].url.spec());
-  EXPECT_EQ(10000, querier.urls()[7].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/4", querier.urls()[8].url.spec());
-  EXPECT_EQ(11000, querier.urls()[8].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/5", querier.urls()[9].url.spec());
-  EXPECT_EQ(12000, querier.urls()[9].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/6", querier.urls()[10].url.spec());
-  EXPECT_EQ(13000, querier.urls()[10].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/6", querier.urls()[11].url.spec());
-  EXPECT_EQ(14000, querier.urls()[11].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/7", querier.urls()[12].url.spec());
-  EXPECT_EQ(15000, querier.urls()[12].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/8", querier.urls()[13].url.spec());
-  EXPECT_EQ(16000, querier.urls()[13].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/9", querier.urls()[14].url.spec());
-  EXPECT_EQ(17000, querier.urls()[14].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/7", querier.urls()[15].url.spec());
-  EXPECT_EQ(18000, querier.urls()[15].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/10", querier.urls()[16].url.spec());
-  EXPECT_EQ(19000, querier.urls()[16].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/11", querier.urls()[17].url.spec());
-  EXPECT_EQ(20000, querier.urls()[17].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://oldforced/8", querier.urls()[18].url.spec());
-  EXPECT_EQ(21000, querier.urls()[18].last_forced_time.ToJsTime());
-  EXPECT_EQ("http://newforced/12", querier.urls()[19].url.spec());
-  EXPECT_EQ(22000, querier.urls()[19].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://oldforced/2", querier.urls()[0].url.spec());
+  EXPECT_EQ(7000, querier.urls()[0].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://newforced/4", querier.urls()[1].url.spec());
+  EXPECT_EQ(8000, querier.urls()[1].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://newforced/5", querier.urls()[2].url.spec());
+  EXPECT_EQ(9000, querier.urls()[2].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://oldforced/3", querier.urls()[3].url.spec());
+  EXPECT_EQ(10000, querier.urls()[3].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://oldforced/4", querier.urls()[4].url.spec());
+  EXPECT_EQ(11000, querier.urls()[4].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://oldforced/5", querier.urls()[5].url.spec());
+  EXPECT_EQ(12000, querier.urls()[5].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://oldforced/6", querier.urls()[6].url.spec());
+  EXPECT_EQ(13000, querier.urls()[6].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://newforced/6", querier.urls()[7].url.spec());
+  EXPECT_EQ(14000, querier.urls()[7].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://newforced/7", querier.urls()[8].url.spec());
+  EXPECT_EQ(15000, querier.urls()[8].last_forced_time.ToJsTime());
+  EXPECT_EQ("http://newforced/8", querier.urls()[9].url.spec());
+  EXPECT_EQ(16000, querier.urls()[9].last_forced_time.ToJsTime());
 
   // Check first and last non-forced URLs.
-  EXPECT_EQ("http://newnonforced/0", querier.urls()[20].url.spec());
-  EXPECT_TRUE(querier.urls()[20].last_forced_time.is_null());
-  EXPECT_EQ("http://newnonforced/19", querier.urls()[39].url.spec());
-  EXPECT_TRUE(querier.urls()[39].last_forced_time.is_null());
+  EXPECT_EQ("http://newnonforced/0",
+            querier.urls()[kForcedTopSitesCount].url.spec());
+  EXPECT_TRUE(querier.urls()[kForcedTopSitesCount].last_forced_time.is_null());
+
+  size_t non_forced_end_index = querier.urls().size() - 1;
+  EXPECT_EQ("http://newnonforced/9",
+            querier.urls()[non_forced_end_index].url.spec());
+  EXPECT_TRUE(querier.urls()[non_forced_end_index].last_forced_time.is_null());
 }
 
 TEST_F(TopSitesImplTest, SetForcedTopSitesWithCollisions) {
diff --git a/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/OfflineItem.java b/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/OfflineItem.java
index 000f0a2..acb34e93 100644
--- a/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/OfflineItem.java
+++ b/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/OfflineItem.java
@@ -74,6 +74,7 @@
     @OfflineItemFilter
     public int filter;
     public boolean isTransient;
+    public boolean isSuggested;
 
     // Content Metadata.
     public long totalSizeBytes;
@@ -81,6 +82,8 @@
     public long creationTimeMs;
     public long lastAccessedTimeMs;
     public boolean isOpenable;
+    public String filePath;
+    public String mimeType;
 
     // Request Metadata.
     public String pageUrl;
diff --git a/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java b/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java
index 1b99def..faad725 100644
--- a/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java
+++ b/components/offline_items_collection/core/android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java
@@ -43,12 +43,12 @@
     @CalledByNative
     private static OfflineItem createOfflineItemAndMaybeAddToList(ArrayList<OfflineItem> list,
             String nameSpace, String id, String title, String description,
-            @OfflineItemFilter int filter, boolean isTransient, long totalSizeBytes,
-            boolean externallyRemoved, long creationTimeMs, long lastAccessedTimeMs,
-            boolean isOpenable, String pageUrl, String originalUrl, boolean isOffTheRecord,
-            @OfflineItemState int state, boolean isResumable, boolean allowMetered,
-            long receivedBytes, long progressValue, long progressMax,
-            @OfflineItemProgressUnit int progressUnit, long timeRemainingMs) {
+            @OfflineItemFilter int filter, boolean isTransient, boolean isSuggested,
+            long totalSizeBytes, boolean externallyRemoved, long creationTimeMs,
+            long lastAccessedTimeMs, boolean isOpenable, String filePath, String mimeType,
+            String pageUrl, String originalUrl, boolean isOffTheRecord, @OfflineItemState int state,
+            boolean isResumable, boolean allowMetered, long receivedBytes, long progressValue,
+            long progressMax, @OfflineItemProgressUnit int progressUnit, long timeRemainingMs) {
         OfflineItem item = new OfflineItem();
         item.id.namespace = nameSpace;
         item.id.id = id;
@@ -56,11 +56,14 @@
         item.description = description;
         item.filter = filter;
         item.isTransient = isTransient;
+        item.isSuggested = isSuggested;
         item.totalSizeBytes = totalSizeBytes;
         item.externallyRemoved = externallyRemoved;
         item.creationTimeMs = creationTimeMs;
         item.lastAccessedTimeMs = lastAccessedTimeMs;
         item.isOpenable = isOpenable;
+        item.filePath = filePath;
+        item.mimeType = mimeType;
         item.pageUrl = pageUrl;
         item.originalUrl = originalUrl;
         item.isOffTheRecord = isOffTheRecord;
diff --git a/components/offline_items_collection/core/android/offline_item_bridge.cc b/components/offline_items_collection/core/android/offline_item_bridge.cc
index 9cb70e5..8ce9c2b 100644
--- a/components/offline_items_collection/core/android/offline_item_bridge.cc
+++ b/components/offline_items_collection/core/android/offline_item_bridge.cc
@@ -31,9 +31,11 @@
       ConvertUTF8ToJavaString(env, item.id.id),
       ConvertUTF8ToJavaString(env, item.title),
       ConvertUTF8ToJavaString(env, item.description),
-      static_cast<jint>(item.filter), item.is_transient, item.total_size_bytes,
-      item.externally_removed, item.creation_time.ToJavaTime(),
-      item.last_accessed_time.ToJavaTime(), item.is_openable,
+      static_cast<jint>(item.filter), item.is_transient, item.is_suggested,
+      item.total_size_bytes, item.externally_removed,
+      item.creation_time.ToJavaTime(), item.last_accessed_time.ToJavaTime(),
+      item.is_openable, ConvertUTF8ToJavaString(env, item.file_path.value()),
+      ConvertUTF8ToJavaString(env, item.mime_type),
       ConvertUTF8ToJavaString(env, item.page_url.spec()),
       ConvertUTF8ToJavaString(env, item.original_url.spec()),
       item.is_off_the_record, static_cast<jint>(item.state), item.is_resumable,
diff --git a/components/offline_items_collection/core/offline_item.cc b/components/offline_items_collection/core/offline_item.cc
index 762a17f..8d2b37b 100644
--- a/components/offline_items_collection/core/offline_item.cc
+++ b/components/offline_items_collection/core/offline_item.cc
@@ -41,6 +41,7 @@
 OfflineItem::OfflineItem()
     : filter(OfflineItemFilter::FILTER_OTHER),
       is_transient(false),
+      is_suggested(false),
       total_size_bytes(0),
       externally_removed(false),
       is_openable(false),
@@ -64,11 +65,14 @@
          description == offline_item.description &&
          filter == offline_item.filter &&
          is_transient == offline_item.is_transient &&
+         is_suggested == offline_item.is_suggested &&
          total_size_bytes == offline_item.total_size_bytes &&
          externally_removed == offline_item.externally_removed &&
          creation_time == offline_item.creation_time &&
          last_accessed_time == offline_item.last_accessed_time &&
          is_openable == offline_item.is_openable &&
+         file_path == offline_item.file_path &&
+         mime_type == offline_item.mime_type &&
          page_url == offline_item.page_url &&
          original_url == offline_item.original_url &&
          is_off_the_record == offline_item.is_off_the_record &&
diff --git a/components/offline_items_collection/core/offline_item.h b/components/offline_items_collection/core/offline_item.h
index 12525688..7e876cf4 100644
--- a/components/offline_items_collection/core/offline_item.h
+++ b/components/offline_items_collection/core/offline_item.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/files/file_path.h"
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "components/offline_items_collection/core/offline_item_filter.h"
@@ -104,6 +105,9 @@
   // persistent UI spaces and will only show up as notifications.
   bool is_transient;
 
+  // Whether this item should show up as a suggested item for the user.
+  bool is_suggested;
+
   // TODO(dtrainor): Build out custom per-item icon support.
 
   // Content Metadata.
@@ -123,6 +127,12 @@
   // Whether or not this item can be opened after it is done being downloaded.
   bool is_openable;
 
+  // The target file path for this offline item.
+  base::FilePath file_path;
+
+  // The mime type for this offline item.
+  std::string mime_type;
+
   // Request Metadata.
   // ---------------------------------------------------------------------------
   // The URL of the top level frame at the time the content was offlined.
diff --git a/components/ui_devtools/views/ui_devtools_dom_agent.cc b/components/ui_devtools/views/ui_devtools_dom_agent.cc
index ec162cd..af3dad9 100644
--- a/components/ui_devtools/views/ui_devtools_dom_agent.cc
+++ b/components/ui_devtools/views/ui_devtools_dom_agent.cc
@@ -449,6 +449,14 @@
   }
 }
 
+int UIDevToolsDOMAgent::GetParentIdOfNodeId(int node_id) const {
+  DCHECK(node_id_to_ui_element_.count(node_id));
+  const UIElement* element = node_id_to_ui_element_.at(node_id);
+  if (element->parent() && element->parent() != window_element_root_.get())
+    return element->parent()->node_id();
+  return 0;
+}
+
 void UIDevToolsDOMAgent::OnPaintLayer(const ui::PaintContext& context) {
   const gfx::Rect& screen_bounds(layer_for_highlighting_->bounds());
   ui::PaintRecorder recorder(context, screen_bounds.size());
diff --git a/components/ui_devtools/views/ui_devtools_dom_agent.h b/components/ui_devtools/views/ui_devtools_dom_agent.h
index 67b9b44..8cf6042 100644
--- a/components/ui_devtools/views/ui_devtools_dom_agent.h
+++ b/components/ui_devtools/views/ui_devtools_dom_agent.h
@@ -92,6 +92,10 @@
   // |element_id| in the highlight overlay.
   void ShowDistancesInHighlightOverlay(int pinned_id, int element_id);
 
+  // Returns parent id of the element with id |node_id|. Returns 0 if parent
+  // does not exist.
+  int GetParentIdOfNodeId(int node_id) const;
+
  private:
   // ui::LayerDelegate:
   void OnPaintLayer(const ui::PaintContext& context) override;
diff --git a/components/ui_devtools/views/ui_devtools_overlay_agent.cc b/components/ui_devtools/views/ui_devtools_overlay_agent.cc
index 972a1bf..ab876ff 100644
--- a/components/ui_devtools/views/ui_devtools_overlay_agent.cc
+++ b/components/ui_devtools/views/ui_devtools_overlay_agent.cc
@@ -5,6 +5,7 @@
 #include "components/ui_devtools/views/ui_devtools_overlay_agent.h"
 
 #include "ui/aura/env.h"
+#include "ui/events/event.h"
 
 namespace ui_devtools {
 
@@ -15,6 +16,12 @@
 
 UIDevToolsOverlayAgent::~UIDevToolsOverlayAgent() {}
 
+void UIDevToolsOverlayAgent::SetPinnedNodeId(int node_id) {
+  pinned_id_ = node_id;
+  frontend()->nodeHighlightRequested(pinned_id_);
+  dom_agent_->HighlightNode(pinned_id_, true /* show_size */);
+}
+
 ui_devtools::protocol::Response UIDevToolsOverlayAgent::setInspectMode(
     const String& in_mode,
     protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
@@ -43,6 +50,22 @@
   if (!dom_agent_->window_element_root())
     return;
 
+  // Show parent of the pinned element with id |pinned_id_| when mouse scrolls
+  // up. If parent exists, hightlight and re-pin parent element.
+  if (event->type() == ui::ET_MOUSEWHEEL && pinned_id_) {
+    const ui::MouseWheelEvent* mouse_event =
+        static_cast<ui::MouseWheelEvent*>(event);
+    DCHECK(mouse_event);
+    if (mouse_event->y_offset() > 0) {
+      const int parent_node_id = dom_agent_->GetParentIdOfNodeId(pinned_id_);
+      if (parent_node_id)
+        SetPinnedNodeId(parent_node_id);
+    } else if (mouse_event->y_offset() < 0) {
+      // TODO(thanhph): discuss behaviours when mouse scrolls down.
+    }
+    return;
+  }
+
   // Find node id of element whose bounds contain the mouse pointer location.
   aura::Window* target = static_cast<aura::Window*>(event->target());
   int element_id = dom_agent_->FindElementIdTargetedByPoint(
@@ -53,14 +76,11 @@
     return;
   }
 
-  // Pin the  hover element on click.
+  // Pin the hover element on click.
   if (event->type() == ui::ET_MOUSE_PRESSED) {
     event->SetHandled();
-    if (element_id) {
-      pinned_id_ = element_id;
-      frontend()->nodeHighlightRequested(element_id);
-      dom_agent_->HighlightNode(element_id, true /* show_size */);
-    }
+    if (element_id)
+      SetPinnedNodeId(element_id);
   } else if (element_id && !pinned_id_) {
     // Display only guidelines if hovering without a pinned element.
     frontend()->nodeHighlightRequested(element_id);
diff --git a/components/ui_devtools/views/ui_devtools_overlay_agent.h b/components/ui_devtools/views/ui_devtools_overlay_agent.h
index 15eafbfc..37f8fba 100644
--- a/components/ui_devtools/views/ui_devtools_overlay_agent.h
+++ b/components/ui_devtools/views/ui_devtools_overlay_agent.h
@@ -17,6 +17,8 @@
  public:
   explicit UIDevToolsOverlayAgent(UIDevToolsDOMAgent* dom_agent);
   ~UIDevToolsOverlayAgent() override;
+  int pinned_id() const { return pinned_id_; };
+  void SetPinnedNodeId(int pinned_id);
 
   // Overlay::Backend:
   ui_devtools::protocol::Response setInspectMode(
diff --git a/components/ui_devtools/views/ui_devtools_unittest.cc b/components/ui_devtools/views/ui_devtools_unittest.cc
index a15c32b..1841d26 100644
--- a/components/ui_devtools/views/ui_devtools_unittest.cc
+++ b/components/ui_devtools/views/ui_devtools_unittest.cc
@@ -504,6 +504,15 @@
   // Clicking on the widget should pin that element.
   generator.PressLeftButton();
 
+  // Pin parent node after mouse wheel moves up.
+  int parent_id = dom_agent()->GetParentIdOfNodeId(node_id);
+  EXPECT_NE(parent_id, overlay_agent()->pinned_id());
+  generator.MoveMouseWheel(0, 1);
+  EXPECT_EQ(parent_id, overlay_agent()->pinned_id());
+
+  // Re-assign pin node.
+  node_id = parent_id;
+
   int inspect_node_notification_count =
       GetOverlayInspectNodeRequestedCount(node_id);
 
diff --git a/content/browser/android/content_view_core.cc b/content/browser/android/content_view_core.cc
index d855115e..8cc17ae 100644
--- a/content/browser/android/content_view_core.cc
+++ b/content/browser/android/content_view_core.cc
@@ -988,6 +988,12 @@
       web_contents_->GetRenderViewHost());
 }
 
+jboolean ContentViewCore::UsingSynchronousCompositing(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& obj) {
+  return content::GetContentClient()->UsingSynchronousCompositing();
+}
+
 void ContentViewCore::SetBackgroundOpaque(JNIEnv* env,
                                           const JavaParamRef<jobject>& jobj,
                                           jboolean opaque) {
diff --git a/content/browser/android/content_view_core.h b/content/browser/android/content_view_core.h
index e122b33..57fe21fe 100644
--- a/content/browser/android/content_view_core.h
+++ b/content/browser/android/content_view_core.h
@@ -214,6 +214,10 @@
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
 
+  jboolean UsingSynchronousCompositing(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj);
+
   // --------------------------------------------------------------------------
   // Public methods that call to Java via JNI
   // --------------------------------------------------------------------------
diff --git a/content/browser/android/synchronous_compositor_browser_filter.h b/content/browser/android/synchronous_compositor_browser_filter.h
index 15c606f..fd40185 100644
--- a/content/browser/android/synchronous_compositor_browser_filter.h
+++ b/content/browser/android/synchronous_compositor_browser_filter.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BROWSER_FILTER_H_
 #define CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BROWSER_FILTER_H_
 
-#include <deque>
 #include <map>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/synchronization/lock.h"
 #include "cc/output/compositor_frame_metadata.h"
@@ -70,7 +70,7 @@
   base::Lock future_map_lock_;  // Protects fields below.
   bool filter_ready_ = false;
   using FrameFutureQueue =
-      std::deque<scoped_refptr<SynchronousCompositor::FrameFuture>>;
+      base::circular_deque<scoped_refptr<SynchronousCompositor::FrameFuture>>;
   // This object is per renderer process, so routing_id is unique.
   using FrameFutureMap = std::map<int, FrameFutureQueue>;
   FrameFutureMap future_map_;
diff --git a/content/browser/appcache/appcache_quota_client.h b/content/browser/appcache/appcache_quota_client.h
index 6366204..acbaafba 100644
--- a/content/browser/appcache/appcache_quota_client.h
+++ b/content/browser/appcache/appcache_quota_client.h
@@ -5,11 +5,11 @@
 #ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_QUOTA_CLIENT_H_
 #define CONTENT_BROWSER_APPCACHE_APPCACHE_QUOTA_CLIENT_H_
 
-#include <deque>
 #include <map>
 #include <memory>
 #include <string>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/browser/appcache/appcache_storage.h"
@@ -31,7 +31,7 @@
 // been destroyed.
 class AppCacheQuotaClient : public storage::QuotaClient {
  public:
-  typedef std::deque<base::OnceClosure> RequestQueue;
+  using RequestQueue = base::circular_deque<base::OnceClosure>;
 
   ~AppCacheQuotaClient() override;
 
diff --git a/content/browser/appcache/appcache_storage_impl.h b/content/browser/appcache/appcache_storage_impl.h
index bc98e38..30cf261 100644
--- a/content/browser/appcache/appcache_storage_impl.h
+++ b/content/browser/appcache/appcache_storage_impl.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <set>
 #include <utility>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -96,11 +96,11 @@
   class CommitLastAccessTimesTask;
   class UpdateEvictionTimesTask;
 
-  typedef std::deque<DatabaseTask*> DatabaseTaskQueue;
-  typedef std::map<int64_t, CacheLoadTask*> PendingCacheLoads;
-  typedef std::map<GURL, GroupLoadTask*> PendingGroupLoads;
-  typedef std::deque<std::pair<GURL, int64_t>> PendingForeignMarkings;
-  typedef std::set<StoreGroupAndCacheTask*> PendingQuotaQueries;
+  using DatabaseTaskQueue = base::circular_deque<DatabaseTask*>;
+  using PendingCacheLoads = std::map<int64_t, CacheLoadTask*>;
+  using PendingGroupLoads = std::map<GURL, GroupLoadTask*>;
+  using PendingForeignMarkings = base::circular_deque<std::pair<GURL, int64_t>>;
+  using PendingQuotaQueries = std::set<StoreGroupAndCacheTask*>;
 
   bool IsInitTaskComplete() {
     return last_cache_id_ != AppCacheStorage::kUnitializedId;
@@ -165,7 +165,7 @@
   PendingQuotaQueries pending_quota_queries_;
 
   // Structures to keep track of lazy response deletion.
-  std::deque<int64_t> deletable_response_ids_;
+  base::circular_deque<int64_t> deletable_response_ids_;
   std::vector<int64_t> deleted_response_ids_;
   bool is_response_deletion_scheduled_;
   bool did_start_deleting_responses_;
@@ -191,7 +191,7 @@
 
   // Used to short-circuit certain operations without having to schedule
   // any tasks on the background database thread.
-  std::deque<base::OnceClosure> pending_simple_tasks_;
+  base::circular_deque<base::OnceClosure> pending_simple_tasks_;
   base::WeakPtrFactory<AppCacheStorageImpl> weak_factory_;
 
   friend class content::AppCacheStorageImplTest;
diff --git a/content/browser/appcache/appcache_update_job.h b/content/browser/appcache/appcache_update_job.h
index cce40a2..c3785e97 100644
--- a/content/browser/appcache/appcache_update_job.h
+++ b/content/browser/appcache/appcache_update_job.h
@@ -8,12 +8,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <set>
 #include <string>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -252,7 +252,7 @@
   // Helper container to track which urls have not been fetched yet. URLs are
   // removed when the fetch is initiated. Flag indicates whether an attempt
   // to load the URL from storage has already been tried and failed.
-  std::deque<UrlToFetch> urls_to_fetch_;
+  base::circular_deque<UrlToFetch> urls_to_fetch_;
 
   // Helper container to track which urls are being loaded from response
   // storage.
diff --git a/content/browser/appcache/mock_appcache_storage.h b/content/browser/appcache/mock_appcache_storage.h
index 717a7070..e144752 100644
--- a/content/browser/appcache/mock_appcache_storage.h
+++ b/content/browser/appcache/mock_appcache_storage.h
@@ -7,12 +7,12 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <memory>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/containers/hash_tables.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -201,7 +201,7 @@
   StoredEvictionTimesMap stored_eviction_times_;
   DoomedResponseIds doomed_response_ids_;
   std::unique_ptr<AppCacheDiskCache> disk_cache_;
-  std::deque<base::OnceClosure> pending_tasks_;
+  base::circular_deque<base::OnceClosure> pending_tasks_;
 
   bool simulate_make_group_obsolete_failure_;
   bool simulate_store_group_and_newest_cache_failure_;
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc
index ede6a3b..41fc47a 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -5,9 +5,9 @@
 #include "content/browser/background_fetch/background_fetch_data_manager.h"
 
 #include <algorithm>
-#include <queue>
 
 #include "base/command_line.h"
+#include "base/containers/queue.h"
 #include "base/memory/ptr_util.h"
 #include "base/numerics/checked_math.h"
 #include "base/strings/string_number_conversions.h"
@@ -473,7 +473,7 @@
  private:
   BackgroundFetchOptions options_;
 
-  std::queue<scoped_refptr<BackgroundFetchRequestInfo>> pending_requests_;
+  base::queue<scoped_refptr<BackgroundFetchRequestInfo>> pending_requests_;
   std::vector<scoped_refptr<BackgroundFetchRequestInfo>> active_requests_;
 
   // TODO(peter): Right now it's safe for this to be a vector because we only
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index 17540f9d..ba02415 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -22,9 +22,9 @@
 
 #include <map>
 #include <memory>
-#include <queue>
 
 #include "base/compiler_specific.h"
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
@@ -453,7 +453,7 @@
 
   // This is a queue of messages that are destined to be sent to the embedder
   // once the guest is attached to a particular embedder.
-  std::deque<std::unique_ptr<IPC::Message>> pending_messages_;
+  base::circular_deque<std::unique_ptr<IPC::Message>> pending_messages_;
 
   BrowserPluginGuestDelegate* const delegate_;
 
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc
index c3c257c..2e762da6 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -572,6 +572,9 @@
       filter_builder(std::move(filter_builder)),
       observer(observer) {}
 
+BrowsingDataRemoverImpl::RemovalTask::RemovalTask(
+    RemovalTask&& other) noexcept = default;
+
 BrowsingDataRemoverImpl::RemovalTask::~RemovalTask() {}
 
 bool BrowsingDataRemoverImpl::AllDone() {
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.h b/content/browser/browsing_data/browsing_data_remover_impl.h
index 2085951..81b62a77 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.h
+++ b/content/browser/browsing_data/browsing_data_remover_impl.h
@@ -7,9 +7,9 @@
 
 #include <stdint.h>
 
-#include <queue>
 #include <set>
 
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -134,6 +134,7 @@
                 int origin_type_mask,
                 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
                 Observer* observer);
+    RemovalTask(RemovalTask&& other) noexcept;
     ~RemovalTask();
 
     base::Time delete_begin;
@@ -201,7 +202,7 @@
   bool is_removing_;
 
   // Removal tasks to be processed.
-  std::queue<RemovalTask> task_queue_;
+  base::queue<RemovalTask> task_queue_;
 
   // If non-null, the |would_complete_callback_| is called each time an instance
   // is about to complete a browsing data removal process, and has the ability
diff --git a/content/browser/byte_stream.cc b/content/browser/byte_stream.cc
index eb07e14..0244811 100644
--- a/content/browser/byte_stream.cc
+++ b/content/browser/byte_stream.cc
@@ -4,11 +4,11 @@
 
 #include "content/browser/byte_stream.h"
 
-#include <deque>
 #include <set>
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -17,8 +17,8 @@
 namespace content {
 namespace {
 
-typedef std::deque<std::pair<scoped_refptr<net::IOBuffer>, size_t> >
-ContentVector;
+using ContentVector =
+    base::circular_deque<std::pair<scoped_refptr<net::IOBuffer>, size_t>>;
 
 class ByteStreamReaderImpl;
 
diff --git a/content/browser/byte_stream_unittest.cc b/content/browser/byte_stream_unittest.cc
index f233a41..e774da1 100644
--- a/content/browser/byte_stream_unittest.cc
+++ b/content/browser/byte_stream_unittest.cc
@@ -6,11 +6,11 @@
 
 #include <stddef.h>
 
-#include <deque>
 #include <limits>
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
@@ -94,8 +94,8 @@
  private:
   int producing_seed_key_;
   int consuming_seed_key_;
-  std::deque<char*> pointer_queue_;
-  std::deque<size_t> length_queue_;
+  base::circular_deque<char*> pointer_queue_;
+  base::circular_deque<size_t> length_queue_;
 };
 
 ByteStreamTest::ByteStreamTest()
diff --git a/content/browser/devtools/devtools_io_context.cc b/content/browser/devtools/devtools_io_context.cc
index 2e8bb87..4598f16 100644
--- a/content/browser/devtools/devtools_io_context.cc
+++ b/content/browser/devtools/devtools_io_context.cc
@@ -5,6 +5,7 @@
 #include "content/browser/devtools/devtools_io_context.h"
 
 #include "base/base64.h"
+#include "base/containers/queue.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
@@ -232,7 +233,7 @@
   OpenCallback open_callback_;
   scoped_refptr<storage::FileSystemContext> fs_context_;
   std::unique_ptr<BlobReader> blob_reader_;
-  std::queue<std::unique_ptr<ReadRequest>> pending_reads_;
+  base::queue<std::unique_ptr<ReadRequest>> pending_reads_;
   scoped_refptr<net::IOBufferWithSize> io_buf_;
   off_t last_read_pos_;
   bool failed_;
@@ -350,7 +351,7 @@
     return;
   }
   failed_ = true;
-  pending_reads_ = std::queue<std::unique_ptr<ReadRequest>>();
+  pending_reads_ = base::queue<std::unique_ptr<ReadRequest>>();
   open_callback_ = OpenCallback();
 }
 
diff --git a/content/browser/devtools/protocol/input_handler.h b/content/browser/devtools/protocol/input_handler.h
index e14d78f..5e7cd42 100644
--- a/content/browser/devtools/protocol/input_handler.h
+++ b/content/browser/devtools/protocol/input_handler.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
 
+#include "base/containers/circular_deque.h"
 #include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -148,8 +149,9 @@
   // Callbacks for calls to Input.dispatchKey/MouseEvent that have been sent to
   // the renderer, but that we haven't yet received an ack for.
   bool input_queued_;
-  std::deque<std::unique_ptr<DispatchKeyEventCallback>> pending_key_callbacks_;
-  std::deque<std::unique_ptr<DispatchMouseEventCallback>>
+  base::circular_deque<std::unique_ptr<DispatchKeyEventCallback>>
+      pending_key_callbacks_;
+  base::circular_deque<std::unique_ptr<DispatchMouseEventCallback>>
       pending_mouse_callbacks_;
   float page_scale_factor_;
   gfx::SizeF scrollable_viewport_size_;
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index a7970f9f..2e3951c 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -11,6 +11,7 @@
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/containers/hash_tables.h"
+#include "base/containers/queue.h"
 #include "base/process/process_handle.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -357,7 +358,7 @@
     for (size_t i = 0; i < actual_urls->length(); i++)
       urls.push_back(GURL(actual_urls->get(i)));
   } else {
-    std::queue<FrameTreeNode*> queue;
+    base::queue<FrameTreeNode*> queue;
     queue.push(frame_host->frame_tree_node());
     while (!queue.empty()) {
       FrameTreeNode* node = queue.front();
diff --git a/content/browser/devtools/protocol/target_auto_attacher.cc b/content/browser/devtools/protocol/target_auto_attacher.cc
index 90e566d..bbc9b99 100644
--- a/content/browser/devtools/protocol/target_auto_attacher.cc
+++ b/content/browser/devtools/protocol/target_auto_attacher.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/devtools/protocol/target_auto_attacher.h"
 
+#include "base/containers/queue.h"
 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
 #include "content/browser/devtools/service_worker_devtools_agent_host.h"
 #include "content/browser/frame_host/frame_tree.h"
@@ -112,7 +113,7 @@
   Hosts new_hosts;
   if (render_frame_host_) {
     FrameTreeNode* root = render_frame_host_->frame_tree_node();
-    std::queue<FrameTreeNode*> queue;
+    base::queue<FrameTreeNode*> queue;
     queue.push(root);
     while (!queue.empty()) {
       FrameTreeNode* node = queue.front();
diff --git a/content/browser/dom_storage/dom_storage_context_impl.h b/content/browser/dom_storage/dom_storage_context_impl.h
index acea443..4e25baa7 100644
--- a/content/browser/dom_storage/dom_storage_context_impl.h
+++ b/content/browser/dom_storage/dom_storage_context_impl.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "base/atomicops.h"
+#include "base/containers/circular_deque.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
@@ -249,7 +249,7 @@
   const int session_id_offset_;
   base::subtle::Atomic32 session_id_sequence_;
   // For diagnoostic purposes.
-  std::deque<int64_t> recently_deleted_session_ids_;
+  base::circular_deque<int64_t> recently_deleted_session_ids_;
 
   bool is_shutdown_;
   bool force_keep_session_state_;
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc
index f2395e39..9de3a75 100644
--- a/content/browser/download/download_browsertest.cc
+++ b/content/browser/download/download_browsertest.cc
@@ -2749,8 +2749,7 @@
 }
 
 // Verify parallel download resumption.
-IN_PROC_BROWSER_TEST_F(ParallelDownloadTest,
-                       DISABLED_ParallelDownloadResumption) {
+IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadResumption) {
   EXPECT_TRUE(base::FeatureList::IsEnabled(features::kParallelDownloading));
 
   TestDownloadRequestHandler request_handler;
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc
index 37d44531..04e24e9 100644
--- a/content/browser/download/download_item_impl_unittest.cc
+++ b/content/browser/download/download_item_impl_unittest.cc
@@ -6,16 +6,16 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <iterator>
 #include <map>
 #include <memory>
-#include <queue>
 #include <utility>
 #include <vector>
 
 #include "base/callback.h"
 #include "base/callback_helpers.h"
+#include "base/containers/circular_deque.h"
+#include "base/containers/queue.h"
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
@@ -1974,14 +1974,14 @@
 
 // A list of observations that are to be made during some event in the
 // DownloadItemImpl control flow. Ordering of the observations is significant.
-using ObservationList = std::deque<CurriedObservation>;
+using ObservationList = base::circular_deque<CurriedObservation>;
 
 // An ordered list of events.
 //
 // An "event" in this context refers to some stage in the DownloadItemImpl's
 // workflow described as "A", "B", "C", or "D" above. An EventList is expected
 // to always contains kEventCount events.
-using EventList = std::deque<ObservationList>;
+using EventList = base::circular_deque<ObservationList>;
 
 // Number of events in an EventList. This is always 4 for now as described
 // above.
@@ -2139,8 +2139,8 @@
   std::unique_ptr<MockDownloadFile> file_;
   std::unique_ptr<MockRequestHandle> request_handle_;
 
-  std::queue<base::Closure> successful_update_events_;
-  std::queue<base::Closure> failing_update_events_;
+  base::queue<base::Closure> successful_update_events_;
+  base::queue<base::Closure> failing_update_events_;
 };
 
 INSTANTIATE_TEST_CASE_P(Success,
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc
index 910a3de..2475cecd 100644
--- a/content/browser/download/mhtml_generation_manager.cc
+++ b/content/browser/download/mhtml_generation_manager.cc
@@ -5,10 +5,10 @@
 #include "content/browser/download/mhtml_generation_manager.h"
 
 #include <map>
-#include <queue>
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/queue.h"
 #include "base/files/file.h"
 #include "base/guid.h"
 #include "base/macros.h"
@@ -152,7 +152,7 @@
   MHTMLGenerationParams params_;
 
   // The IDs of frames that still need to be processed.
-  std::queue<int> pending_frame_tree_node_ids_;
+  base::queue<int> pending_frame_tree_node_ids_;
 
   // Identifies a frame to which we've sent FrameMsg_SerializeAsMHTML but for
   // which we didn't yet process FrameHostMsg_SerializeAsMHTMLResponse via
diff --git a/content/browser/download/mock_download_item_impl.cc b/content/browser/download/mock_download_item_impl.cc
index 1ad51e7c..37a92c9 100644
--- a/content/browser/download/mock_download_item_impl.cc
+++ b/content/browser/download/mock_download_item_impl.cc
@@ -6,9 +6,7 @@
 
 namespace content {
 
-MockDownloadItemImpl::MockDownloadItemImpl(
-    DownloadItemImplDelegate* delegate,
-    const DownloadItem::ReceivedSlices& received_slices)
+MockDownloadItemImpl::MockDownloadItemImpl(DownloadItemImplDelegate* delegate)
     : DownloadItemImpl(delegate,
                        std::string("7d122682-55b5-4a47-a253-36cadc3e5bee"),
                        content::DownloadItem::kInvalidId,
@@ -34,12 +32,9 @@
                        false,
                        base::Time(),
                        true,
-                       received_slices,
+                       DownloadItem::ReceivedSlices(),
                        net::NetLogWithSource()) {}
 
-MockDownloadItemImpl::MockDownloadItemImpl(DownloadItemImplDelegate* delegate)
-    : MockDownloadItemImpl(delegate, DownloadItem::ReceivedSlices()) {}
-
 MockDownloadItemImpl::~MockDownloadItemImpl() = default;
 
 }  // namespace content
diff --git a/content/browser/download/mock_download_item_impl.h b/content/browser/download/mock_download_item_impl.h
index 33e4b45..02fd1c8 100644
--- a/content/browser/download/mock_download_item_impl.h
+++ b/content/browser/download/mock_download_item_impl.h
@@ -26,8 +26,6 @@
  public:
   // Use history constructor for minimal base object.
   explicit MockDownloadItemImpl(DownloadItemImplDelegate* delegate);
-  MockDownloadItemImpl(DownloadItemImplDelegate* delegate,
-                       const DownloadItem::ReceivedSlices& received_slices);
   ~MockDownloadItemImpl() override;
 
   MOCK_METHOD5(OnDownloadTargetDetermined,
@@ -89,6 +87,7 @@
   MOCK_CONST_METHOD0(GetRemoteAddress, std::string());
   MOCK_CONST_METHOD0(GetTotalBytes, int64_t());
   MOCK_CONST_METHOD0(GetReceivedBytes, int64_t());
+  MOCK_CONST_METHOD0(GetReceivedSlices, const std::vector<ReceivedSlice>&());
   MOCK_CONST_METHOD0(GetHashState, const std::string&());
   MOCK_CONST_METHOD0(GetHash, const std::string&());
   MOCK_CONST_METHOD0(GetId, uint32_t());
diff --git a/content/browser/download/parallel_download_job.cc b/content/browser/download/parallel_download_job.cc
index 0ea7744..c67d5301 100644
--- a/content/browser/download/parallel_download_job.cc
+++ b/content/browser/download/parallel_download_job.cc
@@ -29,6 +29,7 @@
     const DownloadCreateInfo& create_info)
     : DownloadJobImpl(download_item, std::move(request_handle), true),
       initial_request_offset_(create_info.offset),
+      initial_received_slices_(download_item->GetReceivedSlices()),
       content_length_(create_info.total_bytes),
       requests_sent_(false),
       is_canceled_(false) {}
@@ -205,9 +206,25 @@
   if (slices_to_download.size() < 2)
     return;
 
-  // Assume the first slice to download will be handled by the initial request.
-  for (auto it = slices_to_download.begin() + 1; it != slices_to_download.end();
+  // If the initial request is working on the first hole, don't create parallel
+  // request for this hole.
+  bool skip_first_slice = true;
+  DownloadItem::ReceivedSlices initial_slices_to_download =
+      FindSlicesToDownload(initial_received_slices_);
+  if (initial_slices_to_download.size() > 1) {
+    DCHECK_EQ(initial_request_offset_, initial_slices_to_download[0].offset);
+    int64_t first_hole_max = initial_slices_to_download[0].offset +
+                             initial_slices_to_download[0].received_bytes;
+    skip_first_slice = slices_to_download[0].offset <= first_hole_max;
+  }
+
+  for (auto it = slices_to_download.begin(); it != slices_to_download.end();
        ++it) {
+    if (skip_first_slice) {
+      skip_first_slice = false;
+      continue;
+    }
+
     DCHECK_GE(it->offset, initial_request_offset_);
     CreateRequest(it->offset, it->received_bytes);
   }
diff --git a/content/browser/download/parallel_download_job.h b/content/browser/download/parallel_download_job.h
index 68c648f..513e4b5 100644
--- a/content/browser/download/parallel_download_job.h
+++ b/content/browser/download/parallel_download_job.h
@@ -79,6 +79,11 @@
   // Information about the initial request when download is started.
   int64_t initial_request_offset_;
 
+  // A snapshot of received slices when creating the parallel download job.
+  // Download item's received slices may be different from this snapshot when
+  // |BuildParallelRequests| is called.
+  DownloadItem::ReceivedSlices initial_received_slices_;
+
   // The length of the response body of the original request.
   // Used to estimate the remaining size of the content when the initial
   // request is half open, i.e, |initial_request_length_| is
diff --git a/content/browser/download/parallel_download_job_unittest.cc b/content/browser/download/parallel_download_job_unittest.cc
index 1206815..36fc086 100644
--- a/content/browser/download/parallel_download_job_unittest.cc
+++ b/content/browser/download/parallel_download_job_unittest.cc
@@ -24,6 +24,7 @@
 using ::testing::_;
 using ::testing::NiceMock;
 using ::testing::Return;
+using ::testing::ReturnRef;
 using ::testing::StrictMock;
 
 namespace content {
@@ -133,13 +134,15 @@
                          int64_t min_slice_size,
                          int min_remaining_time) {
     item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>();
-    download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>(
-        item_delegate_.get(), slices);
+    received_slices_ = slices;
+    download_item_ =
+        base::MakeUnique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get());
     EXPECT_CALL(*download_item_, GetTotalBytes())
-        .WillRepeatedly(
-            testing::Return(initial_request_offset + content_length));
+        .WillRepeatedly(Return(initial_request_offset + content_length));
     EXPECT_CALL(*download_item_, GetReceivedBytes())
-        .WillRepeatedly(testing::Return(initial_request_offset));
+        .WillRepeatedly(Return(initial_request_offset));
+    EXPECT_CALL(*download_item_, GetReceivedSlices())
+        .WillRepeatedly(ReturnRef(received_slices_));
 
     DownloadCreateInfo info;
     info.offset = initial_request_offset;
@@ -162,6 +165,10 @@
 
   void BuildParallelRequests() { job_->BuildParallelRequests(); }
 
+  void set_received_slices(const DownloadItem::ReceivedSlices& slices) {
+    received_slices_ = slices;
+  }
+
   bool IsJobCanceled() const { return job_->is_canceled_; };
 
   void MakeWorkerReady(
@@ -197,6 +204,10 @@
   bool file_initialized_;
   // Request handle for the original request.
   MockDownloadRequestHandle* mock_request_handle_;
+
+  // The received slices used to return in
+  // |MockDownloadItemImpl::GetReceivedSlices| mock function.
+  DownloadItem::ReceivedSlices received_slices_;
 };
 
 // Test if parallel requests can be built correctly for a new download without
@@ -293,6 +304,61 @@
   DestroyParallelJob();
 }
 
+// Ensure that in download resumption, if the first hole is filled before
+// sending multiple requests, the new requests can be correctly calculated.
+TEST_F(ParallelDownloadJobTest, CreateResumptionRequestsFirstSliceFilled) {
+  DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 10),
+                                         DownloadItem::ReceivedSlice(40, 10),
+                                         DownloadItem::ReceivedSlice(80, 10)};
+
+  // The updated slices that has filled the first hole.
+  DownloadItem::ReceivedSlices updated_slices = slices;
+  updated_slices[0].received_bytes = 40;
+
+  CreateParallelJob(10, 90, slices, 3, 1, 10);
+  // Now let download item to return an updated received slice, that the first
+  // hole in the file has been filled.
+  set_received_slices(updated_slices);
+  BuildParallelRequests();
+
+  // Since the first hole is filled, parallel requests are created to fill other
+  // two holes.
+  EXPECT_EQ(2u, job_->workers().size());
+  VerifyWorker(50, 30);
+  VerifyWorker(90, 0);
+  DestroyParallelJob();
+}
+
+// Simulate an edge case that we have one received slice in the middle. The
+// parallel request should be created correctly.
+// This may not happen under current implementation, but should be also handled
+// correctly.
+TEST_F(ParallelDownloadJobTest, CreateResumptionRequestsTwoSlicesToFill) {
+  DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(40, 10)};
+
+  CreateParallelJob(0, 100, slices, 3, 1, 10);
+  BuildParallelRequests();
+
+  EXPECT_EQ(1u, job_->workers().size());
+  VerifyWorker(50, 0);
+  DestroyParallelJob();
+
+  DownloadItem::ReceivedSlices updated_slices = {
+      DownloadItem::ReceivedSlice(0, 10), DownloadItem::ReceivedSlice(40, 10)};
+
+  CreateParallelJob(0, 100, slices, 3, 1, 10);
+  // Now let download item to return an updated received slice, that the first
+  // hole in the file is not fully filled.
+  set_received_slices(updated_slices);
+  BuildParallelRequests();
+
+  // Because the initial request is working on the first hole, there should be
+  // only one parallel request to fill the second hole.
+  EXPECT_EQ(1u, job_->workers().size());
+  VerifyWorker(50, 0);
+  DestroyParallelJob();
+}
+
 // Pause, cancel, resume can be called before or after the worker establish
 // the byte stream.
 // These tests ensure the states consistency between the job and workers.
diff --git a/content/browser/download/save_package.h b/content/browser/download/save_package.h
index b7a8ab9..1a5c6bd 100644
--- a/content/browser/download/save_package.h
+++ b/content/browser/download/save_package.h
@@ -8,7 +8,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <memory>
 #include <set>
@@ -16,6 +15,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -352,7 +352,7 @@
       const std::string& contents_mime_type);
 
   // A queue for items we are about to start saving.
-  std::deque<std::unique_ptr<SaveItem>> waiting_item_queue_;
+  base::circular_deque<std::unique_ptr<SaveItem>> waiting_item_queue_;
 
   // Map of all saving job in in-progress state.
   SaveItemIdMap in_progress_items_;
diff --git a/content/browser/find_request_manager.cc b/content/browser/find_request_manager.cc
index de2783c..f224f70 100644
--- a/content/browser/find_request_manager.cc
+++ b/content/browser/find_request_manager.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/containers/queue.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/frame_messages.h"
@@ -261,7 +262,7 @@
 
   // If this is a new find session, clear any queued requests from last session.
   if (!options.find_next)
-    find_request_queue_ = std::queue<FindRequest>();
+    find_request_queue_ = base::queue<FindRequest>();
 
   find_request_queue_.emplace(request_id, search_text, options);
   if (find_request_queue_.size() == 1)
diff --git a/content/browser/find_request_manager.h b/content/browser/find_request_manager.h
index 245ab69..5a3fbd3 100644
--- a/content/browser/find_request_manager.h
+++ b/content/browser/find_request_manager.h
@@ -5,12 +5,12 @@
 #ifndef CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_
 #define CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_
 
-#include <queue>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
 #include <vector>
 
+#include "base/containers/queue.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/stop_find_action.h"
@@ -299,7 +299,7 @@
 
   // Find requests are queued here when previous requests need to be handled
   // before these ones can be properly routed.
-  std::queue<FindRequest> find_request_queue_;
+  base::queue<FindRequest> find_request_queue_;
 
   // Keeps track of the find request ID of the last find reply reported via
   // NotifyFindReply().
diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h
index f9300509f..6fe990e 100644
--- a/content/browser/frame_host/frame_tree.h
+++ b/content/browser/frame_host/frame_tree.h
@@ -12,6 +12,7 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "content/browser/frame_host/frame_tree_node.h"
@@ -64,7 +65,7 @@
 
     FrameTreeNode* current_node_;
     FrameTreeNode* const root_of_subtree_to_skip_;
-    std::queue<FrameTreeNode*> queue_;
+    base::queue<FrameTreeNode*> queue_;
   };
 
   class CONTENT_EXPORT NodeRange {
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index 71e8e7f..ac6821c 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -6,9 +6,9 @@
 
 #include <stddef.h>
 
-#include <queue>
 #include <utility>
 
+#include "base/containers/queue.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
@@ -892,7 +892,7 @@
   DCHECK(!frame_tree_node->IsMainFrame());
 
   NavigationEntryImpl::TreeNode* node = nullptr;
-  std::queue<NavigationEntryImpl::TreeNode*> work_queue;
+  base::queue<NavigationEntryImpl::TreeNode*> work_queue;
   int count = 0;
 
   work_queue.push(root_node());
@@ -941,7 +941,7 @@
 NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry(
     FrameTreeNode* frame_tree_node) const {
   NavigationEntryImpl::TreeNode* node = nullptr;
-  std::queue<NavigationEntryImpl::TreeNode*> work_queue;
+  base::queue<NavigationEntryImpl::TreeNode*> work_queue;
   work_queue.push(root_node());
   while (!work_queue.empty()) {
     node = work_queue.front();
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c2dd3034..a516093 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -5,12 +5,12 @@
 #include "content/browser/frame_host/render_frame_host_impl.h"
 
 #include <algorithm>
-#include <queue>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/hash_tables.h"
+#include "base/containers/queue.h"
 #include "base/feature_list.h"
 #include "base/lazy_instance.h"
 #include "base/memory/ptr_util.h"
@@ -4291,7 +4291,7 @@
   if (!frame_tree_node_->child_count())
     return;
 
-  std::queue<FrameTreeNode*> queue;
+  base::queue<FrameTreeNode*> queue;
   for (size_t index = 0; index < frame_tree_node_->child_count(); ++index)
     queue.push(frame_tree_node_->child_at(index));
   while (queue.size()) {
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index 3f040d8..4ccec417 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -9,12 +9,12 @@
 
 #include <map>
 #include <memory>
-#include <queue>
 #include <set>
 #include <string>
 
 #include "base/callback.h"
 #include "base/containers/hash_tables.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
@@ -238,10 +238,10 @@
 
   // These are the channel requests that we have already sent to
   // the GPU process, but haven't heard back about yet.
-  std::queue<EstablishChannelCallback> channel_requests_;
+  base::queue<EstablishChannelCallback> channel_requests_;
 
   // The pending create gpu memory buffer requests we need to reply to.
-  std::queue<CreateGpuMemoryBufferCallback> create_gpu_memory_buffer_requests_;
+  base::queue<CreateGpuMemoryBufferCallback> create_gpu_memory_buffer_requests_;
 
   // A callback to signal the completion of a SendDestroyingVideoSurface call.
   base::Closure send_destroying_video_surface_done_cb_;
@@ -249,7 +249,7 @@
   std::vector<RequestGPUInfoCallback> request_gpu_info_callbacks_;
 
   // Qeueud messages to send when the process launches.
-  std::queue<IPC::Message*> queued_messages_;
+  base::queue<IPC::Message*> queued_messages_;
 
   // Whether the GPU process is valid, set to false after Send() failed.
   bool valid_;
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index 91791fb..30401ca 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -11,12 +11,12 @@
 #include <list>
 #include <map>
 #include <memory>
-#include <queue>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -346,7 +346,7 @@
   // This holds open or delete requests that are waiting for the active
   // request to be completed. The requests have not yet broadcast
   // OnVersionChange (if necessary).
-  std::queue<std::unique_ptr<ConnectionRequest>> pending_requests_;
+  base::queue<std::unique_ptr<ConnectionRequest>> pending_requests_;
 
   // The |processing_pending_requests_| flag is set while ProcessRequestQueue()
   // is executing. It prevents rentrant calls if the active request completes
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h
index 2fc65ca..7166d636 100644
--- a/content/browser/indexed_db/indexed_db_transaction.h
+++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -8,10 +8,10 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <set>
 #include <stack>
 
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -183,7 +183,7 @@
     void clear();
 
    private:
-    std::queue<Operation> queue_;
+    base::queue<Operation> queue_;
 
     DISALLOW_COPY_AND_ASSIGN(TaskQueue);
   };
diff --git a/content/browser/loader/resource_buffer.h b/content/browser/loader/resource_buffer.h
index e071d19..85354c4 100644
--- a/content/browser/loader/resource_buffer.h
+++ b/content/browser/loader/resource_buffer.h
@@ -5,8 +5,7 @@
 #ifndef CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
 #define CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
 
-#include <queue>
-
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/shared_memory.h"
@@ -113,7 +112,7 @@
   int alloc_start_;
   int alloc_end_;
 
-  std::queue<int> alloc_sizes_;
+  base::queue<int> alloc_sizes_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceBuffer);
 };
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc
index 1b8bc12..1a3f002c 100644
--- a/content/browser/loader/resource_loader_unittest.cc
+++ b/content/browser/loader/resource_loader_unittest.cc
@@ -7,11 +7,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 #include <utility>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -530,7 +530,7 @@
   // Allows controlling the return values of sequential calls to
   // HandleExternalProtocol. Values are removed by the measure they are used
   // but the last one which is used for all following calls.
-  std::deque<bool> handle_external_protocol_results_{false};
+  base::circular_deque<bool> handle_external_protocol_results_{false};
 
   net::URLRequestJobFactoryImpl job_factory_;
   net::TestNetworkQualityEstimator network_quality_estimator_;
diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h
index 56231141..e631d09d 100644
--- a/content/browser/ppapi_plugin_process_host.h
+++ b/content/browser/ppapi_plugin_process_host.h
@@ -8,10 +8,10 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
+#include "base/containers/queue.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -158,7 +158,7 @@
 
   // Channel requests that we have already sent to the plugin process, but
   // haven't heard back about yet.
-  std::queue<Client*> sent_requests_;
+  base::queue<Client*> sent_requests_;
 
   // Path to the plugin library.
   base::FilePath plugin_path_;
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
index 428bef1f..192a2716 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -8,6 +8,7 @@
 
 #include <utility>
 
+#include "base/containers/circular_deque.h"
 #include "base/lazy_instance.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/compositor/image_transport_factory.h"
@@ -34,8 +35,9 @@
 uint32_t g_browser_compositor_count = 0;
 
 // A spare RecyclableCompositorMac kept around for recycling.
-base::LazyInstance<std::deque<std::unique_ptr<RecyclableCompositorMac>>>::
-    DestructorAtExit g_spare_recyclable_compositors;
+base::LazyInstance<base::circular_deque<
+    std::unique_ptr<RecyclableCompositorMac>>>::DestructorAtExit
+    g_spare_recyclable_compositors;
 
 void ReleaseSpareCompositors() {
   // Allow at most one spare recyclable compositor.
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h
index de6f127..cdb8988 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -10,6 +10,7 @@
 #include <deque>
 #include <memory>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/timer/timer.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
@@ -183,9 +184,9 @@
 
   bool processing_acks_ = false;
 
-  typedef std::deque<GestureEventWithLatencyInfo> GestureQueue;
-  typedef std::deque<GestureEventWithLatencyInfoAndAckState>
-      GestureQueueWithAckState;
+  using GestureQueue = base::circular_deque<GestureEventWithLatencyInfo>;
+  using GestureQueueWithAckState =
+      base::circular_deque<GestureEventWithLatencyInfoAndAckState>;
 
   // If |allow_multiple_inflight_events_|, |coalesced_gesture_events_| stores
   // outstanding events that have been sent to the renderer but not yet been
diff --git a/content/browser/renderer_host/input/legacy_input_router_impl.h b/content/browser/renderer_host/input/legacy_input_router_impl.h
index 4152ec49..bfed77ad6 100644
--- a/content/browser/renderer_host/input/legacy_input_router_impl.h
+++ b/content/browser/renderer_host/input/legacy_input_router_impl.h
@@ -9,8 +9,8 @@
 
 #include <map>
 #include <memory>
-#include <queue>
 
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -214,7 +214,7 @@
 
   // Queue of pending select messages to send after receiving the next select
   // message ack.
-  std::deque<std::unique_ptr<IPC::Message>> pending_select_messages_;
+  base::circular_deque<std::unique_ptr<IPC::Message>> pending_select_messages_;
 
   // True while waiting for MoveCaret_ACK.
   bool move_caret_pending_;
@@ -224,13 +224,13 @@
 
   // A queue of the mouse move events sent to the renderer. Similar
   // to |key_queue_|.
-  typedef std::deque<MouseEventWithLatencyInfo> MouseEventQueue;
+  using MouseEventQueue = base::circular_deque<MouseEventWithLatencyInfo>;
   MouseEventQueue mouse_event_queue_;
 
   // A queue of keyboard events. We can't trust data from the renderer so we
   // stuff key events into a queue and pop them out on ACK, feeding our copy
   // back to whatever unhandled handler instead of the returned version.
-  typedef std::deque<NativeWebKeyboardEventWithLatencyInfo> KeyQueue;
+  using KeyQueue = base::circular_deque<NativeWebKeyboardEventWithLatencyInfo>;
   KeyQueue key_queue_;
 
   // The source of the ack within the scope of |ProcessInputEventAck()|.
diff --git a/content/browser/renderer_host/input/legacy_touch_event_queue.h b/content/browser/renderer_host/input/legacy_touch_event_queue.h
index 742301a..f18b8140 100644
--- a/content/browser/renderer_host/input/legacy_touch_event_queue.h
+++ b/content/browser/renderer_host/input/legacy_touch_event_queue.h
@@ -8,10 +8,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <list>
 #include <memory>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
@@ -195,7 +195,7 @@
   // uncancelable touchmoves which are still waiting for their acks back from
   // render. We do not put them back to the front the touch_event_queue any
   // more.
-  std::deque<uint32_t> ack_pending_async_touchmove_ids_;
+  base::circular_deque<uint32_t> ack_pending_async_touchmove_ids_;
 
   double last_sent_touch_timestamp_sec_;
 
diff --git a/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc
index c346dde..08bf421 100644
--- a/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
@@ -339,7 +340,7 @@
   std::unique_ptr<InputEventAckState> sync_ack_result_;
   double slop_length_dips_;
   gfx::PointF anchor_;
-  std::deque<int> sent_events_ids_;
+  base::circular_deque<int> sent_events_ids_;
 };
 
 // Tests that touch-events are queued properly.
diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.h b/content/browser/renderer_host/input/mouse_wheel_event_queue.h
index b0389f95..ba90b5e 100644
--- a/content/browser/renderer_host/input/mouse_wheel_event_queue.h
+++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOUSE_WHEEL_EVENT_QUEUE_H_
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOUSE_WHEEL_EVENT_QUEUE_H_
 
-#include <deque>
 #include <memory>
 
+#include "base/containers/circular_deque.h"
 #include "base/time/time.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
@@ -80,7 +80,7 @@
 
   MouseWheelEventQueueClient* client_;
 
-  std::deque<std::unique_ptr<QueuedWebMouseWheelEvent>> wheel_queue_;
+  base::circular_deque<std::unique_ptr<QueuedWebMouseWheelEvent>> wheel_queue_;
   std::unique_ptr<QueuedWebMouseWheelEvent> event_sent_for_gesture_ack_;
 
   // True if a non-synthetic GSB needs to be sent before a GSU is sent.
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
index 1b76ac6..dc29a53 100644
--- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
@@ -339,7 +340,7 @@
   std::unique_ptr<InputEventAckState> sync_ack_result_;
   double slop_length_dips_;
   gfx::PointF anchor_;
-  std::deque<int> sent_events_ids_;
+  base::circular_deque<int> sent_events_ids_;
 };
 
 // Tests that touch-events are queued properly.
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.h b/content/browser/renderer_host/input/synthetic_gesture_controller.h
index cbb4403..085fdc353f 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_controller.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -6,11 +6,11 @@
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_CONTROLLER_H_
 
 #include <memory>
-#include <queue>
 #include <utility>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
@@ -105,7 +105,7 @@
     SyntheticGesture::Result result_of_current_gesture_ =
         SyntheticGesture::GESTURE_RUNNING;
     std::vector<std::unique_ptr<SyntheticGesture>> gestures_;
-    std::queue<OnGestureCompleteCallback> callbacks_;
+    base::queue<OnGestureCompleteCallback> callbacks_;
 
     DISALLOW_COPY_AND_ASSIGN(GestureAndCallbackQueue);
   } pending_gesture_queue_;
diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc
index e564e4e..c8cd9a98 100644
--- a/content/browser/renderer_host/input/touch_emulator.cc
+++ b/content/browser/renderer_host/input/touch_emulator.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/renderer_host/input/touch_emulator.h"
 
+#include "base/containers/queue.h"
 #include "build/build_config.h"
 #include "content/browser/renderer_host/input/motion_event_web.h"
 #include "content/browser/renderer_host/ui_events_helper.h"
@@ -117,7 +118,7 @@
   mode_ = Mode::kEmulatingTouchFromMouse;
   CancelTouch();
   gesture_provider_.reset();
-  std::queue<base::OnceClosure> empty;
+  base::queue<base::OnceClosure> empty;
   injected_touch_completion_callbacks_.swap(empty);
   client_->SetCursor(pointer_cursor_);
   ResetState();
diff --git a/content/browser/renderer_host/input/touch_emulator.h b/content/browser/renderer_host/input/touch_emulator.h
index 3bed9e7..c501cef 100644
--- a/content/browser/renderer_host/input/touch_emulator.h
+++ b/content/browser/renderer_host/input/touch_emulator.h
@@ -6,9 +6,9 @@
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EMULATOR_H_
 
 #include <memory>
-#include <queue>
 
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "content/browser/renderer_host/input/touch_emulator_client.h"
 #include "content/common/cursors/webcursor.h"
@@ -149,7 +149,7 @@
   float pinch_scale_;
   bool pinch_gesture_active_;
 
-  std::queue<base::OnceClosure> injected_touch_completion_callbacks_;
+  base::queue<base::OnceClosure> injected_touch_completion_callbacks_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchEmulator);
 };
diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.h b/content/browser/renderer_host/media/audio_input_sync_writer.h
index 4777418..f41631d 100644
--- a/content/browser/renderer_host/media/audio_input_sync_writer.h
+++ b/content/browser/renderer_host/media/audio_input_sync_writer.h
@@ -8,11 +8,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/sync_socket.h"
@@ -170,7 +170,7 @@
     bool key_pressed;
     base::TimeTicks capture_time;
   };
-  std::deque<OverflowParams> overflow_params_;
+  base::circular_deque<OverflowParams> overflow_params_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputSyncWriter);
 };
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index f6eb0a08..99dbf601 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -6,13 +6,13 @@
 
 #include <stddef.h>
 #include <memory>
-#include <queue>
 #include <string>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
+#include "base/containers/queue.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/system_monitor/system_monitor.h"
@@ -218,7 +218,7 @@
 
   mojo::BindingSet<mojom::MediaStreamDispatcher> bindings_;
   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  std::queue<base::Closure> quit_closures_;
+  base::queue<base::Closure> quit_closures_;
 };
 
 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h
index 9e8fe2d..e1d673e 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -8,10 +8,10 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <vector>
 
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/browser/renderer_host/p2p/socket_host.h"
@@ -101,7 +101,7 @@
 
   std::unique_ptr<net::StreamSocket> socket_;
   scoped_refptr<net::GrowableIOBuffer> read_buffer_;
-  std::queue<SendBuffer> write_queue_;
+  base::queue<SendBuffer> write_queue_;
   SendBuffer write_buffer_;
 
   bool write_pending_;
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.h b/content/browser/renderer_host/p2p/socket_host_udp.h
index 7179369..a54f001 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.h
+++ b/content/browser/renderer_host/p2p/socket_host_udp.h
@@ -8,13 +8,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 #include <set>
 #include <vector>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
@@ -99,7 +99,7 @@
   scoped_refptr<net::IOBuffer> recv_buffer_;
   net::IPEndPoint recv_address_;
 
-  std::deque<PendingPacket> send_queue_;
+  base::circular_deque<PendingPacket> send_queue_;
   bool send_pending_;
   net::DiffServCodePoint last_dscp_;
 
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 4b68cd51..2e52da9 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -5,10 +5,10 @@
 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
 
 #include <stdint.h>
-#include <deque>
 #include <utility>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/sys_byteorder.h"
@@ -53,7 +53,7 @@
 
   // P2PSocketHostUdp destroys a socket on errors so sent packets
   // need to be stored outside of this object.
-  FakeDatagramServerSocket(std::deque<UDPPacket>* sent_packets,
+  FakeDatagramServerSocket(base::circular_deque<UDPPacket>* sent_packets,
                            std::vector<uint16_t>* used_ports)
       : sent_packets_(sent_packets),
         recv_address_(nullptr),
@@ -179,8 +179,8 @@
 
  private:
   net::IPEndPoint address_;
-  std::deque<UDPPacket>* sent_packets_;
-  std::deque<UDPPacket> incoming_packets_;
+  base::circular_deque<UDPPacket>* sent_packets_;
+  base::circular_deque<UDPPacket> incoming_packets_;
   net::NetLogWithSource net_log_;
 
   scoped_refptr<net::IOBuffer> recv_buffer_;
@@ -191,7 +191,7 @@
 };
 
 std::unique_ptr<net::DatagramServerSocket> CreateFakeDatagramServerSocket(
-    std::deque<FakeDatagramServerSocket::UDPPacket>* sent_packets,
+    base::circular_deque<FakeDatagramServerSocket::UDPPacket>* sent_packets,
     std::vector<uint16_t>* used_ports) {
   return base::MakeUnique<FakeDatagramServerSocket>(sent_packets, used_ports);
 }
@@ -227,7 +227,7 @@
 
   P2PMessageThrottler throttler_;
   ScopedFakeClock fake_clock_;
-  std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets_;
+  base::circular_deque<FakeDatagramServerSocket::UDPPacket> sent_packets_;
   FakeDatagramServerSocket* socket_;  // Owned by |socket_host_|.
   std::unique_ptr<P2PSocketHostUdp> socket_host_;
   MockIPCSender sender_;
@@ -494,7 +494,7 @@
 TEST_F(P2PSocketHostUdpTest, PortRangeImplicitPort) {
   const uint16_t min_port = 10000;
   const uint16_t max_port = 10001;
-  std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
+  base::circular_deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
   std::vector<uint16_t> used_ports;
   P2PSocketHostUdp::DatagramServerSocketFactory fake_socket_factory =
       base::Bind(&CreateFakeDatagramServerSocket, &sent_packets, &used_ports);
@@ -537,7 +537,7 @@
   const uint16_t min_port = 10000;
   const uint16_t max_port = 10001;
   const uint16_t valid_port = min_port;
-  std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
+  base::circular_deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
   std::vector<uint16_t> used_ports;
   P2PSocketHostUdp::DatagramServerSocketFactory fake_socket_factory =
       base::Bind(&CreateFakeDatagramServerSocket, &sent_packets, &used_ports);
@@ -567,7 +567,7 @@
   const uint16_t min_port = 10000;
   const uint16_t max_port = 10001;
   const uint16_t invalid_port = max_port + 1;
-  std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
+  base::circular_deque<FakeDatagramServerSocket::UDPPacket> sent_packets;
   std::vector<uint16_t> used_ports;
   P2PSocketHostUdp::DatagramServerSocketFactory fake_socket_factory =
       base::Bind(&CreateFakeDatagramServerSocket, &sent_packets, &used_ports);
diff --git a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
index 309e692d..83d15d9 100644
--- a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
+++ b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
@@ -11,6 +11,7 @@
 #include <string>
 
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
@@ -92,11 +93,11 @@
     GURL url;
     ppapi::host::ReplyMessageContext reply_context;
   };
-  std::queue<UnsentRequest> unsent_requests_;
+  base::queue<UnsentRequest> unsent_requests_;
 
   // Requests awaiting a response from ProxyService. We need to store these so
   // that we can cancel them if we get destroyed.
-  std::queue<net::ProxyService::PacRequest*> pending_requests_;
+  base::queue<net::ProxyService::PacRequest*> pending_requests_;
 
   base::WeakPtrFactory<PepperNetworkProxyHost> weak_factory_;
 
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
index 0c5bbca9..3712183 100644
--- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
@@ -8,11 +8,11 @@
 #include <stddef.h>
 
 #include <memory>
-#include <queue>
 #include <string>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
@@ -173,7 +173,7 @@
 
   scoped_refptr<net::IOBuffer> recvfrom_buffer_;
 
-  std::queue<PendingSend> pending_sends_;
+  base::queue<PendingSend> pending_sends_;
 
   net::IPEndPoint recvfrom_address_;
 
diff --git a/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h b/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h
index 2170b33..86c75ba9 100644
--- a/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h
+++ b/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h
@@ -8,11 +8,11 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -104,7 +104,7 @@
   std::unique_ptr<ppapi::VpnProviderSharedBuffer> send_packet_buffer_;
   std::unique_ptr<ppapi::VpnProviderSharedBuffer> recv_packet_buffer_;
 
-  std::queue<std::vector<char>> received_packets_;
+  base::queue<std::vector<char>> received_packets_;
 
   base::WeakPtrFactory<PepperVpnProviderMessageFilter> weak_factory_;
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 4391225652..7c5f7d8 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -1015,7 +1016,7 @@
 
   // List of all swap messages that their corresponding frames have not arrived.
   // Sorted by frame token.
-  std::queue<std::pair<uint32_t, std::vector<IPC::Message>>> queued_messages_;
+  base::queue<std::pair<uint32_t, std::vector<IPC::Message>>> queued_messages_;
 
   // If a CompositorFrame is submitted that references SharedBitmaps that don't
   // exist yet, we keep it here until they are available.
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index f7fb982..6a5d184 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -287,8 +287,11 @@
     if (!root_view->TransformPointToCoordSpaceForView(
             gfx::Point(event->PositionInWidget().x,
                        event->PositionInWidget().y),
-            target, &transformed_point))
+            target, &transformed_point)) {
+      root_view->WheelEventAck(*event,
+                               INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
       return;
+    }
   } else if (root_view->wheel_scroll_latching_enabled()) {
     if (event->phase == blink::WebMouseWheelEvent::kPhaseBegan) {
       wheel_target_.target = FindEventTarget(
@@ -316,8 +319,10 @@
         &transformed_point);
   }
 
-  if (!target)
+  if (!target) {
+    root_view->WheelEventAck(*event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
     return;
+  }
 
   event->SetPositionInWidget(transformed_point.x(), transformed_point.y());
   target->ProcessMouseWheelEvent(*event, latency);
@@ -430,8 +435,12 @@
         touchscreen_gesture_target_map_[event->unique_touch_event_id] =
             touch_target_;
 
-        if (!touch_target_.target)
+        if (!touch_target_.target) {
+          TouchEventWithLatencyInfo touch_with_latency(*event, latency);
+          root_view->ProcessAckedTouchEvent(
+              touch_with_latency, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
           return;
+        }
 
         if (touch_target_.target == bubbling_gesture_scroll_target_.target) {
           SendGestureScrollEnd(
@@ -448,10 +457,15 @@
       break;
     }
     case blink::WebInputEvent::kTouchMove:
-      if (touch_target_.target) {
-        TransformEventTouchPositions(event, touch_target_.delta);
-        touch_target_.target->ProcessTouchEvent(*event, latency);
+      if (!touch_target_.target) {
+        TouchEventWithLatencyInfo touch_with_latency(*event, latency);
+        root_view->ProcessAckedTouchEvent(
+            touch_with_latency, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+        return;
       }
+
+      TransformEventTouchPositions(event, touch_target_.delta);
+      touch_target_.target->ProcessTouchEvent(*event, latency);
       break;
     case blink::WebInputEvent::kTouchEnd:
     case blink::WebInputEvent::kTouchCancel:
@@ -461,8 +475,13 @@
       if (active_touches_)
         active_touches_ -= CountChangedTouchPoints(*event);
       DCHECK_GE(active_touches_, 0);
-      if (!touch_target_.target)
+
+      if (!touch_target_.target) {
+        TouchEventWithLatencyInfo touch_with_latency(*event, latency);
+        root_view->ProcessAckedTouchEvent(
+            touch_with_latency, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
         return;
+      }
 
       TransformEventTouchPositions(event, touch_target_.delta);
       touch_target_.target->ProcessTouchEvent(*event, latency);
@@ -900,8 +919,11 @@
     }
   }
 
-  if (!touchscreen_gesture_target_.target)
+  if (!touchscreen_gesture_target_.target) {
+    root_view->GestureEventAck(*event,
+                               INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
     return;
+  }
 
   // TODO(mohsen): Add tests to check event location.
   event->x += touchscreen_gesture_target_.delta.x();
@@ -938,8 +960,11 @@
     }
   }
 
-  if (!touchpad_gesture_target_.target)
+  if (!touchpad_gesture_target_.target) {
+    root_view->GestureEventAck(*event,
+                               INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
     return;
+  }
 
   // TODO(mohsen): Add tests to check event location.
   event->x += touchpad_gesture_target_.delta.x();
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
index 68306a45..03572845 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -33,12 +33,19 @@
     last_gesture_seen_ = event.GetType();
   }
 
+  void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
+                              InputEventAckState ack_result) override {
+    unique_id_for_last_touch_ack_ = touch.event.unique_touch_event_id;
+  }
+
   blink::WebInputEvent::Type last_gesture_seen() { return last_gesture_seen_; }
+  uint32_t last_id_for_touch_ack() { return unique_id_for_last_touch_ack_; }
 
   void Reset() { last_gesture_seen_ = blink::WebInputEvent::kUndefined; }
 
  private:
   blink::WebInputEvent::Type last_gesture_seen_;
+  uint32_t unique_id_for_last_touch_ack_ = 0;
 };
 
 // The RenderWidgetHostInputEventRouter uses the root RWHV for hittesting, so
@@ -243,4 +250,33 @@
             view_root_->last_gesture_seen());
 }
 
+// Ensure that when RenderWidgetHostInputEventRouter receives an unexpected
+// touch event, it calls the root view's method to Ack the event before
+// dropping it.
+TEST_F(RenderWidgetHostInputEventRouterTest, EnsureDroppedTouchEventsAreAcked) {
+  // Send a touch move without a touch start.
+  blink::WebTouchEvent touch_move_event(
+      blink::WebInputEvent::kTouchMove, blink::WebInputEvent::kNoModifiers,
+      blink::WebInputEvent::kTimeStampForTesting);
+  touch_move_event.touches_length = 1;
+  touch_move_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
+  touch_move_event.unique_touch_event_id = 1;
+
+  rwhier_.RouteTouchEvent(view_root_.get(), &touch_move_event,
+                          ui::LatencyInfo(ui::SourceEventType::TOUCH));
+  EXPECT_EQ(view_root_->last_id_for_touch_ack(), 1lu);
+
+  // Send a touch cancel without a touch start.
+  blink::WebTouchEvent touch_cancel_event(
+      blink::WebInputEvent::kTouchCancel, blink::WebInputEvent::kNoModifiers,
+      blink::WebInputEvent::kTimeStampForTesting);
+  touch_cancel_event.touches_length = 1;
+  touch_cancel_event.touches[0].state = blink::WebTouchPoint::kStateCancelled;
+  touch_cancel_event.unique_touch_event_id = 2;
+
+  rwhier_.RouteTouchEvent(view_root_.get(), &touch_cancel_event,
+                          ui::LatencyInfo(ui::SourceEventType::TOUCH));
+  EXPECT_EQ(view_root_->last_id_for_touch_ack(), 2lu);
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 5b99f6d..539f91e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -10,10 +10,10 @@
 
 #include <map>
 #include <memory>
-#include <queue>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/i18n/rtl.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -435,7 +435,7 @@
   // The most recent surface size that was pushed to the surface layer.
   gfx::Size current_surface_size_;
 
-  std::queue<base::Closure> ack_callbacks_;
+  base::queue<base::Closure> ack_callbacks_;
 
   // Used to control and render overscroll-related effects.
   std::unique_ptr<OverscrollControllerAndroid> overscroll_controller_;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
index 154d05b..c32a739 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -8,11 +8,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "build/build_config.h"
@@ -294,9 +294,10 @@
   // using CSS.
   bool CanBecomeVisible();
 
-  using FrameSwappedCallbackList = std::deque<std::unique_ptr<base::Closure>>;
-  // Since frame-drawn callbacks are "fire once", we use std::deque to make
-  // it convenient to swap() when processing the list.
+  using FrameSwappedCallbackList =
+      base::circular_deque<std::unique_ptr<base::Closure>>;
+  // Since frame-drawn callbacks are "fire once", we use base::circular_deque
+  // to make it convenient to swap() when processing the list.
   FrameSwappedCallbackList frame_swapped_callbacks_;
 
   // The surface client ID of the parent RenderWidgetHostView.  0 if none.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 640c1ba..0e47a4a 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -10,6 +10,7 @@
 #include <tuple>
 
 #include "base/command_line.h"
+#include "base/containers/queue.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_nsautorelease_pool.h"
 #include "base/mac/sdk_forward_declarations.h"
@@ -280,7 +281,7 @@
   DCHECK(output);
   output->clear();
 
-  std::queue<int> break_point_queue;
+  base::queue<int> break_point_queue;
   for (size_t i = 0; i < break_points.size(); ++i)
     break_point_queue.push(break_points[i]);
   break_point_queue.push(length);
diff --git a/content/browser/resolve_proxy_msg_helper.h b/content/browser/resolve_proxy_msg_helper.h
index f076d97d..f552fd2 100644
--- a/content/browser/resolve_proxy_msg_helper.h
+++ b/content/browser/resolve_proxy_msg_helper.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_BROWSER_RESOLVE_PROXY_MSG_HELPER_H_
 #define CONTENT_BROWSER_RESOLVE_PROXY_MSG_HELPER_H_
 
-#include <deque>
 #include <string>
 
+#include "base/containers/circular_deque.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_message_filter.h"
@@ -74,7 +74,7 @@
   net::ProxyInfo proxy_info_;
 
   // FIFO queue of pending requests. The first entry is always the current one.
-  typedef std::deque<PendingRequest> PendingRequestList;
+  using PendingRequestList = base::circular_deque<PendingRequest>;
   PendingRequestList pending_requests_;
 
   scoped_refptr<net::URLRequestContextGetter> context_getter_;
diff --git a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
index 5f6382b7..ef7f7bf 100644
--- a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
+++ b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/service_worker/foreign_fetch_request_handler.h"
 
+#include "base/bind_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/simple_test_clock.h"
@@ -55,8 +56,6 @@
 // tokens in this test, but before the expiry timestamp of the valid ones.
 double kNowTimestamp = 1500000000;
 
-void EmptyCallback() {}
-
 }  // namespace
 
 class ForeignFetchRequestHandlerTest : public testing::Test {
@@ -90,7 +89,8 @@
     clock->SetNow(base::Time::FromDoubleT(kNowTimestamp));
     version_->SetClockForTesting(std::move(clock));
 
-    context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
 
     // Persist the registration data.
diff --git a/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/content/browser/service_worker/service_worker_cache_writer_unittest.cc
index 00d03893..d7789ac8 100644
--- a/content/browser/service_worker/service_worker_cache_writer_unittest.cc
+++ b/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -7,9 +7,9 @@
 #include <stddef.h>
 
 #include <list>
-#include <queue>
 #include <string>
 
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "content/browser/service_worker/service_worker_disk_cache.h"
@@ -89,7 +89,7 @@
     int result;
   };
 
-  std::queue<ExpectedRead> expected_reads_;
+  base::queue<ExpectedRead> expected_reads_;
   scoped_refptr<net::IOBuffer> pending_buffer_;
   size_t pending_buffer_len_;
   scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
@@ -238,7 +238,7 @@
     int result;
   };
 
-  std::queue<ExpectedWrite> expected_writes_;
+  base::queue<ExpectedWrite> expected_writes_;
 
   size_t info_written_;
   size_t data_written_;
diff --git a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
index 87d418f..4377ab783 100644
--- a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
@@ -58,7 +58,8 @@
 
   void SetUp() override {
     helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
-    context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
 
     // A new unstored registration/version.
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 159cde508..3b3ed5c6 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -426,7 +426,7 @@
 
 void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHint(
     const GURL& document_url,
-    const StartServiceWorkerForNavigationHintCallback& callback) {
+    StartServiceWorkerForNavigationHintCallback callback) {
   TRACE_EVENT1("ServiceWorker", "StartServiceWorkerForNavigationHint",
                "document_url", document_url.spec());
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -436,9 +436,9 @@
       base::BindOnce(
           &ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHintOnIO,
           this, document_url,
-          base::Bind(&ServiceWorkerContextWrapper::
-                         RecordStartServiceWorkerForNavigationHintResult,
-                     this, callback)));
+          base::BindOnce(&ServiceWorkerContextWrapper::
+                             RecordStartServiceWorkerForNavigationHintResult,
+                         this, std::move(callback))));
 }
 
 void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
@@ -948,23 +948,23 @@
 
 void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHintOnIO(
     const GURL& document_url,
-    const StartServiceWorkerForNavigationHintCallback& callback) {
+    StartServiceWorkerForNavigationHintCallback callback) {
   TRACE_EVENT1("ServiceWorker", "StartServiceWorkerForNavigationHintOnIO",
                "document_url", document_url.spec());
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!context_core_) {
-    callback.Run(StartServiceWorkerForNavigationHintResult::FAILED);
+    std::move(callback).Run(StartServiceWorkerForNavigationHintResult::FAILED);
     return;
   }
   context_core_->storage()->FindRegistrationForDocument(
       net::SimplifyUrlForRequest(document_url),
       base::Bind(
           &ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint,
-          this, callback));
+          this, base::Passed(std::move(callback))));
 }
 
 void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint(
-    const StartServiceWorkerForNavigationHintCallback& callback,
+    StartServiceWorkerForNavigationHintCallback callback,
     ServiceWorkerStatusCode status,
     scoped_refptr<ServiceWorkerRegistration> registration) {
   TRACE_EVENT1("ServiceWorker", "DidFindRegistrationForNavigationHint",
@@ -972,23 +972,25 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!registration) {
     DCHECK_NE(status, SERVICE_WORKER_OK);
-    callback.Run(StartServiceWorkerForNavigationHintResult::
-                     NO_SERVICE_WORKER_REGISTRATION);
+    std::move(callback).Run(StartServiceWorkerForNavigationHintResult::
+                                NO_SERVICE_WORKER_REGISTRATION);
     return;
   }
   if (!registration->active_version()) {
-    callback.Run(StartServiceWorkerForNavigationHintResult::
-                     NO_ACTIVE_SERVICE_WORKER_VERSION);
+    std::move(callback).Run(StartServiceWorkerForNavigationHintResult::
+                                NO_ACTIVE_SERVICE_WORKER_VERSION);
     return;
   }
   if (registration->active_version()->fetch_handler_existence() ==
       ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST) {
-    callback.Run(StartServiceWorkerForNavigationHintResult::NO_FETCH_HANDLER);
+    std::move(callback).Run(
+        StartServiceWorkerForNavigationHintResult::NO_FETCH_HANDLER);
     return;
   }
   if (registration->active_version()->running_status() ==
       EmbeddedWorkerStatus::RUNNING) {
-    callback.Run(StartServiceWorkerForNavigationHintResult::ALREADY_RUNNING);
+    std::move(callback).Run(
+        StartServiceWorkerForNavigationHintResult::ALREADY_RUNNING);
     return;
   }
 
@@ -996,29 +998,30 @@
       ServiceWorkerMetrics::EventType::NAVIGATION_HINT,
       base::Bind(
           &ServiceWorkerContextWrapper::DidStartServiceWorkerForNavigationHint,
-          this, registration->pattern(), callback));
+          this, registration->pattern(), base::Passed(std::move(callback))));
 }
 
 void ServiceWorkerContextWrapper::DidStartServiceWorkerForNavigationHint(
     const GURL& pattern,
-    const StartServiceWorkerForNavigationHintCallback& callback,
+    StartServiceWorkerForNavigationHintCallback callback,
     ServiceWorkerStatusCode code) {
   TRACE_EVENT2("ServiceWorker", "DidStartServiceWorkerForNavigationHint", "url",
                pattern.spec(), "code", ServiceWorkerStatusToString(code));
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  callback.Run(code == SERVICE_WORKER_OK
-                   ? StartServiceWorkerForNavigationHintResult::STARTED
-                   : StartServiceWorkerForNavigationHintResult::FAILED);
+  std::move(callback).Run(
+      code == SERVICE_WORKER_OK
+          ? StartServiceWorkerForNavigationHintResult::STARTED
+          : StartServiceWorkerForNavigationHintResult::FAILED);
 }
 
 void ServiceWorkerContextWrapper::
     RecordStartServiceWorkerForNavigationHintResult(
-        const StartServiceWorkerForNavigationHintCallback& callback,
+        StartServiceWorkerForNavigationHintCallback callback,
         StartServiceWorkerForNavigationHintResult result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(result);
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::BindOnce(callback, result));
+                          base::BindOnce(std::move(callback), result));
 }
 
 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index c1f49ba..0b42917 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -125,7 +125,7 @@
                                    base::OnceClosure failure_callback) override;
   void StartServiceWorkerForNavigationHint(
       const GURL& document_url,
-      const StartServiceWorkerForNavigationHintCallback& callback) override;
+      StartServiceWorkerForNavigationHintCallback callback) override;
   void StopAllServiceWorkersForOrigin(const GURL& origin) override;
 
   // These methods must only be called from the IO thread.
@@ -256,6 +256,7 @@
   friend class base::RefCountedThreadSafe<ServiceWorkerContextWrapper>;
   friend class EmbeddedWorkerTestHelper;
   friend class EmbeddedWorkerBrowserTest;
+  friend class FakeServiceWorkerContextWrapper;
   friend class ForeignFetchRequestHandler;
   friend class ServiceWorkerDispatcherHost;
   friend class ServiceWorkerInternalsUI;
@@ -263,7 +264,6 @@
   friend class ServiceWorkerProcessManager;
   friend class ServiceWorkerRequestHandler;
   friend class ServiceWorkerVersionBrowserTest;
-  friend class MockServiceWorkerContextWrapper;
 
   ~ServiceWorkerContextWrapper() override;
 
@@ -303,20 +303,20 @@
 
   void StartServiceWorkerForNavigationHintOnIO(
       const GURL& document_url,
-      const StartServiceWorkerForNavigationHintCallback& callback);
+      StartServiceWorkerForNavigationHintCallback callback);
 
   void DidFindRegistrationForNavigationHint(
-      const StartServiceWorkerForNavigationHintCallback& callback,
+      StartServiceWorkerForNavigationHintCallback callback,
       ServiceWorkerStatusCode status,
       scoped_refptr<ServiceWorkerRegistration> registration);
 
   void DidStartServiceWorkerForNavigationHint(
       const GURL& pattern,
-      const StartServiceWorkerForNavigationHintCallback& callback,
+      StartServiceWorkerForNavigationHintCallback callback,
       ServiceWorkerStatusCode code);
 
   void RecordStartServiceWorkerForNavigationHintResult(
-      const StartServiceWorkerForNavigationHintCallback& callback,
+      StartServiceWorkerForNavigationHintCallback callback,
       StartServiceWorkerForNavigationHintResult result);
 
   // The core context is only for use on the IO thread.
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index e7fc0182..9bc3a28 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -125,7 +125,8 @@
     provider_host_ = host->AsWeakPtr();
     context()->AddProviderHost(std::move(host));
 
-    context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
   }
 
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index 7ae60f02..9c5bacf 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -176,11 +176,10 @@
   }
 
   void SetUpRegistration(const GURL& scope, const GURL& script_url) {
-    registration_ =
-        new ServiceWorkerRegistration(ServiceWorkerRegistrationOptions(scope),
-                                      1L, helper_->context()->AsWeakPtr());
+    registration_ = new ServiceWorkerRegistration(
+        ServiceWorkerRegistrationOptions(scope), 1L, context()->AsWeakPtr());
     version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L,
-                                        helper_->context()->AsWeakPtr());
+                                        context()->AsWeakPtr());
     std::vector<ServiceWorkerDatabase::ResourceRecord> records;
     records.push_back(
         ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
@@ -192,11 +191,12 @@
     version_->SetStatus(ServiceWorkerVersion::INSTALLING);
 
     // Make the registration findable via storage functions.
-    helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
     bool called = false;
     ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
-    helper_->context()->storage()->StoreRegistration(
+    context()->storage()->StoreRegistration(
         registration_.get(), version_.get(),
         base::Bind(&SaveStatusCallback, &called, &status));
     base::RunLoop().RunUntilIdle();
@@ -223,8 +223,8 @@
     std::unique_ptr<ServiceWorkerProviderHost> host =
         CreateProviderHostForServiceWorkerContext(
             helper_->mock_render_process_id(),
-            true /* is_parent_frame_secure */, version,
-            helper_->context()->AsWeakPtr(), &remote_endpoint_);
+            true /* is_parent_frame_secure */, version, context()->AsWeakPtr(),
+            &remote_endpoint_);
     provider_host_ = host.get();
     helper_->SimulateAddProcessToPattern(pattern,
                                          helper_->mock_render_process_id());
@@ -666,7 +666,7 @@
     // ProviderHost should be created before OnProviderCreated.
     navigation_handle_core->DidPreCreateProviderHost(
         ServiceWorkerProviderHost::PreCreateNavigationHost(
-            helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
+            context()->AsWeakPtr(), true /* are_ancestors_secure */,
             base::Callback<WebContents*(void)>()));
   }
 
@@ -691,7 +691,7 @@
     // ProviderHost should be created before OnProviderCreated.
     navigation_handle_core->DidPreCreateProviderHost(
         ServiceWorkerProviderHost::PreCreateNavigationHost(
-            helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
+            context()->AsWeakPtr(), true /* are_ancestors_secure */,
             base::Callback<WebContents*(void)>()));
   }
 
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index ab29a95d..b2d8103 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/queue.h"
 #include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/time/time.h"
@@ -232,7 +233,7 @@
 
   base::Optional<std::pair<int, int>> worker_id_;
   std::string devtools_request_id_;
-  std::queue<base::Callback<void(const WorkerId&, const std::string&)>>
+  base::queue<base::Callback<void(const WorkerId&, const std::string&)>>
       devtools_callbacks;
   DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoaderClient);
 };
diff --git a/content/browser/service_worker/service_worker_handle_unittest.cc b/content/browser/service_worker/service_worker_handle_unittest.cc
index ee4c206..1bb961f6 100644
--- a/content/browser/service_worker/service_worker_handle_unittest.cc
+++ b/content/browser/service_worker/service_worker_handle_unittest.cc
@@ -97,7 +97,8 @@
     version_->SetStatus(ServiceWorkerVersion::INSTALLING);
 
     // Make the registration findable via storage functions.
-    helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    helper_->context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
     ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
     helper_->context()->storage()->StoreRegistration(
diff --git a/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc b/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
index 9d0d18b..42d2189 100644
--- a/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
+++ b/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
@@ -231,7 +231,8 @@
   void SetUp() override {
     helper_ = base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath());
 
-    context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
 
     pattern_ = GURL("http://www.example.com/test/");
diff --git a/content/browser/service_worker/service_worker_job_coordinator.h b/content/browser/service_worker/service_worker_job_coordinator.h
index c86b800..94d133a 100644
--- a/content/browser/service_worker/service_worker_job_coordinator.h
+++ b/content/browser/service_worker/service_worker_job_coordinator.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_JOB_COORDINATOR_H_
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_JOB_COORDINATOR_H_
 
-#include <deque>
 #include <map>
 #include <memory>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "content/browser/service_worker/service_worker_register_job.h"
 #include "content/browser/service_worker/service_worker_unregister_job.h"
@@ -85,7 +85,7 @@
     void ClearForShutdown();
 
    private:
-    std::deque<std::unique_ptr<ServiceWorkerRegisterJobBase>> jobs_;
+    base::circular_deque<std::unique_ptr<ServiceWorkerRegisterJobBase>> jobs_;
 
     DISALLOW_COPY_AND_ASSIGN(JobQueue);
   };
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc b/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
index 71cc5fb..9253aa41 100644
--- a/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
@@ -86,7 +86,7 @@
 
   void InitializeStorage() {
     base::RunLoop run_loop;
-    context()->storage()->LazyInitialize(run_loop.QuitClosure());
+    context()->storage()->LazyInitializeForTest(run_loop.QuitClosure());
     run_loop.Run();
 
     // Populate a registration in the storage.
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index 44fdb9e..1d165fc 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -49,7 +49,8 @@
   void SetUp() override {
     helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
 
-    helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
   }
 
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index 4a909b2..b08b4b8 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -40,6 +40,11 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, closure);
 }
 
+void RunSoon(const tracked_objects::Location& from_here,
+             base::OnceClosure closure) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, std::move(closure));
+}
+
 void CompleteFindNow(
     scoped_refptr<ServiceWorkerRegistration> registration,
     ServiceWorkerStatusCode status,
@@ -942,6 +947,10 @@
   StartPurgingResources(resources);
 }
 
+bool ServiceWorkerStorage::LazyInitializeForTest(base::OnceClosure callback) {
+  return LazyInitialize(std::move(callback));
+}
+
 ServiceWorkerStorage::ServiceWorkerStorage(
     const base::FilePath& path,
     base::WeakPtr<ServiceWorkerContextCore> context,
@@ -979,17 +988,17 @@
       .Append(kDiskCacheName);
 }
 
-bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
+bool ServiceWorkerStorage::LazyInitialize(base::OnceClosure callback) {
   switch (state_) {
     case INITIALIZED:
       return true;
     case DISABLED:
       return false;
     case INITIALIZING:
-      pending_tasks_.push_back(callback);
+      pending_tasks_.push_back(std::move(callback));
       return false;
     case UNINITIALIZED:
-      pending_tasks_.push_back(callback);
+      pending_tasks_.push_back(std::move(callback));
       // Fall-through.
   }
 
@@ -1022,8 +1031,8 @@
     ScheduleDeleteAndStartOver();
   }
 
-  for (const auto& task : pending_tasks_)
-    RunSoon(FROM_HERE, task);
+  for (base::OnceClosure& task : pending_tasks_)
+    RunSoon(FROM_HERE, std::move(task));
   pending_tasks_.clear();
 }
 
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
index 70b2460..a681ed4d 100644
--- a/content/browser/service_worker/service_worker_storage.h
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <set>
 #include <string>
@@ -15,6 +14,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/containers/circular_deque.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -250,39 +250,15 @@
   // |resources| must already be on the purgeable list.
   void PurgeResources(const ResourceList& resources);
 
+  bool LazyInitializeForTest(base::OnceClosure callback);
+
  private:
-  friend class ForeignFetchRequestHandlerTest;
-  friend class ServiceWorkerDispatcherHostTest;
-  friend class ServiceWorkerHandleTest;
   friend class ServiceWorkerStorageTest;
-  friend class ServiceWorkerStorageOriginTrialsTest;
-  friend class ServiceWorkerRegistrationTest;
   friend class ServiceWorkerResourceStorageTest;
-  friend class ServiceWorkerControlleeRequestHandlerTest;
-  friend class ServiceWorkerContextRequestHandlerTest;
-  friend class ServiceWorkerReadFromCacheJobTest;
-  friend class ServiceWorkerRequestHandlerTest;
-  friend class ServiceWorkerInstalledScriptsSenderTest;
-  friend class ServiceWorkerURLLoaderJobTest;
-  friend class ServiceWorkerURLRequestJobTest;
-  friend class ServiceWorkerVersionBrowserTest;
-  friend class ServiceWorkerVersionTest;
   friend class ServiceWorkerWriteToCacheJobTest;
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest,
-                           CleanupOnRendererCrash);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
-                           DeleteRegistration_NoLiveVersion);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
-                           DeleteRegistration_WaitingVersion);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
-                           DeleteRegistration_ActiveVersion);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
-                           UpdateRegistration);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
                            CleanupOnRestart);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
-                           ClearOnExit);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
                            DeleteAndStartOver);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
                            DeleteAndStartOver_UnrelatedFileExists);
@@ -364,8 +340,7 @@
   base::FilePath GetDatabasePath();
   base::FilePath GetDiskCachePath();
 
-  bool LazyInitialize(
-      const base::Closure& callback);
+  bool LazyInitialize(base::OnceClosure callback);
   void DidReadInitialData(std::unique_ptr<InitialData> data,
                           ServiceWorkerDatabase::Status status);
   void DidFindRegistrationForDocument(
@@ -553,7 +528,7 @@
   std::set<GURL> foreign_fetch_origins_;
 
   // Pending database tasks waiting for initialization.
-  std::vector<base::Closure> pending_tasks_;
+  std::vector<base::OnceClosure> pending_tasks_;
 
   int64_t next_registration_id_;
   int64_t next_version_id_;
@@ -594,7 +569,7 @@
 
   std::unique_ptr<ServiceWorkerDiskCache> disk_cache_;
 
-  std::deque<int64_t> purgeable_resource_ids_;
+  base::circular_deque<int64_t> purgeable_resource_ids_;
   bool is_purge_pending_;
   bool has_checked_for_stale_resources_;
   std::set<int64_t> pending_deletions_;
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index 4dd89aa..dc9532c 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -330,7 +330,8 @@
   }
 
   ServiceWorkerContextCore* context() { return helper_->context(); }
-  ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
+  ServiceWorkerStorage* storage() { return context()->storage(); }
+  ServiceWorkerDatabase* database() { return storage()->database_.get(); }
 
   // A static class method for friendliness.
   static void VerifyPurgeableListStatusCallback(
@@ -347,7 +348,7 @@
 
  protected:
   void LazyInitialize() {
-    storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    storage()->LazyInitialize(base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
   }
 
@@ -564,10 +565,10 @@
     ServiceWorkerDatabase::RegistrationData deleted_version;
     std::vector<int64_t> newly_purgeable_resources;
 
-    ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
-              storage()->database_->WriteRegistration(
-                  registration, resources, &deleted_version,
-                  &newly_purgeable_resources));
+    ASSERT_EQ(
+        ServiceWorkerDatabase::STATUS_OK,
+        database()->WriteRegistration(registration, resources, &deleted_version,
+                                      &newly_purgeable_resources));
   }
 
   // user_data_directory_ must be declared first to preserve destructor order.
@@ -1238,7 +1239,7 @@
     base::RunLoop().RunUntilIdle();
     std::set<int64_t> verify_ids;
     EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-              storage()->database_->GetUncommittedResourceIds(&verify_ids));
+              database()->GetUncommittedResourceIds(&verify_ids));
     EXPECT_EQ(2u, verify_ids.size());
 
     // And dump something in the disk cache for them.
@@ -1254,7 +1255,7 @@
         StoreRegistration(registration_, registration_->waiting_version()));
     verify_ids.clear();
     EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-              storage()->database_->GetUncommittedResourceIds(&verify_ids));
+              database()->GetUncommittedResourceIds(&verify_ids));
     EXPECT_TRUE(verify_ids.empty());
   }
 
@@ -1352,21 +1353,17 @@
   // Deleting the registration should result in the resources being added to the
   // purgeable list and then doomed in the disk cache and removed from that
   // list.
-  storage()->DeleteRegistration(
-      registration_id_,
-      scope_.GetOrigin(),
-      base::Bind(&VerifyPurgeableListStatusCallback,
-                 base::Unretained(storage()->database_.get()),
-                 &verify_ids,
-                 &was_called,
-                 &result));
+  storage()->DeleteRegistration(registration_id_, scope_.GetOrigin(),
+                                base::Bind(&VerifyPurgeableListStatusCallback,
+                                           base::Unretained(database()),
+                                           &verify_ids, &was_called, &result));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_TRUE(verify_ids.empty());
 
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
@@ -1381,21 +1378,17 @@
   // Deleting the registration should result in the resources being added to the
   // purgeable list and then doomed in the disk cache and removed from that
   // list.
-  storage()->DeleteRegistration(
-      registration_->id(),
-      scope_.GetOrigin(),
-      base::Bind(&VerifyPurgeableListStatusCallback,
-                 base::Unretained(storage()->database_.get()),
-                 &verify_ids,
-                 &was_called,
-                 &result));
+  storage()->DeleteRegistration(registration_->id(), scope_.GetOrigin(),
+                                base::Bind(&VerifyPurgeableListStatusCallback,
+                                           base::Unretained(database()),
+                                           &verify_ids, &was_called, &result));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_EQ(2u, verify_ids.size());
 
   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, false));
@@ -1408,7 +1401,7 @@
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_TRUE(verify_ids.empty());
 
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
@@ -1433,21 +1426,17 @@
 
   // Deleting the registration should move the resources to the purgeable list
   // but keep them available.
-  storage()->DeleteRegistration(
-      registration_->id(),
-      scope_.GetOrigin(),
-      base::Bind(&VerifyPurgeableListStatusCallback,
-                 base::Unretained(storage()->database_.get()),
-                 &verify_ids,
-                 &was_called,
-                 &result));
+  storage()->DeleteRegistration(registration_->id(), scope_.GetOrigin(),
+                                base::Bind(&VerifyPurgeableListStatusCallback,
+                                           base::Unretained(database()),
+                                           &verify_ids, &was_called, &result));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_EQ(2u, verify_ids.size());
 
   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
@@ -1459,7 +1448,7 @@
   base::RunLoop().RunUntilIdle();
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_TRUE(verify_ids.empty());
 
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
@@ -1485,21 +1474,17 @@
 
   // Deleting the registration should move the resources to the purgeable list
   // but keep them available.
-  storage()->DeleteRegistration(
-      registration_->id(),
-      scope_.GetOrigin(),
-      base::Bind(&VerifyPurgeableListStatusCallback,
-                 base::Unretained(storage()->database_.get()),
-                 &verify_ids,
-                 &was_called,
-                 &result));
+  storage()->DeleteRegistration(registration_->id(), scope_.GetOrigin(),
+                                base::Bind(&VerifyPurgeableListStatusCallback,
+                                           base::Unretained(database()),
+                                           &verify_ids, &was_called, &result));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_EQ(2u, verify_ids.size());
 
   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
@@ -1511,7 +1496,7 @@
   base::RunLoop().RunUntilIdle();
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetUncommittedResourceIds(&verify_ids));
+            database()->GetUncommittedResourceIds(&verify_ids));
   EXPECT_EQ(1u, verify_ids.size());
   WriteBasicResponse(storage(), kStaleUncommittedResourceId);
   EXPECT_TRUE(
@@ -1531,7 +1516,7 @@
   // The stale resources should be purged, but the new resource should persist.
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetUncommittedResourceIds(&verify_ids));
+            database()->GetUncommittedResourceIds(&verify_ids));
   ASSERT_EQ(1u, verify_ids.size());
   EXPECT_EQ(kNewResourceId, *verify_ids.begin());
 
@@ -1542,7 +1527,7 @@
 
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_TRUE(verify_ids.empty());
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
@@ -1658,21 +1643,18 @@
 
   // Writing the registration should move the old version's resources to the
   // purgeable list but keep them available.
-  storage()->StoreRegistration(
-      registration_.get(),
-      registration_->waiting_version(),
-      base::Bind(&VerifyPurgeableListStatusCallback,
-                 base::Unretained(storage()->database_.get()),
-                 &verify_ids,
-                 &was_called,
-                 &result));
+  storage()->StoreRegistration(registration_.get(),
+                               registration_->waiting_version(),
+                               base::Bind(&VerifyPurgeableListStatusCallback,
+                                          base::Unretained(database()),
+                                          &verify_ids, &was_called, &result));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(2u, verify_ids.size());
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_EQ(2u, verify_ids.size());
 
   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, false));
@@ -1685,7 +1667,7 @@
   base::RunLoop().RunUntilIdle();
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
-            storage()->database_->GetPurgeableResourceIds(&verify_ids));
+            database()->GetPurgeableResourceIds(&verify_ids));
   EXPECT_TRUE(verify_ids.empty());
 
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
diff --git a/content/browser/service_worker/service_worker_url_loader_job.cc b/content/browser/service_worker/service_worker_url_loader_job.cc
index ceb5d857..f2e21dba 100644
--- a/content/browser/service_worker/service_worker_url_loader_job.cc
+++ b/content/browser/service_worker/service_worker_url_loader_job.cc
@@ -111,6 +111,7 @@
       fetch_dispatcher_->MaybeStartNavigationPreloadWithURLLoader(
           resource_request_, url_loader_factory_getter_.get(),
           base::BindOnce(&base::DoNothing /* TODO(crbug/762357): metrics? */));
+  response_head_.service_worker_start_time = base::TimeTicks::Now();
   fetch_dispatcher_->Run();
 }
 
@@ -143,7 +144,9 @@
 }
 
 void ServiceWorkerURLLoaderJob::DidPrepareFetchEvent(
-    scoped_refptr<ServiceWorkerVersion> version) {}
+    scoped_refptr<ServiceWorkerVersion> version) {
+  response_head_.service_worker_ready_time = base::TimeTicks::Now();
+}
 
 void ServiceWorkerURLLoaderJob::DidDispatchFetchEvent(
     ServiceWorkerStatusCode status,
diff --git a/content/browser/service_worker/service_worker_url_loader_job_unittest.cc b/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
index 6e1cc212..8c4ba55 100644
--- a/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
@@ -406,7 +406,7 @@
 
   void SetUp() override {
     // Create an active service worker.
-    storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    storage()->LazyInitializeForTest(base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
     registration_ = new ServiceWorkerRegistration(
         ServiceWorkerRegistrationOptions(GURL("https://example.com/")),
@@ -484,10 +484,9 @@
               info.url_list_via_service_worker);
     EXPECT_EQ(expected_info.response_type_via_service_worker,
               info.response_type_via_service_worker);
-    EXPECT_EQ(expected_info.service_worker_start_time,
-              info.service_worker_start_time);
-    EXPECT_EQ(expected_info.service_worker_ready_time,
-              info.service_worker_ready_time);
+    EXPECT_FALSE(info.service_worker_start_time.is_null());
+    EXPECT_FALSE(info.service_worker_ready_time.is_null());
+    EXPECT_LT(info.service_worker_start_time, info.service_worker_ready_time);
     EXPECT_EQ(expected_info.is_in_cache_storage, info.is_in_cache_storage);
     EXPECT_EQ(expected_info.cache_storage_cache_name,
               info.cache_storage_cache_name);
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index 65bba2b..11a2a32 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -220,7 +220,8 @@
         ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
 
     // Make the registration findable via storage functions.
-    helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    helper_->context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
     ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
     helper_->context()->storage()->StoreRegistration(
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index b375e2c..34281087 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -165,7 +165,8 @@
   void SetUp() override {
     helper_ = GetMessageReceiver();
 
-    helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+    helper_->context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
 
     pattern_ = GURL("http://www.example.com/test/");
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
index 86a14a0..55266f0d 100644
--- a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -7,6 +7,7 @@
 
 #include <utility>
 
+#include "base/bind_helpers.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -48,9 +49,6 @@
     "\n";
 const char kScriptCode[] = "// no script code\n";
 
-void EmptyCallback() {
-}
-
 // The blocksize that ServiceWorkerWriteToCacheJob reads/writes at a time.
 const int kBlockSize = 16 * 1024;
 const int kNumBlocks = 8;
@@ -341,7 +339,8 @@
     ASSERT_TRUE(host);
     SetUpScriptRequest(helper_->mock_render_process_id(), host->provider_id());
 
-    context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
+    context()->storage()->LazyInitializeForTest(
+        base::BindOnce(&base::DoNothing));
     base::RunLoop().RunUntilIdle();
   }
 
diff --git a/content/browser/speech/audio_buffer.h b/content/browser/speech/audio_buffer.h
index d941543..1231fa4 100644
--- a/content/browser/speech/audio_buffer.h
+++ b/content/browser/speech/audio_buffer.h
@@ -8,9 +8,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <string>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
@@ -72,7 +72,7 @@
   bool IsEmpty() const;
 
  private:
-  typedef std::deque<scoped_refptr<AudioChunk> > ChunksContainer;
+  using ChunksContainer = base::circular_deque<scoped_refptr<AudioChunk>>;
   ChunksContainer chunks_;
   const int bytes_per_sample_;
 
diff --git a/content/browser/speech/speech_recognition_engine_unittest.cc b/content/browser/speech/speech_recognition_engine_unittest.cc
index f90b7ed..4ea8fc4 100644
--- a/content/browser/speech/speech_recognition_engine_unittest.cc
+++ b/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -8,9 +8,9 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 
 #include "base/big_endian.h"
+#include "base/containers/queue.h"
 #include "base/message_loop/message_loop.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -103,7 +103,7 @@
   std::string response_buffer_;
   SpeechRecognitionErrorCode error_;
   int end_of_utterance_counter_;
-  std::queue<SpeechRecognitionResults> results_;
+  base::queue<SpeechRecognitionResults> results_;
 };
 
 TEST_F(SpeechRecognitionEngineTest, SingleDefinitiveResult) {
diff --git a/content/browser/webrtc/webrtc_internals.h b/content/browser/webrtc/webrtc_internals.h
index 45b0dbf..708d5da 100644
--- a/content/browser/webrtc/webrtc_internals.h
+++ b/content/browser/webrtc/webrtc_internals.h
@@ -6,10 +6,10 @@
 #define CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_
 
 #include <memory>
-#include <queue>
 #include <string>
 
 #include "base/containers/hash_tables.h"
+#include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/lazy_instance.h"
 #include "base/memory/weak_ptr.h"
@@ -251,7 +251,7 @@
     DISALLOW_COPY_AND_ASSIGN(PendingUpdate);
   };
 
-  std::queue<PendingUpdate> pending_updates_;
+  base::queue<PendingUpdate> pending_updates_;
   const int aggregate_updates_ms_;
 
   // Weak factory for this object that we use for bulking up updates.
diff --git a/content/child/indexed_db/webidbcursor_impl.h b/content/child/indexed_db/webidbcursor_impl.h
index c870bca7..61cccf2 100644
--- a/content/child/indexed_db/webidbcursor_impl.h
+++ b/content/child/indexed_db/webidbcursor_impl.h
@@ -7,10 +7,10 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <vector>
 
 #include "base/compiler_specific.h"
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
@@ -72,9 +72,9 @@
   scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
 
   // Prefetch cache.
-  std::deque<IndexedDBKey> prefetch_keys_;
-  std::deque<IndexedDBKey> prefetch_primary_keys_;
-  std::deque<blink::WebIDBValue> prefetch_values_;
+  base::circular_deque<IndexedDBKey> prefetch_keys_;
+  base::circular_deque<IndexedDBKey> prefetch_primary_keys_;
+  base::circular_deque<blink::WebIDBValue> prefetch_values_;
 
   // Number of continue calls that would qualify for a pre-fetch.
   int continue_count_;
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h
index 4bda53ec..aea67d9 100644
--- a/content/child/resource_dispatcher.h
+++ b/content/child/resource_dispatcher.h
@@ -9,11 +9,11 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <memory>
 #include <string>
 
+#include "base/containers/circular_deque.h"
 #include "base/containers/hash_tables.h"
 #include "base/macros.h"
 #include "base/memory/linked_ptr.h"
@@ -170,7 +170,7 @@
   friend class URLResponseBodyConsumer;
   friend class ResourceDispatcherTest;
 
-  typedef std::deque<IPC::Message*> MessageQueue;
+  using MessageQueue = base::circular_deque<IPC::Message*>;
   struct PendingRequestInfo {
     PendingRequestInfo(std::unique_ptr<RequestPeer> peer,
                        ResourceType resource_type,
diff --git a/content/child/shared_memory_data_consumer_handle.cc b/content/child/shared_memory_data_consumer_handle.cc
index c78ae8e..44c9384 100644
--- a/content/child/shared_memory_data_consumer_handle.cc
+++ b/content/child/shared_memory_data_consumer_handle.cc
@@ -5,10 +5,10 @@
 #include "content/child/shared_memory_data_consumer_handle.h"
 
 #include <algorithm>
-#include <deque>
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
@@ -244,7 +244,8 @@
   // |result_| stores the ultimate state of this handle if it has. Otherwise,
   // |Ok| is set.
   Result result_;
-  std::deque<std::unique_ptr<RequestPeer::ThreadSafeReceivedData>> queue_;
+  base::circular_deque<std::unique_ptr<RequestPeer::ThreadSafeReceivedData>>
+      queue_;
   size_t first_offset_;
   Client* client_;
   scoped_refptr<base::SingleThreadTaskRunner> notification_task_runner_;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 665a4788..2b85ee29 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -487,7 +487,8 @@
         mWebContentsObserver = new ContentViewWebContentsObserver(this);
 
         mShouldRequestUnbufferedDispatch = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
-                && ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_UNBUFFERED_DISPATCH);
+                && ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_UNBUFFERED_DISPATCH)
+                && !nativeUsingSynchronousCompositing(mNativeContentViewCore);
     }
 
     /**
@@ -2212,6 +2213,8 @@
 
     private native int nativeGetCurrentRenderProcessId(long nativeContentViewCore);
 
+    private native boolean nativeUsingSynchronousCompositing(long nativeContentViewCore);
+
     private native void nativeSetAllowJavascriptInterfacesInspection(
             long nativeContentViewCore, boolean allow);
 
diff --git a/content/public/browser/service_worker_context.h b/content/public/browser/service_worker_context.h
index f6208fb..4a2d93c4 100644
--- a/content/public/browser/service_worker_context.h
+++ b/content/public/browser/service_worker_context.h
@@ -59,8 +59,8 @@
   using CountExternalRequestsCallback =
       base::OnceCallback<void(size_t external_request_count)>;
 
-  using StartServiceWorkerForNavigationHintCallback =
-      base::Callback<void(StartServiceWorkerForNavigationHintResult result)>;
+  using StartServiceWorkerForNavigationHintCallback = base::OnceCallback<void(
+      StartServiceWorkerForNavigationHintResult result)>;
 
   using StartActiveWorkerCallback =
       base::OnceCallback<void(int process_id, int thread_id)>;
@@ -176,7 +176,7 @@
   // |callback| will always be called on the UI thread.
   virtual void StartServiceWorkerForNavigationHint(
       const GURL& document_url,
-      const StartServiceWorkerForNavigationHintCallback& callback) = 0;
+      StartServiceWorkerForNavigationHintCallback callback) = 0;
 
   // Stops all running workers on the given |origin|.
   //
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 55e6d48c0..dadd8fc9 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1643,7 +1643,7 @@
 }
 
 void DOMMessageQueue::ClearQueue() {
-  message_queue_ = std::queue<std::string>();
+  message_queue_ = base::queue<std::string>();
 }
 
 bool DOMMessageQueue::WaitForMessage(std::string* message) {
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 41e84d5..d523861 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -6,12 +6,12 @@
 #define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -593,7 +593,7 @@
 
  private:
   NotificationRegistrar registrar_;
-  std::queue<std::string> message_queue_;
+  base::queue<std::string> message_queue_;
   scoped_refptr<MessageLoopRunner> message_loop_runner_;
   bool renderer_crashed_ = false;
 
diff --git a/content/public/test/fake_service_worker_context.cc b/content/public/test/fake_service_worker_context.cc
new file mode 100644
index 0000000..1cc30ea
--- /dev/null
+++ b/content/public/test/fake_service_worker_context.cc
@@ -0,0 +1,84 @@
+// 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 "content/public/test/fake_service_worker_context.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+
+namespace content {
+
+FakeServiceWorkerContext::FakeServiceWorkerContext() {}
+FakeServiceWorkerContext::~FakeServiceWorkerContext() {}
+
+void FakeServiceWorkerContext::AddObserver(
+    ServiceWorkerContextObserver* observer) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::RemoveObserver(
+    ServiceWorkerContextObserver* observer) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::RegisterServiceWorker(const GURL& pattern,
+                                                     const GURL& script_url,
+                                                     ResultCallback callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::UnregisterServiceWorker(
+    const GURL& pattern,
+    ResultCallback callback) {
+  NOTREACHED();
+}
+bool FakeServiceWorkerContext::StartingExternalRequest(
+    int64_t service_worker_version_id,
+    const std::string& request_uuid) {
+  NOTREACHED();
+  return false;
+}
+bool FakeServiceWorkerContext::FinishedExternalRequest(
+    int64_t service_worker_version_id,
+    const std::string& request_uuid) {
+  NOTREACHED();
+  return false;
+}
+void FakeServiceWorkerContext::CountExternalRequestsForTest(
+    const GURL& url,
+    CountExternalRequestsCallback callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::GetAllOriginsInfo(
+    GetUsageInfoCallback callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::DeleteForOrigin(const GURL& origin,
+                                               ResultCallback callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::CheckHasServiceWorker(
+    const GURL& url,
+    const GURL& other_url,
+    CheckHasServiceWorkerCallback callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::ClearAllServiceWorkersForTest(
+    base::OnceClosure) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::StartActiveWorkerForPattern(
+    const GURL& pattern,
+    ServiceWorkerContext::StartActiveWorkerCallback info_callback,
+    base::OnceClosure failure_callback) {
+  NOTREACHED();
+}
+void FakeServiceWorkerContext::StartServiceWorkerForNavigationHint(
+    const GURL& document_url,
+    StartServiceWorkerForNavigationHintCallback callback) {
+  start_service_worker_for_navigation_hint_called_ = true;
+}
+void FakeServiceWorkerContext::StopAllServiceWorkersForOrigin(
+    const GURL& origin) {
+  NOTREACHED();
+}
+
+}  // namespace content
diff --git a/content/public/test/fake_service_worker_context.h b/content/public/test/fake_service_worker_context.h
new file mode 100644
index 0000000..59c9f08
--- /dev/null
+++ b/content/public/test/fake_service_worker_context.h
@@ -0,0 +1,69 @@
+// 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 CONTENT_PUBLIC_TEST_FAKE_SERVICE_WORKER_CONTEXT_H_
+#define CONTENT_PUBLIC_TEST_FAKE_SERVICE_WORKER_CONTEXT_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "content/public/browser/service_worker_context.h"
+
+class GURL;
+
+namespace content {
+
+class ServiceWorkerContextObserver;
+
+// Fake implementation of ServiceWorkerContext.
+//
+// Currently it only implements StartServiceWorkerForNavigationHint. Add
+// what you need.
+class FakeServiceWorkerContext : public ServiceWorkerContext {
+ public:
+  FakeServiceWorkerContext();
+  ~FakeServiceWorkerContext() override;
+
+  void AddObserver(ServiceWorkerContextObserver* observer) override;
+  void RemoveObserver(ServiceWorkerContextObserver* observer) override;
+  void RegisterServiceWorker(const GURL& pattern,
+                             const GURL& script_url,
+                             ResultCallback callback) override;
+  void UnregisterServiceWorker(const GURL& pattern,
+                               ResultCallback callback) override;
+  bool StartingExternalRequest(int64_t service_worker_version_id,
+                               const std::string& request_uuid) override;
+  bool FinishedExternalRequest(int64_t service_worker_version_id,
+                               const std::string& request_uuid) override;
+  void CountExternalRequestsForTest(
+      const GURL& url,
+      CountExternalRequestsCallback callback) override;
+  void GetAllOriginsInfo(GetUsageInfoCallback callback) override;
+  void DeleteForOrigin(const GURL& origin, ResultCallback callback) override;
+  void CheckHasServiceWorker(const GURL& url,
+                             const GURL& other_url,
+                             CheckHasServiceWorkerCallback callback) override;
+  void ClearAllServiceWorkersForTest(base::OnceClosure) override;
+  void StartActiveWorkerForPattern(
+      const GURL& pattern,
+      ServiceWorkerContext::StartActiveWorkerCallback info_callback,
+      base::OnceClosure failure_callback) override;
+  void StartServiceWorkerForNavigationHint(
+      const GURL& document_url,
+      StartServiceWorkerForNavigationHintCallback callback) override;
+  void StopAllServiceWorkersForOrigin(const GURL& origin) override;
+
+  bool start_service_worker_for_navigation_hint_called() {
+    return start_service_worker_for_navigation_hint_called_;
+  }
+
+ private:
+  bool start_service_worker_for_navigation_hint_called_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContext);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_TEST_FAKE_SERVICE_WORKER_CONTEXT_H_
diff --git a/content/public/test/mock_service_worker_context.cc b/content/public/test/mock_service_worker_context.cc
deleted file mode 100644
index dcabc277..0000000
--- a/content/public/test/mock_service_worker_context.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/test/mock_service_worker_context.h"
-
-#include "base/callback.h"
-#include "base/logging.h"
-
-namespace content {
-
-MockServiceWorkerContext::MockServiceWorkerContext() {}
-MockServiceWorkerContext::~MockServiceWorkerContext() {}
-
-void MockServiceWorkerContext::RegisterServiceWorker(const GURL& pattern,
-                                                     const GURL& script_url,
-                                                     ResultCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::UnregisterServiceWorker(
-    const GURL& pattern,
-    ResultCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::CountExternalRequestsForTest(
-    const GURL& url,
-    CountExternalRequestsCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::GetAllOriginsInfo(
-    GetUsageInfoCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::DeleteForOrigin(const GURL& origin,
-                                               ResultCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::CheckHasServiceWorker(
-    const GURL& url,
-    const GURL& other_url,
-    CheckHasServiceWorkerCallback callback) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::ClearAllServiceWorkersForTest(
-    base::OnceClosure) {
-  NOTREACHED();
-}
-void MockServiceWorkerContext::StartActiveWorkerForPattern(
-    const GURL& pattern,
-    ServiceWorkerContext::StartActiveWorkerCallback info_callback,
-    base::OnceClosure failure_callback) {
-  NOTREACHED();
-}
-
-}  // namespace content
diff --git a/content/public/test/mock_service_worker_context.h b/content/public/test/mock_service_worker_context.h
deleted file mode 100644
index 5220891..0000000
--- a/content/public/test/mock_service_worker_context.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_TEST_MOCK_SERVICE_WORKER_CONTEXT_H_
-#define CONTENT_PUBLIC_TEST_MOCK_SERVICE_WORKER_CONTEXT_H_
-
-#include <string>
-
-#include "base/callback_forward.h"
-#include "content/public/browser/service_worker_context.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-class GURL;
-
-namespace content {
-
-class ServiceWorkerContextObserver;
-
-// Mock implementation of ServiceWorkerContext.
-class MockServiceWorkerContext : public ServiceWorkerContext {
- public:
-  MockServiceWorkerContext();
-  virtual ~MockServiceWorkerContext();
-
-  // Some functions cannot be mocked because they use OnceCallback which is not
-  // copyable.
-  MOCK_METHOD1(AddObserver, void(ServiceWorkerContextObserver*));
-  MOCK_METHOD1(RemoveObserver, void(ServiceWorkerContextObserver*));
-  void RegisterServiceWorker(const GURL& pattern,
-                             const GURL& script_url,
-                             ResultCallback callback) override;
-  void UnregisterServiceWorker(const GURL& pattern,
-                               ResultCallback callback) override;
-  MOCK_METHOD2(StartingExternalRequest, bool(int64_t, const std::string&));
-  MOCK_METHOD2(FinishedExternalRequest, bool(int64_t, const std::string&));
-  void CountExternalRequestsForTest(
-      const GURL& url,
-      CountExternalRequestsCallback callback) override;
-  void GetAllOriginsInfo(GetUsageInfoCallback callback) override;
-  void DeleteForOrigin(const GURL& origin, ResultCallback callback) override;
-  void CheckHasServiceWorker(const GURL& url,
-                             const GURL& other_url,
-                             CheckHasServiceWorkerCallback callback) override;
-  void ClearAllServiceWorkersForTest(base::OnceClosure) override;
-  void StartActiveWorkerForPattern(
-      const GURL& pattern,
-      ServiceWorkerContext::StartActiveWorkerCallback info_callback,
-      base::OnceClosure failure_callback) override;
-  MOCK_METHOD2(StartServiceWorkerForNavigationHint,
-               void(const GURL&,
-                    const StartServiceWorkerForNavigationHintCallback&));
-  MOCK_METHOD1(StopAllServiceWorkersForOrigin, void(const GURL&));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerContext);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_TEST_MOCK_SERVICE_WORKER_CONTEXT_H_
diff --git a/content/public/test/test_download_request_handler.cc b/content/public/test/test_download_request_handler.cc
index 2ee6df20..e02033cfa 100644
--- a/content/public/test/test_download_request_handler.cc
+++ b/content/public/test/test_download_request_handler.cc
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/containers/queue.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
@@ -616,7 +617,7 @@
 TestDownloadRequestHandler::Parameters::~Parameters() {}
 
 void TestDownloadRequestHandler::Parameters::ClearInjectedErrors() {
-  std::queue<InjectedError> empty_error_list;
+  base::queue<InjectedError> empty_error_list;
   injected_errors.swap(empty_error_list);
 }
 
diff --git a/content/public/test/test_download_request_handler.h b/content/public/test/test_download_request_handler.h
index 440f876..43e2c5b5 100644
--- a/content/public/test/test_download_request_handler.h
+++ b/content/public/test/test_download_request_handler.h
@@ -8,9 +8,9 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 
 #include "base/callback_forward.h"
+#include "base/containers/queue.h"
 #include "base/files/file.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -197,7 +197,7 @@
     // * Distinctions about which read requests signal the error is often only
     //   important at the //net layer. From //content, it would appear that 100
     //   bytes were read and then request failed with ERR_CONNECTION_RESET.
-    std::queue<InjectedError> injected_errors;
+    base::queue<InjectedError> injected_errors;
   };
 
   // Details about completed requests returned by GetCompletedRequestInfo().
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 4b7f52a..94c7227 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -7,9 +7,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <queue>
-
 #include "base/bind.h"
+#include "base/containers/queue.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
@@ -334,7 +333,7 @@
   if (!root.UpdateLayoutAndCheckValidity())
     return;
 
-  std::queue<WebAXObject> objs_to_explore;
+  base::queue<WebAXObject> objs_to_explore;
   objs_to_explore.push(root);
   while (objs_to_explore.size()) {
     WebAXObject obj = objs_to_explore.front();
@@ -464,7 +463,7 @@
 
   // Do a breadth-first explore of the whole blink AX tree.
   base::hash_map<int, ui::AXRelativeBounds> new_locations;
-  std::queue<WebAXObject> objs_to_explore;
+  base::queue<WebAXObject> objs_to_explore;
   objs_to_explore.push(root);
   while (objs_to_explore.size()) {
     WebAXObject obj = objs_to_explore.front();
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc
index ff164ef2..417021db 100644
--- a/content/renderer/input/main_thread_event_queue.cc
+++ b/content/renderer/input/main_thread_event_queue.cc
@@ -4,6 +4,7 @@
 
 #include "content/renderer/input/main_thread_event_queue.h"
 
+#include "base/containers/circular_deque.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
@@ -199,7 +200,7 @@
   }
 
   // Contains the pending callbacks to be called.
-  std::deque<HandledEventCallback> blocking_coalesced_callbacks_;
+  base::circular_deque<HandledEventCallback> blocking_coalesced_callbacks_;
   // Contains the number of non-blocking events coalesced.
   size_t non_blocking_coalesced_count_;
   base::TimeTicks creation_timestamp_;
diff --git a/content/renderer/input/main_thread_event_queue_task_list.h b/content/renderer/input/main_thread_event_queue_task_list.h
index b9a81d2..d058087 100644
--- a/content/renderer/input/main_thread_event_queue_task_list.h
+++ b/content/renderer/input/main_thread_event_queue_task_list.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_RENDERER_INPUT_MAIN_THREAD_EVENT_QUEUE_TASK_LIST_H_
 #define CONTENT_RENDERER_INPUT_MAIN_THREAD_EVENT_QUEUE_TASK_LIST_H_
 
-#include <deque>
 #include <memory>
 
+#include "base/containers/circular_deque.h"
 #include "content/renderer/input/main_thread_event_queue_task.h"
 
 namespace content {
@@ -36,7 +36,8 @@
   size_t size() const { return queue_.size(); }
 
  private:
-  typedef std::deque<std::unique_ptr<MainThreadEventQueueTask>> EventQueue;
+  using EventQueue =
+      base::circular_deque<std::unique_ptr<MainThreadEventQueueTask>>;
   EventQueue queue_;
 
   DISALLOW_COPY_AND_ASSIGN(MainThreadEventQueueTaskList);
diff --git a/content/renderer/media/gpu/rtc_video_decoder.h b/content/renderer/media/gpu/rtc_video_decoder.h
index cddee8b..b9db17f 100644
--- a/content/renderer/media/gpu/rtc_video_decoder.h
+++ b/content/renderer/media/gpu/rtc_video_decoder.h
@@ -8,13 +8,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <list>
 #include <map>
 #include <memory>
 #include <set>
 #include <utility>
 
+#include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -274,11 +274,13 @@
 
   // A queue storing WebRTC encoding images (and their metadata) that are
   // waiting for the shared memory. Guarded by |lock_|.
-  std::deque<std::pair<webrtc::EncodedImage, BufferData>> pending_buffers_;
+  base::circular_deque<std::pair<webrtc::EncodedImage, BufferData>>
+      pending_buffers_;
 
   // A queue storing buffers (and their metadata) that will be sent to VDA for
   // decode. Guarded by |lock_|.
-  std::deque<std::pair<std::unique_ptr<base::SharedMemory>, BufferData>>
+  base::circular_deque<
+      std::pair<std::unique_ptr<base::SharedMemory>, BufferData>>
       decode_buffers_;
 
   // The id that will be given to the next bitstream buffer. Guarded by |lock_|.
diff --git a/content/renderer/media/gpu/rtc_video_encoder.cc b/content/renderer/media/gpu/rtc_video_encoder.cc
index 9d6b12d1..84da91b 100644
--- a/content/renderer/media/gpu/rtc_video_encoder.cc
+++ b/content/renderer/media/gpu/rtc_video_encoder.cc
@@ -6,11 +6,11 @@
 
 #include <string.h>
 
-#include <deque>
 #include <memory>
 #include <vector>
 
 #include "base/bind.h"
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
@@ -46,9 +46,6 @@
       : media_timestamp_(media_timestamp), rtp_timestamp(rtp_timestamp) {}
   const base::TimeDelta media_timestamp_;
   const int32_t rtp_timestamp;
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(RTCTimestamps);
 };
 
 webrtc::VideoCodecType ProfileToWebRtcVideoCodecType(
@@ -235,7 +232,7 @@
 
   // Used to match the encoded frame timestamp with WebRTC's given RTP
   // timestamp.
-  std::deque<RTCTimestamps> pending_timestamps_;
+  base::circular_deque<RTCTimestamps> pending_timestamps_;
 
   // Indicates that timestamp match failed and we should no longer attempt
   // matching.
diff --git a/content/renderer/media/webmediaplayer_ms_unittest.cc b/content/renderer/media/webmediaplayer_ms_unittest.cc
index f81bd23..480d7827 100644
--- a/content/renderer/media/webmediaplayer_ms_unittest.cc
+++ b/content/renderer/media/webmediaplayer_ms_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <stddef.h>
 
+#include "base/containers/circular_deque.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
@@ -198,7 +199,7 @@
   const base::Closure error_cb_;
   const MediaStreamVideoRenderer::RepaintCB repaint_cb_;
 
-  std::deque<TestFrame> frames_;
+  base::circular_deque<TestFrame> frames_;
   base::TimeDelta delay_till_next_generated_frame_;
 };
 
diff --git a/content/renderer/media_recorder/audio_track_recorder.cc b/content/renderer/media_recorder/audio_track_recorder.cc
index 9f968018..397a1114 100644
--- a/content/renderer/media_recorder/audio_track_recorder.cc
+++ b/content/renderer/media_recorder/audio_track_recorder.cc
@@ -237,10 +237,10 @@
 
   if (!is_initialized() || paused_)
     return;
-  // TODO(mcasas): Consider using a std::deque<std::unique_ptr<AudioBus>>
-  // instead of
-  // an AudioFifo, to avoid copying data needlessly since we know the sizes of
-  // both input and output and they are multiples.
+  // TODO(mcasas): Consider using a
+  // base::circular_deque<std::unique_ptr<AudioBus>> instead of an AudioFifo,
+  // to avoid copying data needlessly since we know the sizes of both input and
+  // output and they are multiples.
   fifo_->Push(input_bus.get());
 
   // Wait to have enough |input_bus|s to guarantee a satisfactory conversion.
diff --git a/content/renderer/media_recorder/vea_encoder.cc b/content/renderer/media_recorder/vea_encoder.cc
index 77ccb9e7..f88489c 100644
--- a/content/renderer/media_recorder/vea_encoder.cc
+++ b/content/renderer/media_recorder/vea_encoder.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/containers/queue.h"
 #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "media/base/bind_to_current_loop.h"
@@ -78,7 +79,7 @@
 
   vea_requested_input_coded_size_ = input_coded_size;
   output_buffers_.clear();
-  std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_);
+  base::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_);
 
   for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) {
     std::unique_ptr<base::SharedMemory> shm =
diff --git a/content/renderer/media_recorder/vea_encoder.h b/content/renderer/media_recorder/vea_encoder.h
index 3f27f56..57e5c91 100644
--- a/content/renderer/media_recorder/vea_encoder.h
+++ b/content/renderer/media_recorder/vea_encoder.h
@@ -7,6 +7,7 @@
 
 #include <queue>
 
+#include "base/containers/queue.h"
 #include "content/renderer/media_recorder/video_track_recorder.h"
 #include "media/video/video_encode_accelerator.h"
 #include "ui/gfx/geometry/size.h"
@@ -73,7 +74,7 @@
   std::vector<std::unique_ptr<base::SharedMemory>> output_buffers_;
 
   // Shared memory buffers for output with the VEA as FIFO.
-  std::queue<std::unique_ptr<base::SharedMemory>> input_buffers_;
+  base::queue<std::unique_ptr<base::SharedMemory>> input_buffers_;
 
   // Tracks error status.
   bool error_notified_;
@@ -88,7 +89,7 @@
   gfx::Size vea_requested_input_coded_size_;
 
   // Frames and corresponding timestamps in encode as FIFO.
-  std::queue<VideoParamsAndTimestamp> frames_in_encode_;
+  base::queue<VideoParamsAndTimestamp> frames_in_encode_;
 
   // This callback can be exercised on any thread.
   const VideoTrackRecorder::OnErrorCB on_error_callback_;
diff --git a/content/renderer/pepper/content_decryptor_delegate.h b/content/renderer/pepper/content_decryptor_delegate.h
index 4984963..f8e41e6 100644
--- a/content/renderer/pepper/content_decryptor_delegate.h
+++ b/content/renderer/pepper/content_decryptor_delegate.h
@@ -9,12 +9,12 @@
 #include <stdint.h>
 
 #include <map>
-#include <queue>
 #include <string>
 #include <vector>
 
 #include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -237,7 +237,7 @@
   scoped_refptr<PPB_Buffer_Impl> audio_input_resource_;
   scoped_refptr<PPB_Buffer_Impl> video_input_resource_;
 
-  std::queue<uint32_t> free_buffers_;
+  base::queue<uint32_t> free_buffers_;
 
   // Keep track of audio parameters.
   int audio_samples_per_second_;
diff --git a/content/renderer/pepper/message_channel.h b/content/renderer/pepper/message_channel.h
index ea35d20..41d6c9e 100644
--- a/content/renderer/pepper/message_channel.h
+++ b/content/renderer/pepper/message_channel.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_
 #define CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_
 
-#include <deque>
 #include <list>
 #include <map>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "content/renderer/pepper/v8_var_converter.h"
@@ -164,7 +164,7 @@
   };
 
   // This queue stores values being posted to JavaScript.
-  std::deque<blink::WebSerializedScriptValue> js_message_queue_;
+  base::circular_deque<blink::WebSerializedScriptValue> js_message_queue_;
   MessageQueueState js_message_queue_state_;
 
   // True if there is already a posted task to drain the JS message queue.
diff --git a/content/renderer/pepper/pepper_media_stream_audio_track_host.h b/content/renderer/pepper/pepper_media_stream_audio_track_host.h
index 8ca1a17..ab380d1 100644
--- a/content/renderer/pepper/pepper_media_stream_audio_track_host.h
+++ b/content/renderer/pepper/pepper_media_stream_audio_track_host.h
@@ -7,10 +7,10 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 
 #include "base/compiler_specific.h"
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
@@ -109,7 +109,7 @@
     base::Lock lock_;
 
     // A queue for free buffer indices.
-    std::deque<int32_t> buffers_;
+    base::circular_deque<int32_t> buffers_;
 
     // Generation of buffers. It is increased by every |InitBuffers()| call.
     int32_t buffers_generation_;
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc
index 73eb444e..f77e4946b 100644
--- a/content/renderer/pepper/video_decoder_shim.cc
+++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -7,9 +7,11 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #include <GLES2/gl2extchromium.h>
+
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/queue.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
@@ -663,7 +665,7 @@
   bool initialized_ = false;
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
   // Queue of decodes waiting for the decoder.
-  typedef std::queue<PendingDecode> PendingDecodeQueue;
+  using PendingDecodeQueue = base::queue<PendingDecode>;
   PendingDecodeQueue pending_decodes_;
   bool awaiting_decoder_ = false;
   // VideoDecoder returns pictures without information about the decode buffer
diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h
index 1235cef0..16e93d7 100644
--- a/content/renderer/pepper/video_decoder_shim.h
+++ b/content/renderer/pepper/video_decoder_shim.h
@@ -8,10 +8,10 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <vector>
 
 #include "base/containers/hash_tables.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "gpu/command_buffer/common/mailbox.h"
@@ -85,10 +85,10 @@
   // The current decoded frame size.
   gfx::Size texture_size_;
   // Map that takes the plugin's GL texture id to the renderer's GL texture id.
-  typedef base::hash_map<uint32_t, uint32_t> TextureIdMap;
+  using TextureIdMap = base::hash_map<uint32_t, uint32_t>;
   TextureIdMap texture_id_map_;
   // Available textures (these are plugin ids.)
-  typedef base::hash_set<uint32_t> TextureIdSet;
+  using TextureIdSet = base::hash_set<uint32_t>;
   TextureIdSet available_textures_;
   // Track textures that are no longer needed (these are plugin ids.)
   TextureIdSet textures_to_dismiss_;
@@ -96,11 +96,11 @@
   std::vector<gpu::Mailbox> pending_texture_mailboxes_;
 
   // Queue of completed decode ids, for notifying the host.
-  typedef std::queue<uint32_t> CompletedDecodeQueue;
+  using CompletedDecodeQueue = base::queue<uint32_t>;
   CompletedDecodeQueue completed_decodes_;
 
   // Queue of decoded frames that await rgb->yuv conversion.
-  typedef std::queue<std::unique_ptr<PendingFrame>> PendingFrameQueue;
+  using PendingFrameQueue = base::queue<std::unique_ptr<PendingFrame>>;
   PendingFrameQueue pending_frames_;
 
   // The optimal number of textures to allocate for decoder_impl_.
diff --git a/content/renderer/pepper/video_encoder_shim.cc b/content/renderer/pepper/video_encoder_shim.cc
index 4ec1d69..58d4391 100644
--- a/content/renderer/pepper/video_encoder_shim.cc
+++ b/content/renderer/pepper/video_encoder_shim.cc
@@ -6,10 +6,9 @@
 
 #include <inttypes.h>
 
-#include <deque>
-
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/containers/circular_deque.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
 #include "base/sys_info.h"
@@ -143,8 +142,8 @@
 
   uint32_t framerate_;
 
-  std::deque<PendingEncode> frames_;
-  std::deque<BitstreamBuffer> buffers_;
+  base::circular_deque<PendingEncode> frames_;
+  base::circular_deque<BitstreamBuffer> buffers_;
 };
 
 VideoEncoderShim::EncoderImpl::EncoderImpl(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 2c9f02a..ecc3c4d 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -8,7 +8,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <map>
 #include <memory>
 #include <set>
@@ -16,6 +15,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/containers/id_map.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
@@ -1394,7 +1394,8 @@
   // callback, and the remaining elements are the other file chooser completion
   // still waiting to be run (in order).
   struct PendingFileChooser;
-  std::deque<std::unique_ptr<PendingFileChooser>> file_chooser_completions_;
+  base::circular_deque<std::unique_ptr<PendingFileChooser>>
+      file_chooser_completions_;
 
 #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
   // The external popup for the currently showing select popup.
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.cc b/content/renderer/scheduler/resource_dispatch_throttler.cc
index 661daa8b..6eae599 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler.cc
+++ b/content/renderer/scheduler/resource_dispatch_throttler.cc
@@ -5,6 +5,7 @@
 #include "content/renderer/scheduler/resource_dispatch_throttler.h"
 
 #include "base/auto_reset.h"
+#include "base/containers/circular_deque.h"
 #include "base/trace_event/trace_event.h"
 #include "content/common/resource_messages.h"
 #include "ipc/ipc_message_macros.h"
@@ -130,7 +131,7 @@
 
   TRACE_EVENT1("loader", "ResourceDispatchThrottler::FlushAll",
                "total_throttled_messages", throttled_messages_.size());
-  std::deque<IPC::Message*> throttled_messages;
+  base::circular_deque<IPC::Message*> throttled_messages;
   throttled_messages.swap(throttled_messages_);
   for (auto* message : throttled_messages)
     ForwardMessage(message);
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.h b/content/renderer/scheduler/resource_dispatch_throttler.h
index 3ccc788..6c4c933 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler.h
+++ b/content/renderer/scheduler/resource_dispatch_throttler.h
@@ -7,8 +7,7 @@
 
 #include <stdint.h>
 
-#include <deque>
-
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
@@ -68,7 +67,7 @@
   base::Timer flush_timer_;
   base::TimeTicks last_flush_time_;
   uint32_t sent_requests_since_last_flush_;
-  std::deque<IPC::Message*> throttled_messages_;
+  base::circular_deque<IPC::Message*> throttled_messages_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceDispatchThrottler);
 };
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h
index 26731d43..2dee80e 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.h
+++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -5,11 +5,11 @@
 #ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_RUNNER_H_
 #define CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_RUNNER_H_
 
-#include <deque>
 #include <memory>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "content/public/common/page_state.h"
@@ -222,7 +222,7 @@
   std::vector<std::vector<PageState> > session_histories_;
   std::vector<unsigned> current_entry_indexes_;
 
-  std::deque<base::Callback<void(const std::vector<std::string>&)>>
+  base::circular_deque<base::Callback<void(const std::vector<std::string>&)>>
       get_bluetooth_events_callbacks_;
 
   bool is_main_window_;
diff --git a/content/shell/test_runner/event_sender.h b/content/shell/test_runner/event_sender.h
index 390128a..b401231f 100644
--- a/content/shell/test_runner/event_sender.h
+++ b/content/shell/test_runner/event_sender.h
@@ -8,11 +8,11 @@
 #include <stdint.h>
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
@@ -305,7 +305,7 @@
 
   bool replaying_saved_events_;
 
-  std::deque<SavedEvent> mouse_event_queue_;
+  base::circular_deque<SavedEvent> mouse_event_queue_;
 
   blink::WebDragOperationsMask current_drag_effects_allowed_;
 
diff --git a/content/shell/test_runner/mock_web_speech_recognizer.h b/content/shell/test_runner/mock_web_speech_recognizer.h
index b550a6e..72d99b2 100644
--- a/content/shell/test_runner/mock_web_speech_recognizer.h
+++ b/content/shell/test_runner/mock_web_speech_recognizer.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_SHELL_TEST_RUNNER_MOCK_WEB_SPEECH_RECOGNIZER_H_
 #define CONTENT_SHELL_TEST_RUNNER_MOCK_WEB_SPEECH_RECOGNIZER_H_
 
-#include <deque>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "third_party/WebKit/public/web/WebSpeechRecognizer.h"
@@ -80,7 +80,7 @@
   bool was_aborted_;
 
   // Queue of tasks to be run.
-  std::deque<Task*> task_queue_;
+  base::circular_deque<Task*> task_queue_;
   bool task_queue_running_;
 
   WebTestDelegate* delegate_;
diff --git a/content/shell/test_runner/test_runner.h b/content/shell/test_runner/test_runner.h
index 9bfe33989..e7fe912 100644
--- a/content/shell/test_runner/test_runner.h
+++ b/content/shell/test_runner/test_runner.h
@@ -7,12 +7,12 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <memory>
 #include <set>
 #include <string>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "content/shell/test_runner/layout_test_runtime_flags.h"
@@ -210,7 +210,7 @@
    private:
     void ProcessWork();
 
-    std::deque<WorkItem*> queue_;
+    base::circular_deque<WorkItem*> queue_;
     bool frozen_;
     TestRunner* controller_;
 
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 0f1fd55f..fb64334f 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -66,6 +66,8 @@
     "../public/test/download_test_observer.h",
     "../public/test/fake_download_item.cc",
     "../public/test/fake_download_item.h",
+    "../public/test/fake_service_worker_context.cc",
+    "../public/test/fake_service_worker_context.h",
     "../public/test/fake_speech_recognition_manager.cc",
     "../public/test/fake_speech_recognition_manager.h",
     "../public/test/find_test_utils.cc",
@@ -90,8 +92,6 @@
     "../public/test/mock_render_thread.h",
     "../public/test/mock_resource_context.cc",
     "../public/test/mock_resource_context.h",
-    "../public/test/mock_service_worker_context.cc",
-    "../public/test/mock_service_worker_context.h",
     "../public/test/navigation_handle_observer.cc",
     "../public/test/navigation_handle_observer.h",
     "../public/test/navigation_simulator.cc",
diff --git a/extensions/common/api/feedback_private.idl b/extensions/common/api/feedback_private.idl
index 7a2b5e65..2dcc3f1a 100644
--- a/extensions/common/api/feedback_private.idl
+++ b/extensions/common/api/feedback_private.idl
@@ -112,8 +112,26 @@
     // Logs from daemon for Atrus device.
     atrusLog,
 
-    // Network logs.
-    netLog
+    // Network log.
+    netLog,
+
+    // Log of system events.
+    eventLog,
+
+    // Update engine log.
+    updateEngineLog,
+
+    // Log of the current power manager session.
+    powerManagerLatest,
+
+    // Log of the previous power manager session.
+    powerManagerPrevious,
+
+    // Info about system PCI buses devices.
+    lspci,
+
+    // Info about system network interface.
+    ifconfig
   };
 
   // Input parameters for a readLogSource() call.
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 2dd37010..a8331fa2 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -132,6 +132,8 @@
     "ipc_message_sender.h",
     "js_extension_bindings_system.cc",
     "js_extension_bindings_system.h",
+    "js_renderer_messaging_service.cc",
+    "js_renderer_messaging_service.h",
     "lazy_background_page_native_handler.cc",
     "lazy_background_page_native_handler.h",
     "logging_native_handler.cc",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index a71cb3f..a43f1fb 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -73,6 +73,7 @@
 #include "extensions/renderer/id_generator_custom_bindings.h"
 #include "extensions/renderer/ipc_message_sender.h"
 #include "extensions/renderer/js_extension_bindings_system.h"
+#include "extensions/renderer/js_renderer_messaging_service.h"
 #include "extensions/renderer/logging_native_handler.h"
 #include "extensions/renderer/messaging_bindings.h"
 #include "extensions/renderer/module_system.h"
@@ -195,6 +196,7 @@
       content_watcher_(new ContentWatcher()),
       source_map_(&ResourceBundle::GetSharedInstance()),
       v8_schema_registry_(new V8SchemaRegistry),
+      messaging_service_(std::make_unique<JSRendererMessagingService>()),
       user_script_set_manager_observer_(this),
       activity_logging_enabled_(false) {
   const base::CommandLine& command_line =
@@ -964,9 +966,9 @@
 
 void Dispatcher::OnDeliverMessage(const PortId& target_port_id,
                                   const Message& message) {
-  MessagingBindings::DeliverMessage(*script_context_set_, target_port_id,
-                                    message,
-                                    NULL);  // All render frames.
+  messaging_service_->DeliverMessage(*script_context_set_, target_port_id,
+                                     message,
+                                     NULL);  // All render frames.
 }
 
 void Dispatcher::OnDispatchOnConnect(
@@ -977,17 +979,17 @@
     const std::string& tls_channel_id) {
   DCHECK(!target_port_id.is_opener);
 
-  MessagingBindings::DispatchOnConnect(*script_context_set_, target_port_id,
-                                       channel_name, source, info,
-                                       tls_channel_id,
-                                       NULL);  // All render frames.
+  messaging_service_->DispatchOnConnect(*script_context_set_, target_port_id,
+                                        channel_name, source, info,
+                                        tls_channel_id,
+                                        NULL);  // All render frames.
 }
 
 void Dispatcher::OnDispatchOnDisconnect(const PortId& port_id,
                                         const std::string& error_message) {
-  MessagingBindings::DispatchOnDisconnect(*script_context_set_, port_id,
-                                          error_message,
-                                          NULL);  // All render frames.
+  messaging_service_->DispatchOnDisconnect(*script_context_set_, port_id,
+                                           error_message,
+                                           NULL);  // All render frames.
 }
 
 void Dispatcher::OnLoaded(
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h
index 25800fb..9f7e6fd6 100644
--- a/extensions/renderer/dispatcher.h
+++ b/extensions/renderer/dispatcher.h
@@ -56,6 +56,7 @@
 class ContentWatcher;
 class DispatcherDelegate;
 class ExtensionBindingsSystem;
+class JSRendererMessagingService;
 class ScriptContext;
 class ScriptInjectionManager;
 struct EventFilteringInfo;
@@ -146,6 +147,9 @@
                                      V8SchemaRegistry* v8_schema_registry);
 
   ExtensionBindingsSystem* bindings_system() { return bindings_system_.get(); }
+  JSRendererMessagingService* messaging_service() {
+    return messaging_service_.get();
+  }
 
  private:
   // The RendererPermissionsPolicyDelegateTest.CannotScriptWebstore test needs
@@ -282,6 +286,12 @@
   // The bindings system associated with the main thread.
   std::unique_ptr<ExtensionBindingsSystem> bindings_system_;
 
+  // The messaging system.
+  // TODO(devlin): Move this to BindingsSystem? This will only work on the main
+  // thread. But there's more that needs to be done to get messaging to work on
+  // worker threads.
+  std::unique_ptr<JSRendererMessagingService> messaging_service_;
+
   // The platforms system font family and size;
   std::string system_font_family_;
   std::string system_font_size_;
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc
index 7057e0a..2cab418 100644
--- a/extensions/renderer/extension_frame_helper.cc
+++ b/extensions/renderer/extension_frame_helper.cc
@@ -17,7 +17,7 @@
 #include "extensions/renderer/console.h"
 #include "extensions/renderer/content_watcher.h"
 #include "extensions/renderer/dispatcher.h"
-#include "extensions/renderer/messaging_bindings.h"
+#include "extensions/renderer/js_renderer_messaging_service.h"
 #include "extensions/renderer/script_context.h"
 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
@@ -263,7 +263,7 @@
 }
 
 void ExtensionFrameHelper::OnExtensionValidateMessagePort(const PortId& id) {
-  MessagingBindings::ValidateMessagePort(
+  extension_dispatcher_->messaging_service()->ValidateMessagePort(
       extension_dispatcher_->script_context_set(), id, render_frame());
 }
 
@@ -273,19 +273,14 @@
     const ExtensionMsg_TabConnectionInfo& source,
     const ExtensionMsg_ExternalConnectionInfo& info,
     const std::string& tls_channel_id) {
-  MessagingBindings::DispatchOnConnect(
-      extension_dispatcher_->script_context_set(),
-      target_port_id,
-      channel_name,
-      source,
-      info,
-      tls_channel_id,
-      render_frame());
+  extension_dispatcher_->messaging_service()->DispatchOnConnect(
+      extension_dispatcher_->script_context_set(), target_port_id, channel_name,
+      source, info, tls_channel_id, render_frame());
 }
 
 void ExtensionFrameHelper::OnExtensionDeliverMessage(const PortId& target_id,
                                                      const Message& message) {
-  MessagingBindings::DeliverMessage(
+  extension_dispatcher_->messaging_service()->DeliverMessage(
       extension_dispatcher_->script_context_set(), target_id, message,
       render_frame());
 }
@@ -293,7 +288,7 @@
 void ExtensionFrameHelper::OnExtensionDispatchOnDisconnect(
     const PortId& id,
     const std::string& error_message) {
-  MessagingBindings::DispatchOnDisconnect(
+  extension_dispatcher_->messaging_service()->DispatchOnDisconnect(
       extension_dispatcher_->script_context_set(), id, error_message,
       render_frame());
 }
diff --git a/extensions/renderer/js_renderer_messaging_service.cc b/extensions/renderer/js_renderer_messaging_service.cc
new file mode 100644
index 0000000..d8cee8b
--- /dev/null
+++ b/extensions/renderer/js_renderer_messaging_service.cc
@@ -0,0 +1,312 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/js_renderer_messaging_service.h"
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/callback_helpers.h"
+#include "base/values.h"
+#include "content/public/child/v8_value_converter.h"
+#include "content/public/common/child_process_host.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "extensions/common/api/messaging/message.h"
+#include "extensions/common/api/messaging/port_id.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_bindings_system.h"
+#include "extensions/renderer/extension_port.h"
+#include "extensions/renderer/extensions_renderer_client.h"
+#include "extensions/renderer/messaging_bindings.h"
+#include "extensions/renderer/script_context.h"
+#include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/v8_helpers.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+using v8_helpers::ToV8String;
+
+namespace {
+
+void HasMessagePort(const PortId& port_id,
+                    bool* has_port,
+                    ScriptContext* script_context) {
+  if (*has_port)
+    return;  // Stop checking if the port was found.
+
+  MessagingBindings* bindings = MessagingBindings::ForContext(script_context);
+  DCHECK(bindings);
+  // No need for |=; we know this is false right now from above.
+  *has_port = bindings->GetPortWithId(port_id) != nullptr;
+}
+
+void DispatchOnConnectToScriptContext(
+    const PortId& target_port_id,
+    const std::string& channel_name,
+    const ExtensionMsg_TabConnectionInfo* source,
+    const ExtensionMsg_ExternalConnectionInfo& info,
+    const std::string& tls_channel_id,
+    bool* port_created,
+    ScriptContext* script_context) {
+  MessagingBindings* bindings = MessagingBindings::ForContext(script_context);
+  DCHECK(bindings);
+
+  // If the channel was opened by this same context, ignore it. This should only
+  // happen when messages are sent to an entire process (rather than a single
+  // frame) as an optimization; otherwise the browser process filters this out.
+  if (bindings->context_id() == target_port_id.context_id)
+    return;
+
+  // First, determine the event we'll use to connect.
+  std::string target_extension_id = script_context->GetExtensionID();
+  bool is_external = info.source_id != target_extension_id;
+  std::string event_name;
+  if (channel_name == "chrome.extension.sendRequest") {
+    event_name =
+        is_external ? "extension.onRequestExternal" : "extension.onRequest";
+  } else if (channel_name == "chrome.runtime.sendMessage") {
+    event_name =
+        is_external ? "runtime.onMessageExternal" : "runtime.onMessage";
+  } else {
+    event_name =
+        is_external ? "runtime.onConnectExternal" : "runtime.onConnect";
+  }
+
+  ExtensionBindingsSystem* bindings_system =
+      ExtensionsRendererClient::Get()->GetDispatcher()->bindings_system();
+  // If there are no listeners for the given event, then we know the port won't
+  // be used in this context.
+  if (!bindings_system->HasEventListenerInContext(event_name, script_context)) {
+    return;
+  }
+  *port_created = true;
+
+  ExtensionPort* port = bindings->CreateNewPortWithId(target_port_id);
+
+  v8::Isolate* isolate = script_context->isolate();
+  v8::HandleScope handle_scope(isolate);
+
+  const std::string& source_url_spec = info.source_url.spec();
+  const Extension* extension = script_context->extension();
+
+  v8::Local<v8::Value> tab = v8::Null(isolate);
+  v8::Local<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
+  v8::Local<v8::Value> guest_process_id = v8::Undefined(isolate);
+  v8::Local<v8::Value> guest_render_frame_routing_id = v8::Undefined(isolate);
+
+  if (extension) {
+    if (!source->tab.empty() && !extension->is_platform_app()) {
+      tab = content::V8ValueConverter::Create()->ToV8Value(
+          &source->tab, script_context->v8_context());
+    }
+
+    ExternallyConnectableInfo* externally_connectable =
+        ExternallyConnectableInfo::Get(extension);
+    if (externally_connectable &&
+        externally_connectable->accepts_tls_channel_id) {
+      v8::Local<v8::String> v8_tls_channel_id;
+      if (ToV8String(isolate, tls_channel_id.c_str(), &v8_tls_channel_id))
+        tls_channel_id_value = v8_tls_channel_id;
+    }
+
+    if (info.guest_process_id != content::ChildProcessHost::kInvalidUniqueID) {
+      guest_process_id = v8::Integer::New(isolate, info.guest_process_id);
+      guest_render_frame_routing_id =
+          v8::Integer::New(isolate, info.guest_render_frame_routing_id);
+    }
+  }
+
+  v8::Local<v8::String> v8_channel_name;
+  v8::Local<v8::String> v8_source_id;
+  v8::Local<v8::String> v8_target_extension_id;
+  v8::Local<v8::String> v8_source_url_spec;
+  if (!ToV8String(isolate, channel_name.c_str(), &v8_channel_name) ||
+      !ToV8String(isolate, info.source_id.c_str(), &v8_source_id) ||
+      !ToV8String(isolate, target_extension_id.c_str(),
+                  &v8_target_extension_id) ||
+      !ToV8String(isolate, source_url_spec.c_str(), &v8_source_url_spec)) {
+    NOTREACHED() << "dispatchOnConnect() passed non-string argument";
+    return;
+  }
+
+  v8::Local<v8::Value> arguments[] = {
+      // portId
+      v8::Integer::New(isolate, port->js_id()),
+      // channelName
+      v8_channel_name,
+      // sourceTab
+      tab,
+      // source_frame_id
+      v8::Integer::New(isolate, source->frame_id),
+      // guestProcessId
+      guest_process_id,
+      // guestRenderFrameRoutingId
+      guest_render_frame_routing_id,
+      // sourceExtensionId
+      v8_source_id,
+      // targetExtensionId
+      v8_target_extension_id,
+      // sourceUrl
+      v8_source_url_spec,
+      // tlsChannelId
+      tls_channel_id_value,
+  };
+
+  // Note: this can execute asynchronously if JS is suspended.
+  script_context->module_system()->CallModuleMethodSafe(
+      "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
+}
+
+void DeliverMessageToScriptContext(const Message& message,
+                                   const PortId& target_port_id,
+                                   ScriptContext* script_context) {
+  MessagingBindings* bindings = MessagingBindings::ForContext(script_context);
+  DCHECK(bindings);
+  ExtensionPort* port = bindings->GetPortWithId(target_port_id);
+  if (!port)
+    return;
+
+  v8::Isolate* isolate = script_context->isolate();
+  v8::HandleScope handle_scope(isolate);
+
+  v8::Local<v8::Value> port_id_handle =
+      v8::Integer::New(isolate, port->js_id());
+
+  v8::Local<v8::String> v8_data;
+  if (!ToV8String(isolate, message.data.c_str(), &v8_data))
+    return;
+  std::vector<v8::Local<v8::Value>> arguments;
+  arguments.push_back(v8_data);
+  arguments.push_back(port_id_handle);
+
+  std::unique_ptr<blink::WebScopedUserGesture> web_user_gesture;
+  std::unique_ptr<blink::WebScopedWindowFocusAllowedIndicator>
+      allow_window_focus;
+  if (message.user_gesture) {
+    web_user_gesture.reset(
+        new blink::WebScopedUserGesture(script_context->web_frame()));
+
+    if (script_context->web_frame()) {
+      blink::WebDocument document = script_context->web_frame()->GetDocument();
+      allow_window_focus.reset(
+          new blink::WebScopedWindowFocusAllowedIndicator(&document));
+    }
+  }
+
+  script_context->module_system()->CallModuleMethodSafe(
+      "messaging", "dispatchOnMessage", &arguments);
+}
+
+void DispatchOnDisconnectToScriptContext(const PortId& port_id,
+                                         const std::string& error_message,
+                                         ScriptContext* script_context) {
+  MessagingBindings* bindings = MessagingBindings::ForContext(script_context);
+  DCHECK(bindings);
+  ExtensionPort* port = bindings->GetPortWithId(port_id);
+  if (!port)
+    return;
+
+  v8::Isolate* isolate = script_context->isolate();
+  v8::HandleScope handle_scope(isolate);
+
+  std::vector<v8::Local<v8::Value>> arguments;
+  arguments.push_back(v8::Integer::New(isolate, port->js_id()));
+  v8::Local<v8::String> v8_error_message;
+  if (!error_message.empty())
+    ToV8String(isolate, error_message.c_str(), &v8_error_message);
+  if (!v8_error_message.IsEmpty()) {
+    arguments.push_back(v8_error_message);
+  } else {
+    arguments.push_back(v8::Null(isolate));
+  }
+
+  script_context->module_system()->CallModuleMethodSafe(
+      "messaging", "dispatchOnDisconnect", &arguments);
+}
+
+}  // namespace
+
+JSRendererMessagingService::JSRendererMessagingService() {}
+JSRendererMessagingService::~JSRendererMessagingService() {}
+
+void JSRendererMessagingService::ValidateMessagePort(
+    const ScriptContextSet& context_set,
+    const PortId& port_id,
+    content::RenderFrame* render_frame) {
+  int routing_id = render_frame->GetRoutingID();
+
+  bool has_port = false;
+  context_set.ForEach(render_frame,
+                      base::Bind(&HasMessagePort, port_id, &has_port));
+
+  // A reply is only sent if the port is missing, because the port is assumed to
+  // exist unless stated otherwise.
+  if (!has_port) {
+    content::RenderThread::Get()->Send(
+        new ExtensionHostMsg_CloseMessagePort(routing_id, port_id, false));
+  }
+}
+
+void JSRendererMessagingService::DispatchOnConnect(
+    const ScriptContextSet& context_set,
+    const PortId& target_port_id,
+    const std::string& channel_name,
+    const ExtensionMsg_TabConnectionInfo& source,
+    const ExtensionMsg_ExternalConnectionInfo& info,
+    const std::string& tls_channel_id,
+    content::RenderFrame* restrict_to_render_frame) {
+  DCHECK(!target_port_id.is_opener);
+  int routing_id = restrict_to_render_frame
+                       ? restrict_to_render_frame->GetRoutingID()
+                       : MSG_ROUTING_NONE;
+  bool port_created = false;
+  context_set.ForEach(
+      info.target_id, restrict_to_render_frame,
+      base::Bind(&DispatchOnConnectToScriptContext, target_port_id,
+                 channel_name, &source, info, tls_channel_id, &port_created));
+  // Note: |restrict_to_render_frame| may have been deleted at this point!
+
+  if (port_created) {
+    content::RenderThread::Get()->Send(
+        new ExtensionHostMsg_OpenMessagePort(routing_id, target_port_id));
+  } else {
+    content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseMessagePort(
+        routing_id, target_port_id, false));
+  }
+}
+
+void JSRendererMessagingService::DeliverMessage(
+    const ScriptContextSet& context_set,
+    const PortId& target_port_id,
+    const Message& message,
+    content::RenderFrame* restrict_to_render_frame) {
+  context_set.ForEach(
+      restrict_to_render_frame,
+      base::Bind(&DeliverMessageToScriptContext, message, target_port_id));
+}
+
+void JSRendererMessagingService::DispatchOnDisconnect(
+    const ScriptContextSet& context_set,
+    const PortId& port_id,
+    const std::string& error_message,
+    content::RenderFrame* restrict_to_render_frame) {
+  context_set.ForEach(
+      restrict_to_render_frame,
+      base::Bind(&DispatchOnDisconnectToScriptContext, port_id, error_message));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/js_renderer_messaging_service.h b/extensions/renderer/js_renderer_messaging_service.h
new file mode 100644
index 0000000..b2a7990
--- /dev/null
+++ b/extensions/renderer/js_renderer_messaging_service.h
@@ -0,0 +1,68 @@
+// 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 EXTENSIONS_RENDERER_JS_RENDERER_MESSAGING_SERVICE_H_
+#define EXTENSIONS_RENDERER_JS_RENDERER_MESSAGING_SERVICE_H_
+
+#include <string>
+
+#include "base/macros.h"
+
+struct ExtensionMsg_ExternalConnectionInfo;
+struct ExtensionMsg_TabConnectionInfo;
+
+namespace content {
+class RenderFrame;
+}
+
+namespace extensions {
+class ScriptContextSet;
+struct Message;
+struct PortId;
+
+// The messaging service to handle dispatching extension messages and connection
+// events to different contexts.
+class JSRendererMessagingService {
+ public:
+  JSRendererMessagingService();
+  ~JSRendererMessagingService();
+
+  // Checks whether the port exists in the given frame. If it does not, a reply
+  // is sent back to the browser.
+  void ValidateMessagePort(const ScriptContextSet& context_set,
+                           const PortId& port_id,
+                           content::RenderFrame* render_frame);
+
+  // Dispatches the onConnect content script messaging event to some contexts
+  // in |context_set|. If |restrict_to_render_frame| is specified, only contexts
+  // in that render frame will receive the message.
+  void DispatchOnConnect(const ScriptContextSet& context_set,
+                         const PortId& target_port_id,
+                         const std::string& channel_name,
+                         const ExtensionMsg_TabConnectionInfo& source,
+                         const ExtensionMsg_ExternalConnectionInfo& info,
+                         const std::string& tls_channel_id,
+                         content::RenderFrame* restrict_to_render_frame);
+
+  // Delivers a message sent using content script messaging to some of the
+  // contexts in |bindings_context_set|. If |restrict_to_render_frame| is
+  // specified, only contexts in that render view will receive the message.
+  void DeliverMessage(const ScriptContextSet& context_set,
+                      const PortId& target_port_id,
+                      const Message& message,
+                      content::RenderFrame* restrict_to_render_frame);
+
+  // Dispatches the onDisconnect event in response to the channel being closed.
+  void DispatchOnDisconnect(const ScriptContextSet& context_set,
+                            const PortId& port_id,
+                            const std::string& error_message,
+                            content::RenderFrame* restrict_to_render_frame);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(JSRendererMessagingService);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_JS_RENDERER_MESSAGING_SERVICE_H_
diff --git a/extensions/renderer/messaging_bindings.cc b/extensions/renderer/messaging_bindings.cc
index 9947579..a118fd0d 100644
--- a/extensions/renderer/messaging_bindings.cc
+++ b/extensions/renderer/messaging_bindings.cc
@@ -15,30 +15,18 @@
 #include "base/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/values.h"
-#include "content/public/child/v8_value_converter.h"
-#include "content/public/common/child_process_host.h"
 #include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_thread.h"
 #include "extensions/common/api/messaging/message.h"
 #include "extensions/common/api/messaging/port_id.h"
 #include "extensions/common/extension_messages.h"
-#include "extensions/common/manifest_handlers/externally_connectable.h"
-#include "extensions/renderer/dispatcher.h"
-#include "extensions/renderer/extension_bindings_system.h"
 #include "extensions/renderer/extension_frame_helper.h"
 #include "extensions/renderer/extension_port.h"
-#include "extensions/renderer/extensions_renderer_client.h"
 #include "extensions/renderer/gc_callback.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
 #include "extensions/renderer/v8_helpers.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
-#include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
 #include "v8/include/v8.h"
 
@@ -60,202 +48,6 @@
 base::LazyInstance<std::map<ScriptContext*, MessagingBindings*>>::
     DestructorAtExit g_messaging_map = LAZY_INSTANCE_INITIALIZER;
 
-void HasMessagePort(const PortId& port_id,
-                    bool* has_port,
-                    ScriptContext* script_context) {
-  if (*has_port)
-    return;  // Stop checking if the port was found.
-
-  MessagingBindings* bindings = g_messaging_map.Get()[script_context];
-  DCHECK(bindings);
-  // No need for |=; we know this is false right now from above.
-  *has_port = bindings->GetPortWithId(port_id) != nullptr;
-}
-
-void DispatchOnConnectToScriptContext(
-    const PortId& target_port_id,
-    const std::string& channel_name,
-    const ExtensionMsg_TabConnectionInfo* source,
-    const ExtensionMsg_ExternalConnectionInfo& info,
-    const std::string& tls_channel_id,
-    bool* port_created,
-    ScriptContext* script_context) {
-  MessagingBindings* bindings = g_messaging_map.Get()[script_context];
-  DCHECK(bindings);
-
-  // If the channel was opened by this same context, ignore it. This should only
-  // happen when messages are sent to an entire process (rather than a single
-  // frame) as an optimization; otherwise the browser process filters this out.
-  if (bindings->context_id() == target_port_id.context_id)
-    return;
-
-  // First, determine the event we'll use to connect.
-  std::string target_extension_id = script_context->GetExtensionID();
-  bool is_external = info.source_id != target_extension_id;
-  std::string event_name;
-  if (channel_name == "chrome.extension.sendRequest") {
-    event_name =
-        is_external ? "extension.onRequestExternal" : "extension.onRequest";
-  } else if (channel_name == "chrome.runtime.sendMessage") {
-    event_name =
-        is_external ? "runtime.onMessageExternal" : "runtime.onMessage";
-  } else {
-    event_name =
-        is_external ? "runtime.onConnectExternal" : "runtime.onConnect";
-  }
-
-  ExtensionBindingsSystem* bindings_system =
-      ExtensionsRendererClient::Get()->GetDispatcher()->bindings_system();
-  // If there are no listeners for the given event, then we know the port won't
-  // be used in this context.
-  if (!bindings_system->HasEventListenerInContext(event_name, script_context)) {
-    return;
-  }
-  *port_created = true;
-
-  ExtensionPort* port = bindings->CreateNewPortWithId(target_port_id);
-
-  v8::Isolate* isolate = script_context->isolate();
-  v8::HandleScope handle_scope(isolate);
-
-  const std::string& source_url_spec = info.source_url.spec();
-  const Extension* extension = script_context->extension();
-
-  v8::Local<v8::Value> tab = v8::Null(isolate);
-  v8::Local<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
-  v8::Local<v8::Value> guest_process_id = v8::Undefined(isolate);
-  v8::Local<v8::Value> guest_render_frame_routing_id = v8::Undefined(isolate);
-
-  if (extension) {
-    if (!source->tab.empty() && !extension->is_platform_app()) {
-      tab = content::V8ValueConverter::Create()->ToV8Value(
-          &source->tab, script_context->v8_context());
-    }
-
-    ExternallyConnectableInfo* externally_connectable =
-        ExternallyConnectableInfo::Get(extension);
-    if (externally_connectable &&
-        externally_connectable->accepts_tls_channel_id) {
-      v8::Local<v8::String> v8_tls_channel_id;
-      if (ToV8String(isolate, tls_channel_id.c_str(), &v8_tls_channel_id))
-        tls_channel_id_value = v8_tls_channel_id;
-    }
-
-    if (info.guest_process_id != content::ChildProcessHost::kInvalidUniqueID) {
-      guest_process_id = v8::Integer::New(isolate, info.guest_process_id);
-      guest_render_frame_routing_id =
-          v8::Integer::New(isolate, info.guest_render_frame_routing_id);
-    }
-  }
-
-  v8::Local<v8::String> v8_channel_name;
-  v8::Local<v8::String> v8_source_id;
-  v8::Local<v8::String> v8_target_extension_id;
-  v8::Local<v8::String> v8_source_url_spec;
-  if (!ToV8String(isolate, channel_name.c_str(), &v8_channel_name) ||
-      !ToV8String(isolate, info.source_id.c_str(), &v8_source_id) ||
-      !ToV8String(isolate, target_extension_id.c_str(),
-                  &v8_target_extension_id) ||
-      !ToV8String(isolate, source_url_spec.c_str(), &v8_source_url_spec)) {
-    NOTREACHED() << "dispatchOnConnect() passed non-string argument";
-    return;
-  }
-
-  v8::Local<v8::Value> arguments[] = {
-      // portId
-      v8::Integer::New(isolate, port->js_id()),
-      // channelName
-      v8_channel_name,
-      // sourceTab
-      tab,
-      // source_frame_id
-      v8::Integer::New(isolate, source->frame_id),
-      // guestProcessId
-      guest_process_id,
-      // guestRenderFrameRoutingId
-      guest_render_frame_routing_id,
-      // sourceExtensionId
-      v8_source_id,
-      // targetExtensionId
-      v8_target_extension_id,
-      // sourceUrl
-      v8_source_url_spec,
-      // tlsChannelId
-      tls_channel_id_value,
-  };
-
-  // Note: this can execute asynchronously if JS is suspended.
-  script_context->module_system()->CallModuleMethodSafe(
-      "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
-}
-
-void DeliverMessageToScriptContext(const Message& message,
-                                   const PortId& target_port_id,
-                                   ScriptContext* script_context) {
-  MessagingBindings* bindings = g_messaging_map.Get()[script_context];
-  DCHECK(bindings);
-  ExtensionPort* port = bindings->GetPortWithId(target_port_id);
-  if (!port)
-    return;
-
-  v8::Isolate* isolate = script_context->isolate();
-  v8::HandleScope handle_scope(isolate);
-
-  v8::Local<v8::Value> port_id_handle =
-      v8::Integer::New(isolate, port->js_id());
-
-  v8::Local<v8::String> v8_data;
-  if (!ToV8String(isolate, message.data.c_str(), &v8_data))
-    return;
-  std::vector<v8::Local<v8::Value>> arguments;
-  arguments.push_back(v8_data);
-  arguments.push_back(port_id_handle);
-
-  std::unique_ptr<blink::WebScopedUserGesture> web_user_gesture;
-  std::unique_ptr<blink::WebScopedWindowFocusAllowedIndicator>
-      allow_window_focus;
-  if (message.user_gesture) {
-    web_user_gesture.reset(
-        new blink::WebScopedUserGesture(script_context->web_frame()));
-
-    if (script_context->web_frame()) {
-      blink::WebDocument document = script_context->web_frame()->GetDocument();
-      allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator(
-          &document));
-    }
-  }
-
-  script_context->module_system()->CallModuleMethodSafe(
-      "messaging", "dispatchOnMessage", &arguments);
-}
-
-void DispatchOnDisconnectToScriptContext(const PortId& port_id,
-                                         const std::string& error_message,
-                                         ScriptContext* script_context) {
-  MessagingBindings* bindings = g_messaging_map.Get()[script_context];
-  DCHECK(bindings);
-  ExtensionPort* port = bindings->GetPortWithId(port_id);
-  if (!port)
-    return;
-
-  v8::Isolate* isolate = script_context->isolate();
-  v8::HandleScope handle_scope(isolate);
-
-  std::vector<v8::Local<v8::Value>> arguments;
-  arguments.push_back(v8::Integer::New(isolate, port->js_id()));
-  v8::Local<v8::String> v8_error_message;
-  if (!error_message.empty())
-    ToV8String(isolate, error_message.c_str(), &v8_error_message);
-  if (!v8_error_message.IsEmpty()) {
-    arguments.push_back(v8_error_message);
-  } else {
-    arguments.push_back(v8::Null(isolate));
-  }
-
-  script_context->module_system()->CallModuleMethodSafe(
-      "messaging", "dispatchOnDisconnect", &arguments);
-}
-
 }  // namespace
 
 MessagingBindings::MessagingBindings(ScriptContext* context)
@@ -290,73 +82,8 @@
 }
 
 // static
-void MessagingBindings::ValidateMessagePort(
-    const ScriptContextSet& context_set,
-    const PortId& port_id,
-    content::RenderFrame* render_frame) {
-  int routing_id = render_frame->GetRoutingID();
-
-  bool has_port = false;
-  context_set.ForEach(render_frame,
-                      base::Bind(&HasMessagePort, port_id, &has_port));
-
-  // A reply is only sent if the port is missing, because the port is assumed to
-  // exist unless stated otherwise.
-  if (!has_port) {
-    content::RenderThread::Get()->Send(
-        new ExtensionHostMsg_CloseMessagePort(routing_id, port_id, false));
-  }
-}
-
-// static
-void MessagingBindings::DispatchOnConnect(
-    const ScriptContextSet& context_set,
-    const PortId& target_port_id,
-    const std::string& channel_name,
-    const ExtensionMsg_TabConnectionInfo& source,
-    const ExtensionMsg_ExternalConnectionInfo& info,
-    const std::string& tls_channel_id,
-    content::RenderFrame* restrict_to_render_frame) {
-  DCHECK(!target_port_id.is_opener);
-  int routing_id = restrict_to_render_frame
-                       ? restrict_to_render_frame->GetRoutingID()
-                       : MSG_ROUTING_NONE;
-  bool port_created = false;
-  context_set.ForEach(
-      info.target_id, restrict_to_render_frame,
-      base::Bind(&DispatchOnConnectToScriptContext, target_port_id,
-                 channel_name, &source, info, tls_channel_id, &port_created));
-  // Note: |restrict_to_render_frame| may have been deleted at this point!
-
-  if (port_created) {
-    content::RenderThread::Get()->Send(
-        new ExtensionHostMsg_OpenMessagePort(routing_id, target_port_id));
-  } else {
-    content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseMessagePort(
-        routing_id, target_port_id, false));
-  }
-}
-
-// static
-void MessagingBindings::DeliverMessage(
-    const ScriptContextSet& context_set,
-    const PortId& target_port_id,
-    const Message& message,
-    content::RenderFrame* restrict_to_render_frame) {
-  context_set.ForEach(
-      restrict_to_render_frame,
-      base::Bind(&DeliverMessageToScriptContext, message, target_port_id));
-}
-
-// static
-void MessagingBindings::DispatchOnDisconnect(
-    const ScriptContextSet& context_set,
-    const PortId& port_id,
-    const std::string& error_message,
-    content::RenderFrame* restrict_to_render_frame) {
-  context_set.ForEach(
-      restrict_to_render_frame,
-      base::Bind(&DispatchOnDisconnectToScriptContext, port_id, error_message));
+MessagingBindings* MessagingBindings::ForContext(ScriptContext* context) {
+  return g_messaging_map.Get()[context];
 }
 
 ExtensionPort* MessagingBindings::GetPortWithId(const PortId& id) {
diff --git a/extensions/renderer/messaging_bindings.h b/extensions/renderer/messaging_bindings.h
index 9e46331..297698f 100644
--- a/extensions/renderer/messaging_bindings.h
+++ b/extensions/renderer/messaging_bindings.h
@@ -12,18 +12,10 @@
 #include "base/unguessable_token.h"
 #include "extensions/renderer/object_backed_native_handler.h"
 
-struct ExtensionMsg_ExternalConnectionInfo;
-struct ExtensionMsg_TabConnectionInfo;
-
-namespace content {
-class RenderFrame;
-}
-
 namespace extensions {
 class ExtensionPort;
-struct Message;
+class ScriptContext;
 struct PortId;
-class ScriptContextSet;
 
 // Manually implements JavaScript bindings for extension messaging.
 class MessagingBindings : public ObjectBackedNativeHandler {
@@ -31,37 +23,8 @@
   explicit MessagingBindings(ScriptContext* script_context);
   ~MessagingBindings() override;
 
-  // Checks whether the port exists in the given frame. If it does not, a reply
-  // is sent back to the browser.
-  static void ValidateMessagePort(const ScriptContextSet& context_set,
-                                  const PortId& port_id,
-                                  content::RenderFrame* render_frame);
-
-  // Dispatches the onConnect content script messaging event to some contexts
-  // in |context_set|. If |restrict_to_render_frame| is specified, only contexts
-  // in that render frame will receive the message.
-  static void DispatchOnConnect(const ScriptContextSet& context_set,
-                                const PortId& target_port_id,
-                                const std::string& channel_name,
-                                const ExtensionMsg_TabConnectionInfo& source,
-                                const ExtensionMsg_ExternalConnectionInfo& info,
-                                const std::string& tls_channel_id,
-                                content::RenderFrame* restrict_to_render_frame);
-
-  // Delivers a message sent using content script messaging to some of the
-  // contexts in |bindings_context_set|. If |restrict_to_render_frame| is
-  // specified, only contexts in that render view will receive the message.
-  static void DeliverMessage(const ScriptContextSet& context_set,
-                             const PortId& target_port_id,
-                             const Message& message,
-                             content::RenderFrame* restrict_to_render_frame);
-
-  // Dispatches the onDisconnect event in response to the channel being closed.
-  static void DispatchOnDisconnect(
-      const ScriptContextSet& context_set,
-      const PortId& port_id,
-      const std::string& error_message,
-      content::RenderFrame* restrict_to_render_frame);
+  // Returns the MessagingBindings associated with the given |context|.
+  static MessagingBindings* ForContext(ScriptContext* context);
 
   // Returns an existing port with the given |id|, or null.
   ExtensionPort* GetPortWithId(const PortId& id);
diff --git a/media/formats/mpeg/adts_stream_parser.cc b/media/formats/mpeg/adts_stream_parser.cc
index 1089107b..d80a1843 100644
--- a/media/formats/mpeg/adts_stream_parser.cc
+++ b/media/formats/mpeg/adts_stream_parser.cc
@@ -112,8 +112,6 @@
                           << 3;
     extra_data->push_back(esds >> 8);
     extra_data->push_back(esds & 0xFF);
-    if (media_log())
-      DCHECK(mp4::AAC().Parse(*extra_data, media_log()));
   }
 
   return bytes_read;
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index e75af8838..71a0f34 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -218,7 +218,6 @@
     NetLog* net_log)
     : params_(std::move(params)),
       use_localhost_requests_(false),
-      use_small_responses_(false),
       disable_offline_check_(false),
       add_default_platform_observations_(true),
       tick_clock_(new base::DefaultTickClock()),
@@ -677,8 +676,7 @@
 void NetworkQualityEstimator::SetUseSmallResponsesForTesting(
     bool use_small_responses) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  use_small_responses_ = use_small_responses;
-  throughput_analyzer_->SetUseSmallResponsesForTesting(use_small_responses_);
+  params_->SetUseSmallResponsesForTesting(use_small_responses);
 }
 
 void NetworkQualityEstimator::DisableOfflineCheckForTesting(
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
index af987fe..3b7eb4d6 100644
--- a/net/nqe/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -526,11 +526,6 @@
   // network quality. Set to true only for tests.
   bool use_localhost_requests_;
 
-  // Determines if the responses smaller than |kMinTransferSizeInBytes|
-  // or shorter than |kMinTransferSizeInBytes| can be used in estimating the
-  // network quality. Set to true only for tests.
-  bool use_small_responses_;
-
   // When set to true, the device offline check is disabled when computing the
   // effective connection type or when writing the prefs. Set to true only for
   // testing.
diff --git a/net/nqe/network_quality_estimator_params.cc b/net/nqe/network_quality_estimator_params.cc
index 23ce9f9..a6bc3bd1 100644
--- a/net/nqe/network_quality_estimator_params.cc
+++ b/net/nqe/network_quality_estimator_params.cc
@@ -375,7 +375,11 @@
       throughput_min_requests_in_flight_(
           GetValueForVariationParam(params_,
                                     "throughput_min_requests_in_flight",
-                                    1)),
+                                    5)),
+      throughput_min_transfer_size_kilobytes_(
+          GetValueForVariationParam(params_,
+                                    "throughput_min_transfer_size_kilobytes",
+                                    32)),
       weight_multiplier_per_second_(GetWeightMultiplierPerSecond(params_)),
       weight_multiplier_per_signal_strength_level_(
           GetDoubleValueForVariationParamWithDefaultValue(
@@ -418,7 +422,8 @@
           GetDoubleValueForVariationParamWithDefaultValue(
               params_,
               "historical_time_threshold",
-              60000))) {
+              60000))),
+      use_small_responses_(false) {
   DCHECK_LE(0.0, correlation_uma_logging_probability_);
   DCHECK_GE(1.0, correlation_uma_logging_probability_);
   DCHECK(lower_bound_http_rtt_transport_rtt_multiplier_ == -1 ||
@@ -447,6 +452,17 @@
 NetworkQualityEstimatorParams::~NetworkQualityEstimatorParams() {
 }
 
+void NetworkQualityEstimatorParams::SetUseSmallResponsesForTesting(
+    bool use_small_responses) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  use_small_responses_ = use_small_responses;
+}
+
+bool NetworkQualityEstimatorParams::use_small_responses() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return use_small_responses_;
+};
+
 // static
 NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm
 NetworkQualityEstimatorParams::GetEffectiveConnectionTypeAlgorithmFromString(
@@ -479,6 +495,22 @@
   return kDefaultEffectiveConnectionTypeAlgorithm;
 }
 
+size_t NetworkQualityEstimatorParams::throughput_min_requests_in_flight()
+    const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // If |use_small_responses_| is set to true for testing, then consider one
+  // request as sufficient for taking throughput sample.
+  return use_small_responses_ ? 1 : throughput_min_requests_in_flight_;
+}
+
+int64_t NetworkQualityEstimatorParams::GetThroughputMinTransferSizeBits()
+    const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return static_cast<int64_t>(throughput_min_transfer_size_kilobytes_) * 8 *
+         1000;
+}
+
 // static
 const char* NetworkQualityEstimatorParams::GetNameForConnectionType(
     NetworkChangeNotifier::ConnectionType connection_type) {
diff --git a/net/nqe/network_quality_estimator_params.h b/net/nqe/network_quality_estimator_params.h
index 5d02e97..02b4e1d 100644
--- a/net/nqe/network_quality_estimator_params.h
+++ b/net/nqe/network_quality_estimator_params.h
@@ -68,9 +68,11 @@
   // Returns the minimum number of requests in-flight to consider the network
   // fully utilized. A throughput observation is taken only when the network is
   // considered as fully utilized.
-  size_t throughput_min_requests_in_flight() const {
-    return throughput_min_requests_in_flight_;
-  }
+  size_t throughput_min_requests_in_flight() const;
+
+  // Tiny transfer sizes may give inaccurate throughput results.
+  // Minimum size of the transfer over which the throughput is computed.
+  int64_t GetThroughputMinTransferSizeBits() const;
 
   // Returns the weight multiplier per second, which represents the factor by
   // which the weight of an observation reduces every second.
@@ -173,12 +175,23 @@
     return historical_time_threshold_;
   }
 
+  // Determines if the responses smaller than |kMinTransferSizeInBytes|
+  // or shorter than |kMinTransferSizeInBytes| can be used in estimating the
+  // network quality. Set to true only for tests.
+  bool use_small_responses() const;
+
+  // |use_small_responses| should only be true when testing.
+  // Allows the responses smaller than |kMinTransferSizeInBits| to be used for
+  // network quality estimation.
+  void SetUseSmallResponsesForTesting(bool use_small_responses);
+
  private:
   // Map containing all field trial parameters related to
   // NetworkQualityEstimator field trial.
   const std::map<std::string, std::string> params_;
 
   const size_t throughput_min_requests_in_flight_;
+  const int throughput_min_transfer_size_kilobytes_;
   const double weight_multiplier_per_second_;
   const double weight_multiplier_per_signal_strength_level_;
   const double correlation_uma_logging_probability_;
@@ -191,6 +204,8 @@
   const base::TimeDelta recent_time_threshold_;
   const base::TimeDelta historical_time_threshold_;
 
+  bool use_small_responses_;
+
   EffectiveConnectionTypeAlgorithm effective_connection_type_algorithm_;
 
   // Default network quality observations obtained from |params_|.
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
index 3f56090..4549137 100644
--- a/net/nqe/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -195,6 +195,7 @@
   base::HistogramTester histogram_tester;
   // Enable requests to local host to be used for network quality estimation.
   std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
   TestNetworkQualityEstimator estimator(variation_params);
 
   estimator.SimulateNetworkChange(
@@ -347,6 +348,7 @@
         NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET}) {
     base::HistogramTester histogram_tester;
     std::map<std::string, std::string> variation_params;
+    variation_params["throughput_min_requests_in_flight"] = "1";
     TestNetworkQualityEstimator estimator(variation_params);
 
     const std::string connection_id =
@@ -465,6 +467,7 @@
   std::map<std::string, std::string> variation_params;
   // Do not set |persistent_cache_reading_enabled| variation param.
   variation_params["persistent_cache_reading_enabled"] = "false";
+  variation_params["throughput_min_requests_in_flight"] = "1";
   TestNetworkQualityEstimator estimator(variation_params);
 
   estimator.SimulateNetworkChange(
@@ -545,7 +548,9 @@
 }
 
 TEST(NetworkQualityEstimatorTest, StoreObservations) {
-  TestNetworkQualityEstimator estimator;
+  std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
+  TestNetworkQualityEstimator estimator(variation_params);
 
   base::TimeDelta rtt;
   int32_t kbps;
@@ -582,7 +587,9 @@
 // throughput and RTT percentiles are checked for correctness by doing simple
 // verifications.
 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) {
-  TestNetworkQualityEstimator estimator;
+  std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
+  TestNetworkQualityEstimator estimator(variation_params);
 
   std::vector<NetworkQualityObservationSource> disallowed_observation_sources;
   disallowed_observation_sources.push_back(
@@ -1508,6 +1515,7 @@
       test_external_estimate_provider);
 
   std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
   TestNetworkQualityEstimator estimator(variation_params,
                                         std::move(external_estimate_provider));
   estimator.SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_WIFI,
@@ -1553,6 +1561,7 @@
 TEST(NetworkQualityEstimatorTest, TestThroughputNoRequestOverlap) {
   base::HistogramTester histogram_tester;
   std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
 
   static const struct {
     bool allow_small_localhost_requests;
@@ -2060,7 +2069,11 @@
 TEST(NetworkQualityEstimatorTest, TestRttThroughputObservers) {
   TestRTTObserver rtt_observer;
   TestThroughputObserver throughput_observer;
-  TestNetworkQualityEstimator estimator;
+
+  std::map<std::string, std::string> variation_params;
+  variation_params["throughput_min_requests_in_flight"] = "1";
+  TestNetworkQualityEstimator estimator(variation_params);
+
   estimator.AddRTTObserver(&rtt_observer);
   estimator.AddThroughputObserver(&throughput_observer);
 
@@ -2162,6 +2175,7 @@
 
   std::map<std::string, std::string> variation_params;
   variation_params["persistent_cache_reading_enabled"] = "true";
+  variation_params["throughput_min_requests_in_flight"] = "1";
   TestNetworkQualityEstimator estimator(
       nullptr, variation_params, true, true,
       true /* add_default_platform_observations */,
diff --git a/net/nqe/throughput_analyzer.cc b/net/nqe/throughput_analyzer.cc
index e1d29997..b54e5be3 100644
--- a/net/nqe/throughput_analyzer.cc
+++ b/net/nqe/throughput_analyzer.cc
@@ -26,10 +26,6 @@
 // degrade accuracy held in the memory.
 static const size_t kMaxRequestsSize = 300;
 
-// Tiny transfer sizes may give inaccurate throughput results.
-// Minimum size of the transfer over which the throughput is computed.
-static const int kMinTransferSizeInBits = 32 * 8 * 1000;
-
 }  // namespace
 
 namespace nqe {
@@ -49,7 +45,6 @@
       bits_received_at_window_start_(0),
       disable_throughput_measurements_(false),
       use_localhost_requests_for_tests_(false),
-      use_small_responses_for_tests_(false),
       net_log_(net_log) {
   DCHECK(params_);
   DCHECK(task_runner_);
@@ -203,8 +198,10 @@
 
   // Ignore tiny/short transfers, which will not produce accurate rates. Skip
   // the checks if |use_small_responses_| is true.
-  if (!use_small_responses_for_tests_ && bits_received < kMinTransferSizeInBits)
+  if (!params_->use_small_responses() &&
+      bits_received < params_->GetThroughputMinTransferSizeBits()) {
     return false;
+  }
 
   double downstream_kbps_double =
       (bits_received * 1.0f) / duration.InMillisecondsF();
@@ -243,12 +240,6 @@
   use_localhost_requests_for_tests_ = use_localhost_requests;
 }
 
-void ThroughputAnalyzer::SetUseSmallResponsesForTesting(
-    bool use_small_responses) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  use_small_responses_for_tests_ = use_small_responses;
-}
-
 int64_t ThroughputAnalyzer::GetBitsReceived() const {
   DCHECK(thread_checker_.CalledOnValidThread());
   return NetworkActivityMonitor::GetInstance()->GetBytesReceived() * 8;
diff --git a/net/nqe/throughput_analyzer.h b/net/nqe/throughput_analyzer.h
index b815ac5..74c9849f 100644
--- a/net/nqe/throughput_analyzer.h
+++ b/net/nqe/throughput_analyzer.h
@@ -77,12 +77,6 @@
   // quality estimation.
   void SetUseLocalHostRequestsForTesting(bool use_localhost_requests);
 
-  // |use_smaller_responses_for_tests| should only be true when testing, and
-  // allows the responses smaller than |kMinTransferSizeInBits| or shorter than
-  // |kMinRequestDurationMicroseconds| to be used for network quality
-  // estimation.
-  void SetUseSmallResponsesForTesting(bool use_small_responses);
-
   // Returns true if throughput is currently tracked by a throughput
   // observation window.
   bool IsCurrentlyTrackingThroughput() const;
@@ -171,11 +165,6 @@
   // network quality. Set to true only for tests.
   bool use_localhost_requests_for_tests_;
 
-  // Determines if the responses smaller than |kMinTransferSizeInBits|
-  // or shorter than |kMinTransferSizeInBits| can be used in estimating the
-  // network quality. Set to true only for tests.
-  bool use_small_responses_for_tests_;
-
   base::ThreadChecker thread_checker_;
 
   NetLogWithSource net_log_;
diff --git a/net/nqe/throughput_analyzer_unittest.cc b/net/nqe/throughput_analyzer_unittest.cc
index 44fd45d..8041741d 100644
--- a/net/nqe/throughput_analyzer_unittest.cc
+++ b/net/nqe/throughput_analyzer_unittest.cc
@@ -136,6 +136,53 @@
   }
 }
 
+// Tests that the throughput observation is taken only if there are sufficient
+// number of requests in-flight.
+TEST(ThroughputAnalyzerTest, TestMinRequestsForThroughputSample) {
+  std::map<std::string, std::string> variation_params;
+  NetworkQualityEstimatorParams params(variation_params);
+
+  for (size_t num_requests = 1;
+       num_requests <= params.throughput_min_requests_in_flight() + 1;
+       ++num_requests) {
+    TestThroughputAnalyzer throughput_analyzer(&params);
+    TestDelegate test_delegate;
+    TestURLRequestContext context;
+    throughput_analyzer.AddIPAddressResolution(&context);
+    std::vector<std::unique_ptr<URLRequest>> requests_not_local;
+
+    for (size_t i = 0; i < num_requests; ++i) {
+      std::unique_ptr<URLRequest> request_not_local(context.CreateRequest(
+          GURL("http://example.com/echo.html"), DEFAULT_PRIORITY,
+          &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
+      request_not_local->Start();
+      requests_not_local.push_back(std::move(request_not_local));
+    }
+
+    base::RunLoop().Run();
+
+    EXPECT_EQ(0, throughput_analyzer.throughput_observations_received());
+
+    for (size_t i = 0; i < requests_not_local.size(); ++i) {
+      throughput_analyzer.NotifyStartTransaction(*requests_not_local.at(i));
+    }
+
+    // Increment the bytes received count to emulate the bytes received for
+    // |request_local| and |requests_not_local|.
+    throughput_analyzer.IncrementBitsReceived(100 * 1000 * 8);
+
+    for (size_t i = 0; i < requests_not_local.size(); ++i) {
+      throughput_analyzer.NotifyRequestCompleted(*requests_not_local.at(i));
+    }
+    base::RunLoop().RunUntilIdle();
+
+    int expected_throughput_observations =
+        num_requests >= params.throughput_min_requests_in_flight() ? 1 : 0;
+    EXPECT_EQ(expected_throughput_observations,
+              throughput_analyzer.throughput_observations_received());
+  }
+}
+
 // Tests if the throughput observation is taken correctly when local and network
 // requests overlap.
 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) {
@@ -167,10 +214,15 @@
 
     std::unique_ptr<URLRequest> request_local;
 
-    std::unique_ptr<URLRequest> request_not_local(context.CreateRequest(
-        GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate,
-        TRAFFIC_ANNOTATION_FOR_TESTS));
-    request_not_local->Start();
+    std::vector<std::unique_ptr<URLRequest>> requests_not_local;
+
+    for (size_t i = 0; i < params.throughput_min_requests_in_flight(); ++i) {
+      std::unique_ptr<URLRequest> request_not_local(context.CreateRequest(
+          GURL("http://example.com/echo.html"), DEFAULT_PRIORITY,
+          &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
+      request_not_local->Start();
+      requests_not_local.push_back(std::move(request_not_local));
+    }
 
     if (test.start_local_request) {
       request_local = context.CreateRequest(GURL("http://127.0.0.1/echo.html"),
@@ -190,7 +242,10 @@
     // at all times.
     if (test.start_local_request)
       throughput_analyzer.NotifyStartTransaction(*request_local);
-    throughput_analyzer.NotifyStartTransaction(*request_not_local);
+
+    for (size_t i = 0; i < requests_not_local.size(); ++i) {
+      throughput_analyzer.NotifyStartTransaction(*requests_not_local.at(i));
+    }
 
     if (test.local_request_completes_first) {
       ASSERT_TRUE(test.start_local_request);
@@ -198,10 +253,12 @@
     }
 
     // Increment the bytes received count to emulate the bytes received for
-    // |request_local| and |request_not_local|.
+    // |request_local| and |requests_not_local|.
     throughput_analyzer.IncrementBitsReceived(100 * 1000 * 8);
 
-    throughput_analyzer.NotifyRequestCompleted(*request_not_local);
+    for (size_t i = 0; i < requests_not_local.size(); ++i) {
+      throughput_analyzer.NotifyRequestCompleted(*requests_not_local.at(i));
+    }
     if (test.start_local_request && !test.local_request_completes_first)
       throughput_analyzer.NotifyRequestCompleted(*request_local);
 
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc
index ba5954cf..7f992385 100644
--- a/net/socket/udp_socket_posix.cc
+++ b/net/socket/udp_socket_posix.cc
@@ -736,22 +736,30 @@
                                      int buf_len,
                                      IPEndPoint* address) {
   int bytes_transferred;
-  int flags = 0;
+
+  struct iovec iov = {};
+  iov.iov_base = buf->data();
+  iov.iov_len = buf_len;
+
+  struct msghdr msg = {};
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
 
   SockaddrStorage storage;
+  msg.msg_name = storage.addr;
+  msg.msg_namelen = storage.addr_len;
 
-  bytes_transferred =
-      HANDLE_EINTR(recvfrom(socket_,
-                            buf->data(),
-                            buf_len,
-                            flags,
-                            storage.addr,
-                            &storage.addr_len));
+  bytes_transferred = HANDLE_EINTR(recvmsg(socket_, &msg, 0));
+  storage.addr_len = msg.msg_namelen;
   int result;
   if (bytes_transferred >= 0) {
-    result = bytes_transferred;
-    if (address && !address->FromSockAddr(storage.addr, storage.addr_len))
-      result = ERR_ADDRESS_INVALID;
+    if (msg.msg_flags & MSG_TRUNC) {
+      result = ERR_MSG_TOO_BIG;
+    } else {
+      result = bytes_transferred;
+      if (address && !address->FromSockAddr(storage.addr, storage.addr_len))
+        result = ERR_ADDRESS_INVALID;
+    }
   } else {
     result = MapSystemError(errno);
   }
diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc
index d49d110..652bd78d 100644
--- a/net/socket/udp_socket_unittest.cc
+++ b/net/socket/udp_socket_unittest.cc
@@ -272,16 +272,7 @@
                              &recv_from_address_, recv_callback.callback());
   rv = recv_callback.GetResult(rv);
 
-#if defined(OS_WIN)
-  // On Windows Recv() returns ERR_MSG_TOO_BIG.
-  // TODO(sergeyu): Consider making this behavior consistent on all platforms.
   EXPECT_EQ(rv, ERR_MSG_TOO_BIG);
-#else   // !OS_WIN
-  EXPECT_EQ(rv, kPartialReadSize);
-#endif  // !OS_WIN
-
-  EXPECT_EQ(test_packet.substr(0, kPartialReadSize),
-            std::string(buffer->data(), kPartialReadSize));
 
   // Send a different message again.
   std::string second_packet("Second packet");
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 01524720..c40d7fa 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -15,6 +15,34 @@
 # LayoutNG is enabled, but not when disabled.
 crbug.com/707656 editing/deleting/in-visibly-empty-root.html [ Failure ]
 
+# New passes
+crbug.com/626703 external/wpt/css/css-ui-3/text-overflow-021.html [ Pass ]
+crbug.com/492664 external/wpt/css/css-writing-modes-3/inline-block-alignment-003.xht [ Pass ]
+crbug.com/492664 external/wpt/css/css-writing-modes-3/inline-block-alignment-005.xht [ Pass ]
+crbug.com/492664 external/wpt/css/css-writing-modes-3/inline-table-alignment-003.xht [ Pass ]
+crbug.com/492664 external/wpt/css/css-writing-modes-3/inline-table-alignment-005.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-htb-in-vlr-004.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-htb-in-vlr-016.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-htb-in-vrl-016.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-002.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-005.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-006.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vrl-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vrl-002.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vrl-005.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-htb-in-vrl-006.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-vlr-in-htb-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-vlr-in-htb-002.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-002.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-vlr-in-htb-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-vlr-in-htb-004.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-vrl-in-htb-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes-3/sizing-orthog-vrl-in-htb-004.xht [ Pass ]
+crbug.com/542660 fast/css/absolute-inline-alignment-2.html [ Pass ]
+crbug.com/724697 overflow/overflow-basic-002.html [ Pass ]
+
 # New failures are appended below by the script.
 crbug.com/591099 accessibility/accessibility-hit-test-crash.html [ Failure Pass ]
 crbug.com/591099 accessibility/accessibility-node-memory-management.html [ Failure Pass ]
@@ -10098,7 +10126,6 @@
 crbug.com/591099 fast/scroll-behavior/smooth-scroll/scroll-during-selection.html [ Failure Pass ]
 crbug.com/591099 fast/scroll-behavior/smooth-scroll/track-scroll.html [ Failure Pass ]
 crbug.com/591099 fast/scroll-behavior/subframe-interrupted-scroll.html [ Failure Pass ]
-crbug.com/591099 fast/scrolling/abspos-relayout-overflow-style-change.html [ Failure ]
 crbug.com/591099 fast/scrolling/content-box-smaller-than-scrollbar.html [ Crash Failure ]
 crbug.com/591099 fast/scrolling/custom-scrollbar-style-applied.html [ Failure ]
 crbug.com/591099 fast/scrolling/editor-command-scroll-page-scale.html [ Failure Pass ]
@@ -13262,7 +13289,6 @@
 crbug.com/591099 http/tests/xmlhttprequest/abort-should-destroy-responseText.html [ Failure Pass ]
 crbug.com/591099 http/tests/xmlhttprequest/access-control-response-with-body-sync.html [ Failure Pass ]
 crbug.com/591099 http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-origin-null.html [ Failure Pass ]
-crbug.com/591099 http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html [ Failure Pass ]
 crbug.com/591099 http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html [ Failure Pass Timeout ]
 crbug.com/591099 http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html [ Failure Pass ]
 crbug.com/591099 http/tests/xmlhttprequest/async-xhr-revalidate-after-sync-xhr.html [ Failure Pass ]
@@ -13878,7 +13904,6 @@
 crbug.com/591099 overflow/overflow-basic-003.html [ Failure ]
 crbug.com/591099 overflow/overflow-bug-chrome-ng-001.html [ Failure ]
 crbug.com/591099 overflow/overflow-position-003.html [ Failure ]
-crbug.com/591099 overflow/overflow-position-004.html [ Failure ]
 crbug.com/591099 overflow/overflow-transform-perspective.html [ Failure ]
 crbug.com/591099 paint/background/background-and-shadow.html [ Failure ]
 crbug.com/591099 paint/background/fieldset-legend-background-shadow-border-radius.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index e848fc48..9b05039 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -385,7 +385,7 @@
 Bug(none) compositing/squashing/selection-repaint-with-gaps.html [ Failure ]
 Bug(none) compositing/squashing/squash-above-fixed-1.html [ Failure ]
 Bug(none) compositing/squashing/squash-above-fixed-2.html [ Crash Failure ]
-Bug(none) compositing/squashing/squash-above-fixed-3.html [ Failure ]
+Bug(none) compositing/squashing/squash-above-fixed-3.html [ Crash Failure ]
 Bug(none) compositing/squashing/squash-compositing-hover.html [ Failure ]
 Bug(none) compositing/squashing/squash-onto-distant-relative.html [ Failure ]
 Bug(none) compositing/squashing/squash-onto-nephew.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 48fde40..ec750e9 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -295,8 +295,6 @@
 external/wpt/gyroscope [ WontFix ]
 external/wpt/magnetometer [ WontFix ]
 external/wpt/upgrade-insecure-requests [ WontFix ]
-external/wpt/css/css-conditional-3 [ WontFix ]
-external/wpt/css/css-namespaces-3 [ WontFix ]
 
 # Temporary disabling of most encrypted-media WPT tests while enabling
 # https only. Once the switch is complete (and the WPT tests renamed so they
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 77038d5..0685230 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -168,6 +168,7 @@
 crbug.com/451577 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html [ Slow ]
 crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-border-radius.html [ Slow ]
 crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-image-canvas-svg.html [ Slow ]
+crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-image-svg-resource-url.html [ Slow ]
 
 crbug.com/510337 cssom/cssvalue-comparison.html [ Slow ]
 crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 16ac670f..0c82b100 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -590,7 +590,6 @@
 crbug.com/724701 virtual/layout_ng/overflow/overflow-basic-004.html [ Failure ]
 crbug.com/728378 virtual/layout_ng/overflow/overflow-bug-chrome-ng-001.html [ Failure ]
 crbug.com/728378 virtual/layout_ng/overflow/overflow-position-003.html [ Failure ]
-crbug.com/728378 virtual/layout_ng/overflow/overflow-position-004.html [ Failure ]
 
 # ====== LayoutNG-only failures until here ======
 
diff --git a/third_party/WebKit/LayoutTests/compositing/layer-creation/overlap-animation-container-expected.txt b/third_party/WebKit/LayoutTests/compositing/layer-creation/overlap-animation-container-expected.txt
index 1bc45ac..b76a656 100644
--- a/third_party/WebKit/LayoutTests/compositing/layer-creation/overlap-animation-container-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/layer-creation/overlap-animation-container-expected.txt
@@ -106,6 +106,11 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "position": [58, 230],
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (relative positioned) DIV class='box gray force-layer'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -113,26 +118,9 @@
       "transform": 4
     },
     {
-      "name": "LayoutBlockFlow (relative positioned) DIV id='first-green-box' class='box green rotate-45deg'",
-      "bounds": [102, 102],
-      "backgroundColor": "#008000",
-      "transform": 6
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "position": [58, 230],
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='box green rotate-45deg'",
-      "bounds": [102, 102],
-      "backgroundColor": "#008000",
-      "transform": 8
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='box green')",
-      "position": [18, 570],
-      "bounds": [152, 222]
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='first-green-box' class='box green rotate-45deg')",
+      "position": [18, 328],
+      "bounds": [174, 464]
     }
   ],
   "transforms": [
@@ -162,7 +150,8 @@
         [...],
         [...],
         [...]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 4,
@@ -172,48 +161,7 @@
         [...],
         [...],
         [...]
-      ]
-    },
-    {
-      "id": 5,
-      "transform": [
-        [...],
-        [...],
-        [...],
-        [...]
-      ]
-    },
-    {
-      "id": 6,
-      "parent": 5,
-      "transform": [
-        [...],
-        [...],
-        [...],
-        [...]
       ],
-      "origin": [51, 51]
-    },
-    {
-      "id": 7,
-      "transform": [
-        [...],
-        [...],
-        [...],
-        [...]
-      ],
-      "flattenInheritedTransform": false
-    },
-    {
-      "id": 8,
-      "parent": 7,
-      "transform": [
-        [...],
-        [...],
-        [...],
-        [...]
-      ],
-      "origin": [51, 51],
       "flattenInheritedTransform": false
     }
   ]
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-with-scale-transform.html b/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-with-scale-transform.html
index 943daa39..c8e69c3 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-with-scale-transform.html
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-with-scale-transform.html
@@ -18,12 +18,9 @@
     if (window.internals) {
         var layers = JSON.parse(internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_DEBUG_INFO))["layers"];
 
-        // The scale-transform layer can't be squashed
-        assert_true(layers[3].compositingReasons[1] == "Layer was separately composited because it could not be squashed.");
-        assert_true(layers[3].squashingDisallowedReasons[0] == "Cannot squash layers with transforms that are not identity or translation.");
-
-        // ...but the translate-transform one can.
-        assert_true(layers[4].compositingReasons[0] == "Secondary layer, home for a group of squashable content");
+        // Both transformed layers squash together after the will-change layer.
+        assert_true(layers[2].compositingReasons[0] == "Has a will-change compositing hint");
+        assert_true(layers[3].compositingReasons[0] == "Secondary layer, home for a group of squashable content");
     }
 };
 </script>
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-expected.txt
index f5bd6d0..dd1faf9 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-expected.txt
@@ -7,6 +7,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -14,20 +18,9 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#00FF00",
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [-1, -1],
+      "bounds": [281, 281]
     }
   ],
   "transforms": [
@@ -38,29 +31,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.707106781186548, 0.707106781186548, 0, 0],
-        [-0.707106781186548, 0.707106781186548, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-child-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-child-expected.txt
index ab197e05..84e38c2 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-child-expected.txt
@@ -8,6 +8,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -15,20 +19,9 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#00FF00",
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [-1, -1],
+      "bounds": [281, 281]
     }
   ],
   "transforms": [
@@ -39,29 +32,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.707106781186548, 0.707106781186548, 0, 0],
-        [-0.707106781186548, 0.707106781186548, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ]
 }
@@ -75,6 +47,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -82,27 +58,16 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#008000",
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [-1, -1],
+      "bounds": [281, 281],
       "paintInvalidations": [
         {
           "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
-          "rect": [0, 0, 100, 100],
+          "rect": [0, 0, 142, 142],
           "reason": "style change"
         }
-      ],
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      ]
     }
   ],
   "transforms": [
@@ -113,29 +78,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.707106781186548, 0.707106781186548, 0, 0],
-        [-0.707106781186548, 0.707106781186548, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ],
   "objectPaintInvalidations": [
@@ -155,6 +99,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -162,32 +110,21 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#008000",
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [-1, -1],
+      "bounds": [281, 281],
       "paintInvalidations": [
         {
           "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
-          "rect": [0, 0, 100, 100],
+          "rect": [0, 0, 142, 142],
           "reason": "style change"
         },
         {
           "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
-          "rect": [20, 25, 50, 50],
+          "rect": [32, 32, 71, 71],
           "reason": "style change"
         }
-      ],
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      ]
     }
   ],
   "transforms": [
@@ -198,29 +135,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.707106781186548, 0.707106781186548, 0, 0],
-        [-0.707106781186548, 0.707106781186548, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ],
   "objectPaintInvalidations": [
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
index befb988..9c6d5644 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
@@ -8,6 +8,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -15,20 +19,9 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#00FF00",
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [4, 4],
+      "bounds": [276, 276]
     }
   ],
   "transforms": [
@@ -39,29 +32,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.927183854566787, 0.374606593415912, 0, 0],
-        [-0.374606593415912, 0.927183854566787, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ]
 }
@@ -75,6 +47,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -82,27 +58,16 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#008000",
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [4, 4],
+      "bounds": [276, 276],
       "paintInvalidations": [
         {
           "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
-          "rect": [0, 0, 100, 100],
+          "rect": [0, 0, 132, 132],
           "reason": "style change"
         }
-      ],
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      ]
     }
   ],
   "transforms": [
@@ -113,29 +78,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.927183854566787, 0.374606593415912, 0, 0],
-        [-0.374606593415912, 0.927183854566787, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ],
   "objectPaintInvalidations": [
@@ -155,6 +99,10 @@
       "backgroundColor": "#FFFFFF"
     },
     {
+      "name": "Squashing Containment Layer",
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
       "bounds": [100, 100],
       "contentsOpaque": true,
@@ -162,32 +110,21 @@
       "transform": 1
     },
     {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#008000",
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
+      "position": [4, 4],
+      "bounds": [276, 276],
       "paintInvalidations": [
         {
           "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
-          "rect": [0, 0, 100, 100],
+          "rect": [0, 0, 132, 132],
           "reason": "style change"
         },
         {
           "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
-          "rect": [12, 17, 66, 66],
+          "rect": [19, 21, 85, 86],
           "reason": "style change"
         }
-      ],
-      "transform": 3
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
-      "position": [180, 180],
-      "bounds": [100, 100]
+      ]
     }
   ],
   "transforms": [
@@ -198,29 +135,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [100, 100, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [20, 20, 0, 1]
       ],
       "flattenInheritedTransform": false
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [0.927183854566787, 0.374606593415912, 0, 0],
-        [-0.374606593415912, 0.927183854566787, 0, 0],
-        [0, 0, 1, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false
     }
   ],
   "objectPaintInvalidations": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-sandboxed-iframe-allow.htm b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-sandboxed-iframe-allow.htm
new file mode 100644
index 0000000..21413f3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-sandboxed-iframe-allow.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Tests that sandboxed iframe has CORS XHR access to a server that accepts all domains</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/get-host-info.sub.js"></script>
+  </head>
+  <body>
+    <script type="text/javascript">
+async_test((test) => {
+  window.addEventListener("message", test.step_func((evt) => {
+    if (evt.data === "ready") {
+      document.getElementById("frame").contentWindow.postMessage(
+          get_host_info().HTTP_ORIGIN +
+          "/XMLHttpRequest/resources/pass.txt?pipe=" +
+          "header(Cache-Control,no-store)|" +
+          "header(Content-Type,text/plain)|" +
+          "header(Access-Control-Allow-Credentials,true)|" +
+          "header(Access-Control-Allow-External,true)|" +
+          "header(Access-Control-Allow-Origin,*)", "*");
+    } else {
+      assert_equals(evt.data.trim(), "PASS");
+      test.done();
+    }
+  }), false);
+});
+    </script>
+    <iframe id="frame" sandbox="allow-scripts" src="/XMLHttpRequest/resources/access-control-sandboxed-iframe.html">
+    </iframe>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/access-control-sandboxed-iframe.html b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/access-control-sandboxed-iframe.html
new file mode 100644
index 0000000..7e47275
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/access-control-sandboxed-iframe.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <body>
+  <script type="text/javascript">
+window.addEventListener("message", (evt) => {
+  const url = evt.data;
+  const xhr = new XMLHttpRequest;
+
+  xhr.open("GET", url, false);
+
+  try {
+    xhr.send();
+  } catch(e) {
+    parent.postMessage("Exception thrown. Sandboxed iframe XHR access was denied in 'send'.", "*");
+    return;
+  }
+
+  parent.postMessage(xhr.responseText, "*");
+}, false);
+
+parent.postMessage("ready", "*");
+  </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional-3/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional-3/OWNERS
new file mode 100644
index 0000000..02d41d82
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional-3/OWNERS
@@ -0,0 +1,8 @@
+# TEAM: style-dev@chromium.org
+# COMPONENT: Blink>CSS
+bugsnash@chromium.org
+ericwilligers@chromium.org
+meade@chromium.org
+nainar@chromium.org
+rjwright@chromium.org
+shend@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-namespaces-3/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/css-namespaces-3/OWNERS
new file mode 100644
index 0000000..02d41d82
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-namespaces-3/OWNERS
@@ -0,0 +1,8 @@
+# TEAM: style-dev@chromium.org
+# COMPONENT: Blink>CSS
+bugsnash@chromium.org
+ericwilligers@chromium.org
+meade@chromium.org
+nainar@chromium.org
+rjwright@chromium.org
+shend@chromium.org
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/stable/getComputedStyle-text-decoration.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/stable/getComputedStyle-text-decoration.html
index 741f0b9..22638a72 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/stable/getComputedStyle-text-decoration.html
+++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/stable/getComputedStyle-text-decoration.html
@@ -5,9 +5,5 @@
 description("Test that computed style for text-decoration is correctly represented.");
 
 var decoration = getComputedStyle(target).textDecoration;
-
-if (window.internals && internals.runtimeFlags.css3TextDecorationsEnabled)
-    shouldBe("decoration", "'underline solid rgb(0, 0, 0)'");
-else
-    shouldBe("decoration", "'underline'");
+shouldBe("decoration", "'underline solid rgb(0, 0, 0)'");
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/change-column-count-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/change-column-count-crash.html
new file mode 100644
index 0000000..6f95fb8e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/change-column-count-crash.html
@@ -0,0 +1,38 @@
+<!doctype HTML>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<style>
+#target {
+    columns: 1px;
+    font: 14px/0 Ahem
+</style>
+<div id="target"></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<script>
+test(function() {
+  target.innerText += "test";
+}, "Should not crash");
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt
deleted file mode 100644
index 5b96c8d..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-CONSOLE WARNING: line 10: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-This test verifies that sandboxed iframe has XmlHttpRequest access to the server that accepts all domains. It will print "PASS" on success.
-
-
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-PASS: Sandboxed iframe XHR access allowed.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html
deleted file mode 100644
index bd03188..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
-<script>
-
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.dumpChildFramesAsText();
-}
-
-</script>
-<body>
-    <p>This test verifies that sandboxed iframe has XmlHttpRequest access
-    to the server that accepts all domains. It will print &quot;PASS&quot; on success.</p>
-    
-    <iframe sandbox="allow-scripts" src="http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html" style="width: 500px;">
-    </iframe> 
-    
-</body> 
-</html> 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html
deleted file mode 100644
index 383e7cbf4..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html> 
-<body> 
-<pre id='console'></pre> 
-<script type="text/javascript"> 
-
-document.getElementById('console').innerHTML = (function() { 
-    var xhr = new XMLHttpRequest; 
- 
-    try { 
-        xhr.open("GET", "http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi", false); 
-    } catch(e) { 
-        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'open'. [" + e.message + "]."; 
-    } 
- 
-    try { 
-        xhr.send(); 
-    } catch(e) { 
-        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'send'. [" + e.message + "]."; 
-    } 
- 
-    return xhr.responseText; 
-})(); 
-</script> 
-</body> 
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi
deleted file mode 100755
index db7178c..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/perl -wT
-use strict;
-
-print "Content-Type: text/plain\n";
-print "Access-Control-Allow-Credentials: true\n";
-print "Access-Control-Allow-External: true\n";
-print "Access-Control-Allow-Origin: *\n\n";
-
-print "PASS: Sandboxed iframe XHR access allowed.\n";
diff --git a/third_party/WebKit/PRESUBMIT_test.py b/third_party/WebKit/PRESUBMIT_test.py
index 6a87437b..ffe89f2 100644
--- a/third_party/WebKit/PRESUBMIT_test.py
+++ b/third_party/WebKit/PRESUBMIT_test.py
@@ -1,18 +1,29 @@
-# disable camel case warning
+# 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.
+#
+# Note: running this test requires installing the package python-mock.
 # pylint: disable=C0103
+# pylint: disable=F0401
 import PRESUBMIT
 
 import mock
+import os.path
 import subprocess
+import sys
 import unittest
 
-from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi, MockAffectedFile  # pylint: disable=F0401
+sys.path.append(
+    os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))
+
+from PRESUBMIT_test_mocks import MockInputApi
+from PRESUBMIT_test_mocks import MockOutputApi
+from PRESUBMIT_test_mocks import MockAffectedFile
 
 
 class Capture(object):
-    """
-    Class to capture a call argument that can be tested later on.
-    """
+    """Class to capture a call argument that can be tested later on."""
+
     def __init__(self):
         self.value = None
 
@@ -32,10 +43,10 @@
         diff_file_webkit_h = ['some diff']
         diff_file_chromium_h = ['another diff']
         mock_input_api = MockInputApi()
-        mock_input_api.files = [MockAffectedFile('FileWebkit.h',
-                                                 diff_file_webkit_h),
-                                MockAffectedFile('file_chromium.h',
-                                                 diff_file_chromium_h)]
+        mock_input_api.files = [
+            MockAffectedFile('FileWebkit.h', diff_file_webkit_h),
+            MockAffectedFile('file_chromium.h', diff_file_chromium_h)
+        ]
         # Access to a protected member _CheckStyle
         # pylint: disable=W0212
         PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi())
@@ -54,10 +65,10 @@
         diff_file_chromium1_h = ['some diff']
         diff_file_chromium2_h = ['another diff']
         mock_input_api = MockInputApi()
-        mock_input_api.files = [MockAffectedFile('first_file_chromium.h',
-                                                 diff_file_chromium1_h),
-                                MockAffectedFile('second_file_chromium.h',
-                                                 diff_file_chromium2_h)]
+        mock_input_api.files = [
+            MockAffectedFile('first_file_chromium.h', diff_file_chromium1_h),
+            MockAffectedFile('second_file_chromium.h', diff_file_chromium2_h)
+        ]
         # Access to a protected member _CheckStyle
         # pylint: disable=W0212
         PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi())
diff --git a/third_party/WebKit/Source/build/scripts/templates/StylePropertyShorthand.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/StylePropertyShorthand.cpp.tmpl
index 8408e2b..d53e07794 100644
--- a/third_party/WebKit/Source/build/scripts/templates/StylePropertyShorthand.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/StylePropertyShorthand.cpp.tmpl
@@ -59,9 +59,6 @@
   // FIXME: We shouldn't switch between shorthand/not shorthand based on a runtime flag
   static constexpr StylePropertyShorthand emptyShorthand;
 
-  if (propertyID == CSSPropertyTextDecoration &&
-      !RuntimeEnabledFeatures::CSS3TextDecorationsEnabled())
-    return emptyShorthand;
   if (propertyID == CSSPropertyOffset &&
       !RuntimeEnabledFeatures::CSSOffsetPositionAnchorEnabled())
     return offsetShorthandWithoutPositionAnchor();
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index ec516cd..6a55295 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -2653,7 +2653,6 @@
       api_methods: ["ParseSingleValue"],
       custom_all: true,
       interpolable: true,
-      runtime_flag: "CSS3TextDecorations",
       field_template: "external",
       type_name: "StyleColor",
       include_paths: ["core/css/StyleColor.h"],
@@ -2666,7 +2665,6 @@
       api_methods: ["ParseSingleValue"],
       converter: "ConvertFlags<TextDecoration>",
       name_for_methods: "TextDecoration",
-      runtime_flag: "CSS3TextDecorations",
       type_name: "TextDecoration",
       field_template: "multi_keyword",
       default_value: "none",
@@ -2679,7 +2677,6 @@
       api_methods: ["ParseSingleValue"],
       converter: "ConvertFlags<TextDecorationSkip>",
       inherited: true,
-      runtime_flag: "CSS3TextDecorations",
       field_template: "primitive",
       type_name: "TextDecorationSkip",
       default_value: "TextDecorationSkip::kObjects",
@@ -2689,7 +2686,6 @@
     {
       name: "text-decoration-style",
       api_class: true,
-      runtime_flag: "CSS3TextDecorations",
       field_template: "keyword",
       keywords: ["solid", "double", "dotted", "dashed", "wavy"],
       field_group: "*",
@@ -2768,7 +2764,6 @@
       api_class: true,
       api_methods: ["ParseSingleValue"],
       inherited: true,
-      runtime_flag: "CSS3TextDecorations",
       field_template: "keyword",
       type_name: "TextUnderlinePosition",
       default_value: "auto",
diff --git a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
index a4b4dea..5b3bf0e4 100644
--- a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
@@ -89,7 +89,7 @@
   return !CSSPropertyParserHelpers::IsCSSWideKeyword(ident);
 }
 
-CSSSyntaxDescriptor::CSSSyntaxDescriptor(String input) {
+CSSSyntaxDescriptor::CSSSyntaxDescriptor(const String& input) {
   size_t offset = 0;
   ConsumeWhitespace(input, offset);
 
diff --git a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h
index 5afa2821..65a6dd3 100644
--- a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h
+++ b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h
@@ -46,7 +46,7 @@
 
 class CORE_EXPORT CSSSyntaxDescriptor {
  public:
-  CSSSyntaxDescriptor(String syntax);
+  explicit CSSSyntaxDescriptor(const String& syntax);
 
   const CSSValue* Parse(CSSParserTokenRange,
                         const CSSParserContext*,
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index f4afa52..073a823 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2967,11 +2967,9 @@
     case CSSPropertyTextAlignLast:
       return CSSIdentifierValue::Create(style.TextAlignLast());
     case CSSPropertyTextDecoration:
-      if (RuntimeEnabledFeatures::CSS3TextDecorationsEnabled())
-        return ValuesForShorthandProperty(textDecorationShorthand(), style,
-                                          layout_object, styled_node,
-                                          allow_visited_style);
-    // Fall through.
+      return ValuesForShorthandProperty(textDecorationShorthand(), style,
+                                        layout_object, styled_node,
+                                        allow_visited_style);
     case CSSPropertyTextDecorationLine:
       return RenderTextDecorationFlagsToCSSValue(style.GetTextDecoration());
     case CSSPropertyTextDecorationSkip:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
index 32a46cd..4cf82ff4 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
@@ -681,7 +681,6 @@
     case CSSPropertyTextCombineUpright:
       return value_id == CSSValueNone || value_id == CSSValueAll;
     case CSSPropertyTextDecorationStyle:
-      DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
       return value_id == CSSValueSolid || value_id == CSSValueDouble ||
              value_id == CSSValueDotted || value_id == CSSValueDashed ||
              value_id == CSSValueWavy;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIBaseCustom.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIBaseCustom.cpp
index 1216c9db..3653e7d 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIBaseCustom.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIBaseCustom.cpp
@@ -33,14 +33,7 @@
     const CSSParserLocalContext& local_context) const {
   // This is the legacy ParseSingleValue code.
   // TODO(bugsnash): Move all of this to individual CSSPropertyAPI subclasses.
-  switch (property) {
-    case CSSPropertyTextDecoration:
-      DCHECK(!RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
-      return CSSPropertyTextDecorationLineUtils::ConsumeTextDecorationLine(
-          range);
-    default:
-      return nullptr;
-  }
+  return nullptr;
 }
 
 bool CSSPropertyAPI::ParseShorthand(
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationColor.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationColor.cpp
index 0bdda7bc..c6bc17e7 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationColor.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationColor.cpp
@@ -15,7 +15,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
   return CSSPropertyParserHelpers::ConsumeColor(range, context.Mode());
 }
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationSkip.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationSkip.cpp
index 94b5ba68..89d42e6 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationSkip.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextDecorationSkip.cpp
@@ -16,7 +16,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
   CSSValueList* list = CSSValueList::CreateSpaceSeparated();
   while (true) {
     CSSIdentifierValue* ident =
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp
index fdd73030..dd180a05 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp
@@ -16,10 +16,6 @@
     const CSSParserLocalContext&) const {
   // auto | [ under || [ left | right ] ], but we only support auto | under
   // for now
-  DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
-  // auto | [ under || [ left | right ] ], but we only support auto | under
-  // for now
-  DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
   return CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto, CSSValueUnder>(
       range);
 }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp
index 578de9e..d42a0c4 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp
@@ -16,7 +16,6 @@
     const CSSParserContext& context,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
   return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs(
       textDecorationShorthand(), important, context, range, properties);
 }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index e70d1d41..84107ee 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -1297,7 +1297,6 @@
     case CSSPropertyTextDecorationStyle:
     case CSSPropertyTextDecorationColor:
     case CSSPropertyTextDecorationSkip:
-      DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
       return true;
     case CSSPropertyFontVariationSettings:
       DCHECK(RuntimeEnabledFeatures::CSSVariableFontsEnabled());
@@ -1408,14 +1407,10 @@
     case CSSPropertyFontVariationSettings:
       DCHECK(RuntimeEnabledFeatures::CSSVariableFontsEnabled());
       return true;
-    case CSSPropertyTextDecoration:
-      DCHECK(!RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
-      return true;
     case CSSPropertyTextDecorationColor:
     case CSSPropertyTextDecorationLine:
     case CSSPropertyTextDecorationStyle:
     case CSSPropertyTextDecorationSkip:
-      DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
       return true;
 
     // text-shadow added in text decoration spec:
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
index 91f9b8c6..b770246 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyle.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -68,14 +68,6 @@
 
 using namespace cssvalue;
 
-static const CSSPropertyID& TextDecorationPropertyForEditing() {
-  static const CSSPropertyID kProperty =
-      RuntimeEnabledFeatures::CSS3TextDecorationsEnabled()
-          ? CSSPropertyTextDecorationLine
-          : CSSPropertyTextDecoration;
-  return kProperty;
-}
-
 // Editing style properties must be preserved during editing operation.
 // e.g. when a user inserts a new paragraph, all properties listed here must be
 // copied to the new paragraph.
@@ -106,8 +98,7 @@
     CSSProperty::FilterEnabledCSSPropertiesIntoVector(
         kStaticEditingProperties, WTF_ARRAY_LENGTH(kStaticEditingProperties),
         properties);
-    if (RuntimeEnabledFeatures::CSS3TextDecorationsEnabled())
-      properties.erase(properties.Find(CSSPropertyTextDecoration));
+    properties.erase(properties.Find(CSSPropertyTextDecoration));
   }
   return properties;
 }
@@ -257,7 +248,7 @@
 HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(
     CSSValueID primitive_value,
     const HTMLQualifiedName& tag_name)
-    : HTMLElementEquivalent(TextDecorationPropertyForEditing(),
+    : HTMLElementEquivalent(CSSPropertyTextDecorationLine,
                             primitive_value,
                             tag_name)
 // m_propertyID is used in HTMLElementEquivalent::addToStyle
@@ -266,7 +257,7 @@
 bool HTMLTextDecorationEquivalent::PropertyExistsInStyle(
     const StylePropertySet* style) const {
   return style->GetPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) ||
-         style->GetPropertyCSSValue(TextDecorationPropertyForEditing());
+         style->GetPropertyCSSValue(CSSPropertyTextDecorationLine);
 }
 
 bool HTMLTextDecorationEquivalent::ValueIsPresentInStyle(
@@ -275,8 +266,7 @@
   const CSSValue* style_value =
       style->GetPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
   if (!style_value)
-    style_value =
-        style->GetPropertyCSSValue(TextDecorationPropertyForEditing());
+    style_value = style->GetPropertyCSSValue(CSSPropertyTextDecorationLine);
   return Matches(element) && style_value && style_value->IsValueList() &&
          ToCSSValueList(style_value)->HasValue(*identifier_value_);
 }
@@ -739,13 +729,13 @@
   if (!text_decorations_in_effect)
     return;
 
-  if (text_decorations_in_effect->IsValueList())
-    mutable_style_->SetProperty(TextDecorationPropertyForEditing(),
-                                text_decorations_in_effect->CssText(),
-                                mutable_style_->PropertyIsImportant(
-                                    TextDecorationPropertyForEditing()));
-  else
-    mutable_style_->RemoveProperty(TextDecorationPropertyForEditing());
+  if (text_decorations_in_effect->IsValueList()) {
+    mutable_style_->SetProperty(
+        CSSPropertyTextDecorationLine, text_decorations_in_effect->CssText(),
+        mutable_style_->PropertyIsImportant(CSSPropertyTextDecorationLine));
+  } else {
+    mutable_style_->RemoveProperty(CSSPropertyTextDecorationLine);
+  }
   mutable_style_->RemoveProperty(CSSPropertyWebkitTextDecorationsInEffect);
 }
 
@@ -860,20 +850,19 @@
       continue;
 
     if (property_id == CSSPropertyWebkitTextDecorationsInEffect &&
-        inline_style->GetPropertyCSSValue(TextDecorationPropertyForEditing())) {
+        inline_style->GetPropertyCSSValue(CSSPropertyTextDecorationLine)) {
       if (!conflicting_properties)
         return true;
       conflicting_properties->push_back(CSSPropertyTextDecoration);
-      // Because text-decoration expands to text-decoration-line when CSS3
-      // Text Decoration is enabled, we also state it as conflicting.
-      if (RuntimeEnabledFeatures::CSS3TextDecorationsEnabled())
-        conflicting_properties->push_back(CSSPropertyTextDecorationLine);
-      if (extracted_style)
+      // Because text-decoration expands to text-decoration-line,
+      // we also state it as conflicting.
+      conflicting_properties->push_back(CSSPropertyTextDecorationLine);
+      if (extracted_style) {
         extracted_style->SetProperty(
-            TextDecorationPropertyForEditing(),
-            inline_style->GetPropertyValue(TextDecorationPropertyForEditing()),
-            inline_style->PropertyIsImportant(
-                TextDecorationPropertyForEditing()));
+            CSSPropertyTextDecorationLine,
+            inline_style->GetPropertyValue(CSSPropertyTextDecorationLine),
+            inline_style->PropertyIsImportant(CSSPropertyTextDecorationLine));
+      }
       continue;
     }
 
@@ -1284,7 +1273,7 @@
     const CSSValue* value = mutable_style_->GetPropertyCSSValue(property.Id());
 
     // text decorations never override values
-    if ((property.Id() == TextDecorationPropertyForEditing() ||
+    if ((property.Id() == CSSPropertyTextDecorationLine ||
          property.Id() == CSSPropertyWebkitTextDecorationsInEffect) &&
         property.Value().IsValueList() && value) {
       if (value->IsValueList()) {
@@ -1495,11 +1484,11 @@
   const CSSValue* text_decorations_in_effect =
       style->GetPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
   const CSSValue* text_decoration =
-      style->GetPropertyCSSValue(TextDecorationPropertyForEditing());
+      style->GetPropertyCSSValue(CSSPropertyTextDecorationLine);
   // "LayoutTests/editing/execCommand/insert-list-and-strikethrough.html" makes
   // both |textDecorationsInEffect| and |textDecoration| non-null.
   if (text_decorations_in_effect) {
-    style->SetProperty(TextDecorationPropertyForEditing(),
+    style->SetProperty(CSSPropertyTextDecorationLine,
                        text_decorations_in_effect->CssText());
     style->RemoveProperty(CSSPropertyWebkitTextDecorationsInEffect);
     text_decoration = text_decorations_in_effect;
@@ -1508,7 +1497,7 @@
   // If text-decoration is set to "none", remove the property because we don't
   // want to add redundant "text-decoration: none".
   if (text_decoration && !text_decoration->IsValueList())
-    style->RemoveProperty(TextDecorationPropertyForEditing());
+    style->RemoveProperty(CSSPropertyTextDecorationLine);
 }
 
 StyleChange::StyleChange(EditingStyle* style, const Position& position)
@@ -1603,7 +1592,7 @@
   // Furthermore, text-decoration: none has been trimmed so that text-decoration
   // property is always a CSSValueList.
   const CSSValue* text_decoration =
-      style->GetPropertyCSSValue(TextDecorationPropertyForEditing());
+      style->GetPropertyCSSValue(CSSPropertyTextDecorationLine);
   if (text_decoration && text_decoration->IsValueList()) {
     DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline,
                         (CSSIdentifierValue::Create(CSSValueUnderline)));
@@ -1617,7 +1606,7 @@
 
     // If trimTextDecorations, delete underline and line-through
     SetTextDecorationProperty(style, new_text_decoration,
-                              TextDecorationPropertyForEditing());
+                              CSSPropertyTextDecorationLine);
   }
 
   int vertical_align = GetIdentifierValue(style, CSSPropertyVerticalAlign);
@@ -1718,7 +1707,7 @@
   const CSSValue* base_text_decorations_in_effect =
       base_style->GetPropertyCSSValueInternal(
           CSSPropertyWebkitTextDecorationsInEffect);
-  DiffTextDecorations(result, TextDecorationPropertyForEditing(),
+  DiffTextDecorations(result, CSSPropertyTextDecorationLine,
                       base_text_decorations_in_effect);
   DiffTextDecorations(result, CSSPropertyWebkitTextDecorationsInEffect,
                       base_text_decorations_in_effect);
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc
index 43e3d04d..2b477d7 100644
--- a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc
@@ -32,4 +32,34 @@
   return position;
 }
 
+LayoutUnit NGStaticPosition::LeftInset(LayoutUnit container_size,
+                                       LayoutUnit width,
+                                       LayoutUnit margin_left,
+                                       LayoutUnit margin_right) const {
+  if (HasLeft())
+    return offset.left;
+  else
+    return offset.left - width - margin_left - margin_right;
+}
+
+LayoutUnit NGStaticPosition::RightInset(LayoutUnit container_size,
+                                        LayoutUnit width,
+                                        LayoutUnit margin_left,
+                                        LayoutUnit margin_right) const {
+  if (HasLeft())
+    return container_size - offset.left - width - margin_left - margin_right;
+  else
+    return container_size - offset.left;
+}
+
+LayoutUnit NGStaticPosition::TopInset(LayoutUnit container_size,
+                                      LayoutUnit height,
+                                      LayoutUnit margin_top,
+                                      LayoutUnit margin_bottom) const {
+  if (HasTop())
+    return offset.top;
+  else
+    return offset.top - height - margin_bottom - margin_top;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h
index 6e39b08..cc130640 100644
--- a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h
@@ -24,48 +24,27 @@
   static NGStaticPosition Create(NGWritingMode,
                                  TextDirection,
                                  NGPhysicalOffset);
-  // Left/Right/TopPosition functions map static position to
+
+  // Left/Right/TopPosition functions map static position to inset of
   // left/right/top edge wrt container space.
   // The function arguments are required to solve the equation:
   // contaner_size = left + margin_left + width + margin_right + right
-  LayoutUnit LeftPosition(LayoutUnit container_size,
-                          LayoutUnit width,
-                          LayoutUnit margin_left,
-                          LayoutUnit margin_right) const {
-    return GenericPosition(HasLeft(), offset.left, container_size, width,
-                           margin_left, margin_right);
-  }
-  LayoutUnit RightPosition(LayoutUnit container_size,
-                           LayoutUnit width,
-                           LayoutUnit margin_left,
-                           LayoutUnit margin_right) const {
-    return GenericPosition(!HasLeft(), offset.left, container_size, width,
-                           margin_left, margin_right);
-  }
-  LayoutUnit TopPosition(LayoutUnit container_size,
-                         LayoutUnit height,
-                         LayoutUnit margin_top,
-                         LayoutUnit margin_bottom) const {
-    return GenericPosition(HasTop(), offset.top, container_size, height,
-                           margin_top, margin_bottom);
-  }
+  LayoutUnit LeftInset(LayoutUnit container_size,
+                       LayoutUnit width,
+                       LayoutUnit margin_left,
+                       LayoutUnit margin_right) const;
+  LayoutUnit RightInset(LayoutUnit container_size,
+                        LayoutUnit width,
+                        LayoutUnit margin_left,
+                        LayoutUnit margin_right) const;
+  LayoutUnit TopInset(LayoutUnit container_size,
+                      LayoutUnit height,
+                      LayoutUnit margin_top,
+                      LayoutUnit margin_bottom) const;
 
  private:
   bool HasTop() const { return type == kTopLeft || type == kTopRight; }
   bool HasLeft() const { return type == kTopLeft || type == kBottomLeft; }
-  LayoutUnit GenericPosition(bool position_matches,
-                             LayoutUnit position,
-                             LayoutUnit container_size,
-                             LayoutUnit length,
-                             LayoutUnit margin_start,
-                             LayoutUnit margin_end) const {
-    DCHECK_GE(container_size, LayoutUnit());
-    DCHECK_GE(length, LayoutUnit());
-    if (position_matches)
-      return position;
-    else
-      return container_size - position - length - margin_start - margin_end;
-  }
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
index 2ff53b3..f4ffc8a6 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
@@ -114,11 +114,11 @@
     DCHECK(child_minmax.has_value());
     width = child_minmax->ShrinkToFit(container_size.width) + border_padding;
     if (space.Direction() == TextDirection::kLtr) {
-      left = static_position.LeftPosition(container_size.width, *width,
-                                          *margin_left, *margin_right);
+      left = static_position.LeftInset(container_size.width, *width,
+                                       *margin_left, *margin_right);
     } else {
-      right = static_position.RightPosition(container_size.width, *width,
-                                            *margin_left, *margin_right);
+      right = static_position.RightInset(container_size.width, *width,
+                                         *margin_left, *margin_right);
     }
   } else if (left && right && width) {
     // Standard: "If left, right, and width are not auto:"
@@ -172,11 +172,11 @@
     // Rule 2.
     DCHECK(width.has_value());
     if (space.Direction() == TextDirection::kLtr)
-      left = static_position.LeftPosition(container_size.width, *width,
-                                          *margin_left, *margin_right);
+      left = static_position.LeftInset(container_size.width, *width,
+                                       *margin_left, *margin_right);
     else
-      right = static_position.RightPosition(container_size.width, *width,
-                                            *margin_left, *margin_right);
+      right = static_position.RightInset(container_size.width, *width,
+                                         *margin_left, *margin_right);
   } else if (!width && !right) {
     // Rule 3.
     DCHECK(child_minmax.has_value());
@@ -269,8 +269,8 @@
       margin_bottom = LayoutUnit();
     DCHECK(child_minmax.has_value());
     height = child_minmax->ShrinkToFit(container_size.height) + border_padding;
-    top = static_position.TopPosition(container_size.height, *height,
-                                      *margin_top, *margin_bottom);
+    top = static_position.TopInset(container_size.height, *height, *margin_top,
+                                   *margin_bottom);
   } else if (top && bottom && height) {
     // Standard: "If top, bottom, and height are not auto:"
     // Compute margins.
@@ -311,8 +311,8 @@
   } else if (!top && !bottom) {
     // Rule 2.
     DCHECK(height.has_value());
-    top = static_position.TopPosition(container_size.height, *height,
-                                      *margin_top, *margin_bottom);
+    top = static_position.TopInset(container_size.height, *height, *margin_top,
+                                   *margin_bottom);
   } else if (!height && !bottom) {
     // Rule 3.
     DCHECK(child_minmax.has_value());
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
index d3b2a03..db4ea6b7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
@@ -158,7 +158,7 @@
                                                 static_right_position,
                                                 estimated_inline, WTF::nullopt);
   EXPECT_EQ(minmax_60.min_size + border_padding, p.size.width);
-  EXPECT_EQ(LayoutUnit(0), p.inset.right);
+  EXPECT_EQ(container_size_.inline_size, p.inset.right);
 
   // All auto + RTL.
   p = ComputePartialAbsoluteWithChildInlineSize(
@@ -346,7 +346,7 @@
   ComputeFullAbsoluteWithChildBlockSize(*ltr_space_, *style_,
                                         static_position_bottom, auto_height,
                                         WTF::nullopt, &p);
-  EXPECT_EQ(LayoutUnit(0), p.inset.bottom);
+  EXPECT_EQ(container_size_.block_size, p.inset.bottom);
 
   // If top, bottom, and height are known, compute margins.
   SetVerticalStyle(top, NGAuto, height, NGAuto, bottom);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index 33b4b67..a5eace5 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -206,8 +206,8 @@
   if (NeedMinMaxSize(ConstraintSpace(), Style()))
     min_max_size = ComputeMinMaxSize();
 
-  border_scrollbar_padding_ = CalculateBorderScrollbarPadding(
-      ConstraintSpace(), Style(), Node().GetLayoutObject());
+  border_scrollbar_padding_ =
+      CalculateBorderScrollbarPadding(ConstraintSpace(), Style(), Node());
 
   // TODO(layout-ng): For quirks mode, should we pass blockSize instead of
   // NGSizeIndefinite?
@@ -407,7 +407,8 @@
   // Only layout absolute and fixed children if we aren't going to revisit this
   // layout.
   if (unpositioned_floats_.IsEmpty()) {
-    NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_)
+    NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), Style(),
+                          &container_builder_)
         .Run();
   }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 8b7c9aa..7b922a3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -198,6 +198,23 @@
   return sizes;
 }
 
+NGBoxStrut NGBlockNode::GetScrollbarSizes() const {
+  NGPhysicalBoxStrut sizes;
+  const ComputedStyle* style = GetLayoutObject()->Style();
+  if (!style->IsOverflowVisible()) {
+    const LayoutBox* box = ToLayoutBox(GetLayoutObject());
+    LayoutUnit vertical = LayoutUnit(box->VerticalScrollbarWidth());
+    LayoutUnit horizontal = LayoutUnit(box->HorizontalScrollbarHeight());
+    sizes.bottom = horizontal;
+    if (style->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+      sizes.left = vertical;
+    else
+      sizes.right = vertical;
+  }
+  return sizes.ConvertToLogical(
+      FromPlatformWritingMode(style->GetWritingMode()), style->Direction());
+}
+
 NGLayoutInputNode NGBlockNode::NextSibling() const {
   LayoutObject* next_sibling = box_->NextSibling();
   if (next_sibling) {
@@ -261,7 +278,7 @@
   intrinsic_content_logical_height += fragment.OverflowSize().block_size;
   NGBoxStrut border_scrollbar_padding =
       ComputeBorders(constraint_space, Style()) +
-      ComputePadding(constraint_space, Style()) + GetScrollbarSizes(box_);
+      ComputePadding(constraint_space, Style()) + GetScrollbarSizes();
   if (IsLastFragment(physical_fragment))
     intrinsic_content_logical_height -= border_scrollbar_padding.BlockSum();
   box_->SetLogicalHeight(logical_height);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
index 178fce4..f333124b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -20,6 +20,7 @@
 class NGPhysicalFragment;
 struct MinMaxSize;
 struct NGBaselineRequest;
+struct NGBoxStrut;
 struct NGLogicalOffset;
 
 // Represents a node to be laid out.
@@ -40,6 +41,8 @@
   // both.
   MinMaxSize ComputeMinMaxSize();
 
+  NGBoxStrut GetScrollbarSizes() const;
+
   NGLayoutInputNode FirstChild();
 
   // Runs layout on the underlying LayoutObject and creates a fragment for the
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc
index 47eee44..d670ee6 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc
@@ -23,8 +23,8 @@
   Optional<MinMaxSize> min_max_size;
   if (NeedMinMaxSize(ConstraintSpace(), Style()))
     min_max_size = ComputeMinMaxSize();
-  NGBoxStrut border_scrollbar_padding = CalculateBorderScrollbarPadding(
-      ConstraintSpace(), Style(), Node().GetLayoutObject());
+  NGBoxStrut border_scrollbar_padding =
+      CalculateBorderScrollbarPadding(ConstraintSpace(), Style(), Node());
   NGLogicalSize border_box_size =
       CalculateBorderBoxSize(ConstraintSpace(), Style(), min_max_size);
   content_box_size_ =
@@ -71,7 +71,8 @@
 
   container_builder_.SetOverflowSize(overflow);
 
-  NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_).Run();
+  NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), Style(), &container_builder_)
+      .Run();
 
   // TODO(mstensho): Propagate baselines.
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
index 055b12b..f12bfb4f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -511,21 +511,12 @@
   return length;
 }
 
-NGBoxStrut GetScrollbarSizes(const LayoutObject* layout_object) {
-  NGPhysicalBoxStrut sizes;
-  const ComputedStyle* style = layout_object->Style();
-  if (!style->IsOverflowVisible()) {
-    const LayoutBox* box = ToLayoutBox(layout_object);
-    LayoutUnit vertical = LayoutUnit(box->VerticalScrollbarWidth());
-    LayoutUnit horizontal = LayoutUnit(box->HorizontalScrollbarHeight());
-    sizes.bottom = horizontal;
-    if (style->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
-      sizes.left = vertical;
-    else
-      sizes.right = vertical;
-  }
-  return sizes.ConvertToLogical(
-      FromPlatformWritingMode(style->GetWritingMode()), style->Direction());
+NGBoxStrut CalculateBorderScrollbarPadding(
+    const NGConstraintSpace& constraint_space,
+    const ComputedStyle& style,
+    const NGBlockNode node) {
+  return ComputeBorders(constraint_space, style) +
+         ComputePadding(constraint_space, style) + node.GetScrollbarSizes();
 }
 
 NGLogicalSize CalculateContentBoxSize(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
index 637e2fa..0ea112d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
@@ -15,9 +15,9 @@
 
 namespace blink {
 class ComputedStyle;
-class LayoutObject;
 class Length;
 class NGConstraintSpace;
+class NGBlockNode;
 class NGLayoutInputNode;
 
 enum class LengthResolveType {
@@ -128,17 +128,10 @@
                                          Optional<LayoutUnit> min,
                                          Optional<LayoutUnit> max);
 
-// Returns scrollbar sizes or this layout object.
-NGBoxStrut GetScrollbarSizes(const LayoutObject*);
-
-inline NGBoxStrut CalculateBorderScrollbarPadding(
+NGBoxStrut CalculateBorderScrollbarPadding(
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
-    const LayoutObject* layout_object) {
-  return ComputeBorders(constraint_space, style) +
-         ComputePadding(constraint_space, style) +
-         GetScrollbarSizes(layout_object);
-}
+    const NGBlockNode node);
 
 inline NGLogicalSize CalculateBorderBoxSize(
     const NGConstraintSpace& constraint_space,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
index fb4503a3..4964c39 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -34,6 +34,7 @@
 }  // namespace
 
 NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
+    const NGBlockNode container,
     const NGConstraintSpace& container_space,
     const ComputedStyle& container_style,
     NGFragmentBuilder* container_builder)
@@ -42,17 +43,19 @@
       FromPlatformWritingMode(container_style_.GetWritingMode()));
 
   NGBoxStrut borders = ComputeBorders(container_space, container_style_);
-  container_border_offset_ =
-      NGLogicalOffset{borders.inline_start, borders.block_start};
-  container_border_physical_offset_ =
-      container_border_offset_.ConvertToPhysical(
-          writing_mode, container_style_.Direction(),
-          container_builder_->Size().ConvertToPhysical(writing_mode),
-          NGPhysicalSize());
+  NGBoxStrut scrollers = container.GetScrollbarSizes();
+  NGBoxStrut borders_and_scrollers = borders + scrollers;
+  content_offset_ = NGLogicalOffset{borders_and_scrollers.inline_start,
+                                    borders_and_scrollers.block_start};
+
+  NGPhysicalBoxStrut physical_borders = borders_and_scrollers.ConvertToPhysical(
+      writing_mode, container_style_.Direction());
+  content_physical_offset_ =
+      NGPhysicalOffset(physical_borders.left, physical_borders.top);
 
   container_size_ = container_builder_->Size();
-  container_size_.inline_size -= borders.InlineSum();
-  container_size_.block_size -= borders.BlockSum();
+  container_size_.inline_size -= borders_and_scrollers.InlineSum();
+  container_size_.block_size -= borders_and_scrollers.BlockSum();
 
   icb_size_ = container_space.InitialContainingBlockSize();
 }
@@ -97,7 +100,7 @@
   // Adjust the static_position origin. The static_position coordinate origin is
   // relative to the container's border box, ng_absolute_utils expects it to be
   // relative to the container's padding box.
-  static_position.offset -= container_border_physical_offset_;
+  static_position.offset -= content_physical_offset_;
 
   // The block estimate is in the descendant's writing mode.
   RefPtr<NGConstraintSpace> descendant_constraint_space =
@@ -151,10 +154,8 @@
   // to the padding box so add back the container's borders.
   NGBoxStrut inset = node_position.inset.ConvertToLogical(
       container_writing_mode, container_style_.Direction());
-  offset->inline_offset =
-      inset.inline_start + container_border_offset_.inline_offset;
-  offset->block_offset =
-      inset.block_start + container_border_offset_.block_offset;
+  offset->inline_offset = inset.inline_start + content_offset_.inline_offset;
+  offset->block_offset = inset.block_start + content_offset_.block_offset;
 
   return layout_result;
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
index f3ceeec..78329af 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -27,7 +27,8 @@
   STACK_ALLOCATED();
 
  public:
-  NGOutOfFlowLayoutPart(const NGConstraintSpace& contianer_space,
+  NGOutOfFlowLayoutPart(const NGBlockNode container,
+                        const NGConstraintSpace& container_space,
                         const ComputedStyle& container_style,
                         NGFragmentBuilder* container_builder);
   void Run();
@@ -45,8 +46,8 @@
   const ComputedStyle& container_style_;
   NGFragmentBuilder* container_builder_;
 
-  NGLogicalOffset container_border_offset_;
-  NGPhysicalOffset container_border_physical_offset_;
+  NGLogicalOffset content_offset_;
+  NGPhysicalOffset content_physical_offset_;
   NGLogicalSize container_size_;
   NGPhysicalSize icb_size_;
 };
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 9753e20..aad4413 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -230,7 +230,12 @@
 
   // Repaint if previously the layer might be clipped by paintDirtyRect and
   // paintDirtyRect changes.
-  if (paint_layer.PreviousPaintResult() == kMayBeClippedByPaintDirtyRect &&
+  if ((paint_layer.PreviousPaintResult() == kMayBeClippedByPaintDirtyRect ||
+       // When PaintUnderInvalidationChecking is enabled, always repaint the
+       // subsequence when the paint rect changes because we will strictly match
+       // new and cached subsequences. Normally we can reuse the cached fully
+       // painted subsequence even if we would partially paint this time.
+       RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) &&
       paint_layer.PreviousPaintDirtyRect() != painting_info.paint_dirty_rect) {
     needs_repaint = true;
     should_clear_empty_paint_phase_flags = true;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
index 71ee3d5..53f3215 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -272,6 +272,29 @@
 }
 
 TEST_P(PaintLayerPainterTest,
+       CachedSubsequenceOnInterestRectChangeUnderInvalidationChecking) {
+  ScopedPaintUnderInvalidationCheckingForTest under_invalidation_checking(true);
+
+  SetBodyInnerHTML(
+      "<style>p { width: 200px; height: 50px; background: green }</style>"
+      "<div id='target' style='position: relative; z-index: 1'>"
+      "  <p></p><p></p><p></p><p></p>"
+      "</div>");
+  RootPaintController().InvalidateAll();
+
+  // |target| will be fully painted.
+  GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+  IntRect interest_rect(0, 0, 400, 300);
+  Paint(&interest_rect);
+
+  // |target| will be partially painted. Should not trigger under-invalidation
+  // checking DCHECKs.
+  GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+  IntRect new_interest_rect(0, 100, 300, 1000);
+  Paint(&new_interest_rect);
+}
+
+TEST_P(PaintLayerPainterTest,
        CachedSubsequenceOnStyleChangeWithInterestRectClipping) {
   SetBodyInnerHTML(
       "<div id='container1' style='position: relative; z-index: 1;"
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index fe068e8..4fb7da28 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -1319,10 +1319,7 @@
       // frame rect, so force a property update if it changes. TODO(pdr): We
       // only need to update properties if there are relative lengths.
       box.StyleRef().HasTransform() || box.StyleRef().HasPerspective() ||
-      box_generates_property_nodes_for_mask_and_clip_path
-      // Fragmentation sizes, positions and counts depend on the size of a
-      // fragmented box.
-      || (box.Layer() && box.Layer()->EnclosingPaginationLayer()))
+      box_generates_property_nodes_for_mask_and_clip_path)
     box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
 }
 
@@ -1416,6 +1413,12 @@
       PaintLayer* enclosing_pagination_layer =
           paint_layer->EnclosingPaginationLayer();
 
+      // Always force-update properties for fragmented content.
+      // TODO(chrishtr): find ways to optimize this in the future.
+      // It may suffice to compare previous and current visual overflow,
+      // but we do not currenly cache that on the LayoutObject or PaintLayer.
+      object.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
+
       LayoutPoint offset_within_paginated_layer;
       paint_layer->ConvertToLayerCoords(enclosing_pagination_layer,
                                         offset_within_paginated_layer);
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
index 0a2dc6f..57cef37 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -3182,28 +3182,24 @@
     const GraphicsLayer* graphics_layer) const {
   FloatRect graphics_layer_bounds(FloatPoint(), graphics_layer->Size());
 
-  IntSize offset_from_anchor_layout_object;
+  FloatSize offset_from_anchor_layout_object;
   const LayoutBoxModelObject* anchor_layout_object;
   if (graphics_layer == squashing_layer_.get()) {
-    // TODO(chrishtr): this is a speculative fix for crbug.com/561306. However,
-    // it should never be the case that m_squashingLayer exists,
-    // yet m_squashedLayers.size() == 0. There must be a bug elsewhere.
-    if (squashed_layers_.size() == 0)
-      return IntRect();
     // All squashed layers have the same clip and transform space, so we can use
     // the first squashed layer's layoutObject to map the squashing layer's
     // bounds into viewport space, with offsetFromAnchorLayoutObject to
     // translate squashing layer's bounds into the first squashed layer's space.
-    anchor_layout_object = &squashed_layers_[0].paint_layer->GetLayoutObject();
+    anchor_layout_object =
+        &owning_layer_.EnclosingTransformedAncestor()->GetLayoutObject();
     offset_from_anchor_layout_object =
-        squashed_layers_[0].offset_from_layout_object;
+        ToFloatSize(FloatPoint(SquashingOffsetFromTransformedAncestor()));
   } else {
     DCHECK(graphics_layer == graphics_layer_.get() ||
            graphics_layer == scrolling_contents_layer_.get());
     anchor_layout_object = &owning_layer_.GetLayoutObject();
-    offset_from_anchor_layout_object = graphics_layer->OffsetFromLayoutObject();
-    AdjustForCompositedScrolling(graphics_layer,
-                                 offset_from_anchor_layout_object);
+    IntSize offset = graphics_layer->OffsetFromLayoutObject();
+    AdjustForCompositedScrolling(graphics_layer, offset);
+    offset_from_anchor_layout_object = FloatSize(offset);
   }
 
   // Start with the bounds of the graphics layer in the space of the anchor
@@ -3226,12 +3222,12 @@
   FloatRect visible_content_rect(graphics_layer_bounds_in_root_view_space);
   root_view->GetFrameView()->ClipPaintRect(&visible_content_rect);
 
-  IntRect enclosing_graphics_layer_bounds(
+  FloatRect enclosing_graphics_layer_bounds(
       EnclosingIntRect(graphics_layer_bounds));
 
   // Map the visible content rect from root view space to local graphics layer
   // space.
-  IntRect local_interest_rect;
+  FloatRect local_interest_rect;
   // If the visible content rect is empty, then it makes no sense to map it back
   // since there is nothing to map.
   if (!visible_content_rect.IsEmpty()) {
@@ -3257,7 +3253,7 @@
     local_interest_rect.Inflate(kPixelDistanceToRecord);
     local_interest_rect.Intersect(enclosing_graphics_layer_bounds);
   }
-  return local_interest_rect;
+  return EnclosingIntRect(local_interest_rect);
 }
 
 static const int kMinimumDistanceBeforeRepaint = 512;
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.h
index d92ab80f..9ffab1c91 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.h
@@ -278,7 +278,7 @@
 
   LayoutSize ContentOffsetInCompositingLayer() const;
 
-  LayoutPoint SquashingOffsetFromTransformedAncestor() {
+  LayoutPoint SquashingOffsetFromTransformedAncestor() const {
     return squashing_layer_offset_from_transformed_ancestor_;
   }
 
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
index cb338e7..6ba15f2 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
@@ -184,9 +184,6 @@
   if (layer->TransformAncestor() != squashing_layer.TransformAncestor())
     return kSquashingDisallowedReasonTransformAncestorMismatch;
 
-  if (layer->Transform() && !layer->Transform()->IsIdentityOrTranslation())
-    return kSquashingDisallowedReasonNonTranslationTransform;
-
   if (layer->RenderingContextRoot() != squashing_layer.RenderingContextRoot())
     return kSquashingDisallowedReasonRenderingContextMismatch;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js
index 054cef0a..545653e8 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js
@@ -228,15 +228,8 @@
     this._selectedByUser = true;
 
     axNode.deferredDOMNode().resolve(domNode => {
-      var inspectedDOMNode = UI.context.flavor(SDK.DOMNode);
-      // Special case the root accessibility node: set the node for the
-      // accessibility panel, not the Elements tree, as it maps to the Document
-      // node which is not shown in the DOM panel, causing the first child to be
-      // inspected instead.
-      if (axNode.parentNode() && domNode !== inspectedDOMNode)
-        Common.Revealer.reveal(domNode, true /* omitFocus */);
-      else
-        this._axSidebarView.setNode(domNode);
+      this._axSidebarView.setNode(domNode, true /* fromAXTree */);
+      Common.Revealer.reveal(domNode, true /* omitFocus */);
     });
 
     return true;
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
index 8f7de13..78b3918 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -9,6 +9,7 @@
     super();
     this._node = null;
     this._axNode = null;
+    this._skipNextPullNode = false;
     this._sidebarPaneStack = UI.viewManager.createStackLocation();
     this._breadcrumbsSubPane = new Accessibility.AXBreadcrumbsPane(this);
     this._sidebarPaneStack.showView(this._breadcrumbsSubPane);
@@ -37,8 +38,10 @@
 
   /**
    * @param {?SDK.DOMNode} node
+   * @param {boolean=} fromAXTree
    */
-  setNode(node) {
+  setNode(node, fromAXTree) {
+    this._skipNextPullNode = !!fromAXTree;
     this._node = node;
     this.update();
   }
@@ -114,6 +117,10 @@
   }
 
   _pullNode() {
+    if (this._skipNextPullNode) {
+      this._skipNextPullNode = false;
+      return;
+    }
     this.setNode(UI.context.flavor(SDK.DOMNode));
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/color_picker/spectrum.css b/third_party/WebKit/Source/devtools/front_end/color_picker/spectrum.css
index f303774..f4f9dd39 100644
--- a/third_party/WebKit/Source/devtools/front_end/color_picker/spectrum.css
+++ b/third_party/WebKit/Source/devtools/front_end/color_picker/spectrum.css
@@ -101,6 +101,7 @@
     background-color: rgba(255, 255, 255, 0.2);
     align-items: center;
     transition: right .05s ease-out, left .05s ease-out, bottom .05s ease-out, top .05s ease-out;
+    cursor: pointer;
 }
 
 .spectrum-contrast-info.contrast-unknown .value {
@@ -623,6 +624,10 @@
     top: 7px;
 }
 
-button.background-color-picker.active [is=ui-icon].largeicon-eyedropper.icon-mask{
+button.background-color-picker.active [is=ui-icon].largeicon-eyedropper.icon-mask {
     background-color: hsl(218, 81%, 59%);
 }
+
+button.background-color-picker:hover [is=ui-icon].largeicon-eyedropper.icon-mask {
+    background-color: #333;
+}
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
index a6550875..b6c4c2e 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -195,6 +195,11 @@
       reader_ = handle_->ObtainReader(this);
     }
 
+    void Cancel() {
+      reader_ = nullptr;
+      handle_ = nullptr;
+    }
+
     void DidGetReadable() override {
       DCHECK(reader_);
       DCHECK(loader_);
@@ -648,6 +653,8 @@
     loader_->Cancel();
     loader_ = nullptr;
   }
+  if (integrity_verifier_)
+    integrity_verifier_->Cancel();
   execution_context_ = nullptr;
 }
 
diff --git a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
index 37eac55..049c7896 100644
--- a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
+++ b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
@@ -244,8 +244,12 @@
   // cross-origin fingerprinting. The random number should also be a function
   // of randomized salt which is known only to the device. This prevents
   // origin from removing noise from the estimates.
-  unsigned hash = StringHash::GetHash(GetExecutionContext()->Url().Host()) +
-                  GetNetworkStateNotifier().RandomizationSalt();
+  const String host = GetExecutionContext()->Url().Host();
+  if (!host)
+    return 1.0;
+
+  unsigned hash =
+      StringHash::GetHash(host) + GetNetworkStateNotifier().RandomizationSalt();
   double random_multiplier = 0.9 + static_cast<double>((hash % 21)) * 0.01;
   DCHECK_LE(0.90, random_multiplier);
   DCHECK_GE(1.10, random_multiplier);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index 03b27c9..c4f3531 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -206,10 +206,6 @@
       status: "experimental",
     },
     {
-      name: "CSS3TextDecorations",
-      status: "stable",
-    },
-    {
       name: "CSSAdditiveAnimations",
       depends_on: ["StackedCSSPropertyAnimations"],
       status: "experimental",
diff --git a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.cpp b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.cpp
index aee47ed..7f25de0 100644
--- a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.cpp
+++ b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.cpp
@@ -62,10 +62,6 @@
         {kSquashingDisallowedReasonRenderingContextMismatch,
          "squashingLayerRenderingContextMismatch",
          "Cannot squash layers with different 3D contexts."},
-        {kSquashingDisallowedReasonNonTranslationTransform,
-         "SquashingDisallowedReasonNonTranslationTransform",
-         "Cannot squash layers with transforms that are not identity or "
-         "translation."},
         {kSquashingDisallowedReasonFragmentedContent,
          "SquashingDisallowedReasonFragmentedContent",
          "Cannot squash layers that are inside fragmentation contexts."},
diff --git a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
index 95c98a9..70b346c 100644
--- a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
+++ b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
@@ -28,8 +28,7 @@
   kSquashingDisallowedReasonScrollChildWithCompositedDescendants = 1 << 12,
   kSquashingDisallowedReasonSquashingLayerIsAnimating = 1 << 13,
   kSquashingDisallowedReasonRenderingContextMismatch = 1 << 14,
-  kSquashingDisallowedReasonNonTranslationTransform = 1 << 15,
-  kSquashingDisallowedReasonFragmentedContent = 1 << 16,
+  kSquashingDisallowedReasonFragmentedContent = 1 << 15,
 };
 
 typedef unsigned SquashingDisallowedReasons;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 3a24763..bbfdaa2 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -173,18 +173,9 @@
 void PaintController::EndSubsequence(const DisplayItemClient& client,
                                      size_t start) {
   size_t end = new_display_item_list_.size();
-  if (start == end) {
-    // Omit the empty subsequence. The forcing-new-chunk flag set by
-    // BeginSubsequence() still applies, but this not a big deal because empty
-    // subsequences are not common. Also we should not clear the flag because
-    // there might be unhandled flag that was set before this empty subsequence.
-    return;
-  }
 
-  // Force new paint chunk which is required for subsequence caching.
-  new_paint_chunks_.ForceNewChunk();
-
-  if (IsCheckingUnderInvalidation()) {
+  if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
+      IsCheckingUnderInvalidation()) {
     SubsequenceMarkers* markers = GetSubsequenceMarkers(client);
     if (!markers) {
       ShowSequenceUnderInvalidationError(
@@ -197,8 +188,20 @@
           end);
       CHECK(false);
     }
+    under_invalidation_checking_end_ = 0;
   }
 
+  if (start == end) {
+    // Omit the empty subsequence. The forcing-new-chunk flag set by
+    // BeginSubsequence() still applies, but this not a big deal because empty
+    // subsequences are not common. Also we should not clear the flag because
+    // there might be unhandled flag that was set before this empty subsequence.
+    return;
+  }
+
+  // Force new paint chunk which is required for subsequence caching.
+  new_paint_chunks_.ForceNewChunk();
+
   DCHECK(new_cached_subsequences_.find(&client) ==
          new_cached_subsequences_.end());
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index 09571a8..78ad5e9 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -306,9 +306,8 @@
 
   void CheckUnderInvalidation();
   bool IsCheckingUnderInvalidation() const {
-    return under_invalidation_checking_end_ -
-               under_invalidation_checking_begin_ >
-           0;
+    return under_invalidation_checking_end_ >
+           under_invalidation_checking_begin_;
   }
 
   struct SubsequenceMarkers {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 6ae7f82..6cfeb9b 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -2387,6 +2387,25 @@
     }
     GetPaintController().CommitNewDisplayItems();
   }
+
+  void TestSubsequenceBecomesEmpty() {
+    FakeDisplayItemClient target("target");
+    GraphicsContext context(GetPaintController());
+
+    {
+      SubsequenceRecorder r(context, target);
+      DrawRect(context, target, kBackgroundDrawingType,
+               FloatRect(100, 100, 300, 300));
+    }
+    GetPaintController().CommitNewDisplayItems();
+
+    {
+      EXPECT_FALSE(
+          SubsequenceRecorder::UseCachedSubsequenceIfPossible(context, target));
+      SubsequenceRecorder r(context, target);
+    }
+    GetPaintController().CommitNewDisplayItems();
+  }
 };
 
 TEST_F(PaintControllerUnderInvalidationTest, ChangeDrawing) {
@@ -2436,6 +2455,10 @@
   TestInvalidationInSubsequence();
 }
 
+TEST_F(PaintControllerUnderInvalidationTest, SubsequenceBecomesEmpty) {
+  EXPECT_DEATH(TestSubsequenceBecomesEmpty(), "");
+}
+
 #endif  // defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 2cd1653..80280f7 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -318,10 +318,8 @@
 
 size_t ThreadState::EstimatedLiveSize(size_t estimation_base_size,
                                       size_t size_at_last_gc) {
-  if (heap_->HeapStats().WrapperCountAtLastGC() == 0) {
-    // We'll reach here only before hitting the first GC.
-    return 0;
-  }
+  if (heap_->HeapStats().WrapperCountAtLastGC() == 0)
+    return estimation_base_size;
 
   // (estimated size) = (estimation base size) - (heap size at the last GC) /
   //   (# of persistent handles at the last GC) *
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index 43ff3fa..1d2b0d9 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -278,11 +278,13 @@
         gesture_event.GetType() == blink::WebGestureEvent::kGestureScrollEnd;
     if (is_from_set_non_blocking_touch || is_scroll_end_from_wheel ||
         synchronous_input_handler_) {
-      // Gesture events was already delayed by blocking events in rAF aligned
+      // 1. Gesture events was already delayed by blocking events in rAF aligned
       // queue. We want to avoid additional one frame delay by flushing the
       // VSync queue immediately.
       // The first GSU latency was tracked by:
       // |smoothness.tough_scrolling_cases:first_gesture_scroll_update_latency|.
+      // 2. |synchronous_input_handler_| is WebView only. WebView has different
+      // mechanisms and we want to forward all events immediately.
       compositor_event_queue_->Queue(std::move(event_with_callback),
                                      tick_clock_->NowTicks());
       DispatchQueuedInputEvents();