diff --git a/DEPS b/DEPS
index 15e6b53..6bcec07 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': 'c61abeed8958a757c6b49937f28b63066148dd67',
+  'skia_revision': '7928e768728fe7eef9345345c74e810435dd3eac',
   # 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': '03d03326a57b940fc386775d3efe1f33525c4f2d',
+  'v8_revision': '0096d40434210d7c3a0f42eb63f93fd196bb4d36',
   # 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.
diff --git a/base/security_unittest.cc b/base/security_unittest.cc
index 24fbbd7..519c997eb 100644
--- a/base/security_unittest.cc
+++ b/base/security_unittest.cc
@@ -87,7 +87,8 @@
   }
 }
 
-#if defined(OS_IOS) || defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+#if defined(OS_IOS) || defined(ADDRESS_SANITIZER) || \
+    defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER)
 #define MAYBE_NewOverflow DISABLED_NewOverflow
 #else
 #define MAYBE_NewOverflow NewOverflow
diff --git a/build/install-build-deps-android.sh b/build/install-build-deps-android.sh
index 37f4244..6ae6e90 100755
--- a/build/install-build-deps-android.sh
+++ b/build/install-build-deps-android.sh
@@ -67,6 +67,9 @@
 
 sudo apt-get -y install ant
 
+# Required for apk-patch-size-estimator
+sudo apt-get -y install bsdiff
+
 # Install openjdk and openjre stuff
 sudo apt-get -y install $java_pkgs
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index 5cfed32..5f492485 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -36,6 +36,8 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.blink.mojom.MediaSessionAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeApplication;
+import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
 import org.chromium.content_public.common.MediaMetadata;
 
@@ -84,7 +86,7 @@
 
     private SparseArray<MediaButtonInfo> mActionToButtonInfo;
 
-    private NotificationCompat.Builder mNotificationBuilder;
+    private ChromeNotificationBuilder mNotificationBuilder;
 
     private Bitmap mDefaultNotificationLargeIcon;
 
@@ -539,8 +541,7 @@
 
     @VisibleForTesting
     @Nullable
-    static NotificationCompat.Builder getNotificationBuilderForTesting(
-            int notificationId) {
+    static ChromeNotificationBuilder getNotificationBuilderForTesting(int notificationId) {
         MediaNotificationManager manager = getManager(notificationId);
         if (manager == null) return null;
 
@@ -721,7 +722,15 @@
 
         updateMediaSession();
 
-        mNotificationBuilder = new NotificationCompat.Builder(mContext);
+        mNotificationBuilder =
+                ((ChromeApplication) mContext.getApplicationContext())
+                        .createChromeNotificationBuilder(true,
+                                NotificationConstants.CATEGORY_ID_BROWSER,
+                                mContext.getString(
+                                        org.chromium.chrome.R.string.notification_category_browser),
+                                NotificationConstants.CATEGORY_GROUP_ID_GENERAL,
+                                mContext.getString(org.chromium.chrome.R.string
+                                                           .notification_category_group_general));
         setMediaStyleLayoutForNotificationBuilder(mNotificationBuilder);
 
         mNotificationBuilder.setSmallIcon(mMediaNotificationInfo.notificationSmallIcon);
@@ -853,7 +862,7 @@
         mMediaSession.setActive(true);
     }
 
-    private void setMediaStyleLayoutForNotificationBuilder(NotificationCompat.Builder builder) {
+    private void setMediaStyleLayoutForNotificationBuilder(ChromeNotificationBuilder builder) {
         setMediaStyleNotificationText(builder);
         if (!mMediaNotificationInfo.supportsPlayPause()) {
             builder.setLargeIcon(null);
@@ -876,7 +885,7 @@
         addNotificationButtons(builder);
     }
 
-    private void addNotificationButtons(NotificationCompat.Builder builder) {
+    private void addNotificationButtons(ChromeNotificationBuilder builder) {
         Set<Integer> actions = new HashSet<>();
 
         // TODO(zqzhang): handle other actions when play/pause is not supported? See
@@ -907,15 +916,8 @@
 
         // Only apply MediaStyle when NotificationInfo supports play/pause.
         if (mMediaNotificationInfo.supportsPlayPause()) {
-            NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
-            style.setMediaSession(mMediaSession.getSessionToken());
-
-            int[] compactViewActionIndices = computeCompactViewActionIndices(bigViewActions);
-
-            style.setShowActionsInCompactView(compactViewActionIndices);
-            style.setCancelButtonIntent(createPendingIntent(ListenerService.ACTION_CANCEL));
-            style.setShowCancelButton(true);
-            builder.setStyle(style);
+            builder.setMediaStyle(mMediaSession, computeCompactViewActionIndices(bigViewActions),
+                    createPendingIntent(ListenerService.ACTION_CANCEL), true);
         }
     }
 
@@ -926,7 +928,7 @@
         return bitmapDrawable.getBitmap();
     }
 
-    private void setMediaStyleNotificationText(NotificationCompat.Builder builder) {
+    private void setMediaStyleNotificationText(ChromeNotificationBuilder builder) {
         builder.setContentTitle(mMediaNotificationInfo.metadata.getTitle());
         String artistAndAlbumText = getArtistAndAlbumText(mMediaNotificationInfo.metadata);
         if (isRunningN() || !artistAndAlbumText.isEmpty()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java
index d28cf02..05dea24 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java
@@ -8,6 +8,7 @@
 import android.app.PendingIntent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
+import android.support.v4.media.session.MediaSessionCompat;
 import android.widget.RemoteViews;
 
 /**
@@ -74,6 +75,9 @@
 
     ChromeNotificationBuilder setStyle(Notification.BigTextStyle bigTextStyle);
 
+    ChromeNotificationBuilder setMediaStyle(MediaSessionCompat session, int[] actions,
+            PendingIntent intent, boolean showCancelButton);
+
     Notification buildWithBigContentView(RemoteViews bigView);
 
     Notification buildWithBigTextStyle(String bigText);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
index 5597085..13c19bcc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
@@ -9,7 +9,9 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
+import android.media.session.MediaSession;
 import android.os.Build;
+import android.support.v4.media.session.MediaSessionCompat;
 import android.widget.RemoteViews;
 
 /**
@@ -221,6 +223,18 @@
     }
 
     @Override
+    public ChromeNotificationBuilder setMediaStyle(MediaSessionCompat session, int[] actions,
+            PendingIntent intent, boolean showCancelButton) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            Notification.MediaStyle style = new Notification.MediaStyle();
+            style.setMediaSession(((MediaSession) session.getMediaSession()).getSessionToken());
+            style.setShowActionsInCompactView(actions);
+            mBuilder.setStyle(style);
+        }
+        return this;
+    }
+
+    @Override
     public Notification buildWithBigContentView(RemoteViews view) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
             return mBuilder.setCustomBigContentView(view).build();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationCompatBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationCompatBuilder.java
index 78034fd..14b4950 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationCompatBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationCompatBuilder.java
@@ -9,7 +9,8 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
-import android.support.v4.app.NotificationCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v7.app.NotificationCompat;
 import android.widget.RemoteViews;
 
 /**
@@ -195,6 +196,18 @@
     }
 
     @Override
+    public ChromeNotificationBuilder setMediaStyle(MediaSessionCompat session, int[] actions,
+            PendingIntent intent, boolean showCancelButton) {
+        NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
+        style.setMediaSession(session.getSessionToken());
+        style.setShowActionsInCompactView(actions);
+        style.setCancelButtonIntent(intent);
+        style.setShowCancelButton(showCancelButton);
+        mBuilder.setStyle(style);
+        return this;
+    }
+
+    @Override
     public Notification buildWithBigContentView(RemoteViews view) {
         return mBuilder.setCustomBigContentView(view).build();
     }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 89a7db5..3ffb8b5 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -14937,6 +14937,14 @@
     <message name="IDS_FLAGS_ENABLE_ADJUSTABLE_LARGE_CURSOR_DESCRIPTION" desc="Description of the flag that enables adjustable large cursor.">
       Make size of accessibility large cursor adjustable.
     </message>
+    <if expr="chromeos or is_linux or is_macosx or is_win">
+      <message name="IDS_FLAGS_OMNIBOX_ENTITY_SUGGESTIONS_NAME" desc="Name of the flag that enables receiving entity suggestions.">
+        Omnibox entity suggestions
+      </message>
+      <message name="IDS_FLAGS_OMNIBOX_ENTITY_SUGGESTIONS_DESCRIPTION" desc="Description of the flag that enables entity suggestions.">
+        Enable receiving entity suggestions in Omnibox.
+      </message>
+    </if>
   </messages>
  </release>
 </grit>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index ea4ad48..18dd9c4 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2321,6 +2321,14 @@
      IDS_FLAGS_NEW_OMNIBOX_ANSWER_TYPES_DESCRIPTION, kOsAll,
      FEATURE_VALUE_TYPE(omnibox::kNewOmniboxAnswerTypes)},
 
+#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX) || \
+    defined(OS_WIN)
+    {"omnibox-entity-suggestions", IDS_FLAGS_OMNIBOX_ENTITY_SUGGESTIONS_NAME,
+     IDS_FLAGS_OMNIBOX_ENTITY_SUGGESTIONS_DESCRIPTION, kOsDesktop,
+     FEATURE_VALUE_TYPE(omnibox::kOmniboxEntitySuggestions)},
+#endif  // defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX) ||
+        // defined(OS_WIN)
+
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms.xml. See note in
     // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 295fdfb..6430bae 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -9,6 +9,8 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
+#include "base/path_service.h"
+#include "base/syslog_logging.h"
 #include "build/build_config.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
@@ -34,6 +36,7 @@
 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/channel_info.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -55,6 +58,7 @@
 #include "components/search_engines/search_engine_data_type_controller.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/spellcheck/spellcheck_build_features.h"
+#include "components/sync/base/pref_names.h"
 #include "components/sync/base/report_unrecoverable_error.h"
 #include "components/sync/driver/async_directory_type_controller.h"
 #include "components/sync/driver/sync_api_component_factory.h"
@@ -123,6 +127,13 @@
 
 namespace browser_sync {
 
+namespace {
+#if defined(OS_WIN)
+const base::FilePath::CharType kLoopbackServerBackendFilename[] =
+    FILE_PATH_LITERAL("profile.pb");
+#endif
+}  // namespace
+
 // Chrome implementation of SyncSessionsClient. Needs to be in a separate class
 // due to possible multiple inheritance issues, wherein ChromeSyncClient might
 // inherit from other interfaces with same methods.
@@ -235,6 +246,35 @@
   return profile_->GetPrefs();
 }
 
+base::FilePath ChromeSyncClient::GetLocalSyncBackendFolder() {
+  base::FilePath local_sync_backend_folder =
+      GetPrefService()->GetFilePath(syncer::prefs::kLocalSyncBackendDir);
+
+#if defined(OS_WIN)
+  if (local_sync_backend_folder.empty()) {
+    if (!base::PathService::Get(chrome::DIR_ROAMING_USER_DATA,
+                                &local_sync_backend_folder)) {
+      SYSLOG(WARNING) << "Local sync can not get the roaming profile folder.";
+      return base::FilePath();
+    }
+  }
+
+  // This code as it is now will assume the same profile order is present on
+  // all machines, which is not a given. It is to be defined if only the
+  // Default profile should get this treatment or all profile as is the case
+  // now.
+  // TODO(pastarmovj): http://crbug.com/674928 Decide if only the Default one
+  // should be considered roamed. For now the code assumes all profiles are
+  // created in the same order on all machines.
+  local_sync_backend_folder =
+      local_sync_backend_folder.Append(profile_->GetPath().BaseName());
+  local_sync_backend_folder =
+      local_sync_backend_folder.Append(kLoopbackServerBackendFilename);
+#endif  // defined(OS_WIN)
+
+  return local_sync_backend_folder;
+}
+
 bookmarks::BookmarkModel* ChromeSyncClient::GetBookmarkModel() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return BookmarkModelFactory::GetForBrowserContext(profile_);
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h
index 4004061..7ad51302 100644
--- a/chrome/browser/sync/chrome_sync_client.h
+++ b/chrome/browser/sync/chrome_sync_client.h
@@ -39,6 +39,7 @@
   void Initialize() override;
   syncer::SyncService* GetSyncService() override;
   PrefService* GetPrefService() override;
+  base::FilePath GetLocalSyncBackendFolder() override;
   bookmarks::BookmarkModel* GetBookmarkModel() override;
   favicon::FaviconService* GetFaviconService() override;
   history::HistoryService* GetHistoryService() override;
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index 468c41ea..57d9f22 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -8,6 +8,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -75,11 +76,6 @@
                  latency, base::TimeTicks::Now()));
 }
 
-#if defined(OS_WIN)
-static const base::FilePath::CharType kLoopbackServerBackendFilename[] =
-    FILE_PATH_LITERAL("profile.pb");
-#endif
-
 }  // anonymous namespace
 
 // static
@@ -160,27 +156,31 @@
           blocking_pool->GetSequenceToken(),
           base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
-  bool local_sync_backend_enabled = false;
+  if (!client_factory_) {
+    init_params.sync_client =
+        base::MakeUnique<browser_sync::ChromeSyncClient>(profile);
+  } else {
+    init_params.sync_client = client_factory_->Run(profile);
+  }
 
+  bool local_sync_backend_enabled = false;
 // Since the local sync backend is currently only supported on Windows don't
 // even check the pref on other os-es.
 #if defined(OS_WIN)
   syncer::SyncPrefs prefs(profile->GetPrefs());
   local_sync_backend_enabled = prefs.IsLocalSyncEnabled();
+  UMA_HISTOGRAM_BOOLEAN("Sync.Local.Enabled", local_sync_backend_enabled);
+
   if (local_sync_backend_enabled) {
-    // This code as it is now will assume the same profile order is present on
-    // all machines, which is not a given. It is to be defined if only the
-    // Default profile should get this treatment or all profile as is the case
-    // now. The solution for now will be to assume profiles are created in the
-    // same order on all machines and in the future decide if only the Default
-    // one should be considered roamed.
-    init_params.local_sync_backend_folder = prefs.GetLocalSyncBackendDir();
-    init_params.local_sync_backend_folder =
-        init_params.local_sync_backend_folder.Append(
-            init_params.base_directory.BaseName());
-    init_params.local_sync_backend_folder =
-        init_params.local_sync_backend_folder.Append(
-            kLoopbackServerBackendFilename);
+    base::FilePath local_sync_backend_folder =
+        init_params.sync_client->GetLocalSyncBackendFolder();
+
+    // If the user has not specified a folder and we can't get the default
+    // roaming profile location the sync service will not be created.
+    UMA_HISTOGRAM_BOOLEAN("Sync.Local.RoamingProfileUnavailable",
+                          local_sync_backend_folder.empty());
+    if (local_sync_backend_folder.empty())
+      return nullptr;
 
     init_params.start_behavior = ProfileSyncService::AUTO_START;
   }
@@ -216,13 +216,6 @@
                                      : ProfileSyncService::MANUAL_START;
   }
 
-  if (!client_factory_) {
-    init_params.sync_client =
-        base::MakeUnique<browser_sync::ChromeSyncClient>(profile);
-  } else {
-    init_params.sync_client = client_factory_->Run(profile);
-  }
-
   auto pss = base::MakeUnique<ProfileSyncService>(std::move(init_params));
 
   // Will also initialize the sync client.
diff --git a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller.mm b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller.mm
index fe02247..b736557 100644
--- a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller.mm
+++ b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller.mm
@@ -43,7 +43,7 @@
    clickedOnLink:(id)link
          atIndex:(NSUInteger)charIndex {
   if (self.model)
-    self.model->OnManageLinkClicked();
+    self.model->OnNavigateToPasswordManagerAccountDashboardLinkClicked();
   [self.delegate viewShouldDismiss];
   return YES;
 }
diff --git a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
index e9ff521..79f0d32 100644
--- a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
@@ -44,7 +44,7 @@
 
 TEST_F(ConfirmationPasswordSavedViewControllerTest,
        ShouldOpenPasswordsAndDismissWhenLinkClicked) {
-  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerSettingsPage());
+  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerAccountDashboard());
   [controller().confirmationText clickedOnLink:@"about:blank" atIndex:0];
   EXPECT_TRUE([delegate() dismissed]);
 }
@@ -52,7 +52,7 @@
 TEST_F(ConfirmationPasswordSavedViewControllerTest, CloseBubbleAndHandleClick) {
   // A user may press mouse down, some navigation closes the bubble, mouse up
   // still sends the action.
-  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerSettingsPage())
+  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerAccountDashboard())
       .Times(0);
   [delegate() setModel:nil];
   [controller().confirmationText clickedOnLink:@"about:blank" atIndex:0];
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 25210a4..6ae15530 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -251,6 +251,8 @@
   // Enable navigator.connection API.
   // TODO(derekjchow): Remove this switch when enabled by default.
   { switches::kEnableNetworkInformation, "" },
+  // TODO(halliwell): Remove after fixing b/35422666.
+  { switches::kEnableUseZoomForDSF, "false" },
   { NULL, NULL },  // Termination
 };
 
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 7280c42..34924acf 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -176,7 +176,6 @@
       engine_initialized_(false),
       sync_disabled_by_admin_(false),
       is_auth_in_progress_(false),
-      local_sync_backend_folder_(init_params.local_sync_backend_folder),
       unrecoverable_error_reason_(ERROR_REASON_UNSET),
       expect_sync_configuration_aborted_(false),
       configure_status_(DataTypeManager::UNKNOWN),
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index ee7fa2f9..7048a48 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -241,7 +241,6 @@
     std::string debug_identifier;
     version_info::Channel channel = version_info::Channel::UNKNOWN;
     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner;
-    base::FilePath local_sync_backend_folder;
 
    private:
     DISALLOW_COPY_AND_ASSIGN(InitParams);
@@ -786,9 +785,6 @@
   // engine to refresh its credentials.
   bool is_auth_in_progress_;
 
-  // The location where the local sync backend stores its data.
-  base::FilePath local_sync_backend_folder_;
-
   // Information describing an unrecoverable error.
   UnrecoverableErrorReason unrecoverable_error_reason_;
   std::string unrecoverable_error_message_;
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc
index a7044ffe..935d62f 100644
--- a/components/browser_sync/profile_sync_service_unittest.cc
+++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -222,8 +222,6 @@
             ProfileSyncService::AUTO_START, builder.Build());
 
     prefs()->SetBoolean(syncer::prefs::kEnableLocalSyncBackend, true);
-    init_params.local_sync_backend_folder =
-        base::FilePath(FILE_PATH_LITERAL("dummyPath"));
     init_params.oauth2_token_service = nullptr;
     init_params.gaia_cookie_manager_service = nullptr;
 
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 935e2b1..26321ea 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -37,6 +37,11 @@
 const base::Feature kNewOmniboxAnswerTypes{"NewOmniboxAnswerTypes",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to enable the transmission of entity suggestions from GWS
+// to this client.
+const base::Feature kOmniboxEntitySuggestions{
+    "OmniboxEntitySuggestions", base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace omnibox
 
 namespace {
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 6c7ca25..7db2d031 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -25,6 +25,7 @@
 namespace omnibox {
 
 extern const base::Feature kNewOmniboxAnswerTypes;
+extern const base::Feature kOmniboxEntitySuggestions;
 
 }
 
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index 3063f7c8..d9038963 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -560,23 +560,7 @@
 }
 
 base::FilePath SyncPrefs::GetLocalSyncBackendDir() const {
-  base::FilePath local_sync_backend_folder =
-      pref_service_->GetFilePath(prefs::kLocalSyncBackendDir);
-
-#if defined(OS_WIN)
-  if (local_sync_backend_folder.empty()) {
-    // TODO(pastarmovj): Add DIR_ROAMING_USER_DATA to PathService to simplify
-    // this code and move the logic in its right place. See crbug/657810.
-    CHECK(
-        base::PathService::Get(base::DIR_APP_DATA, &local_sync_backend_folder));
-
-    // TODO(pastarmovj): Quick and dirty solution for stage 1 of crbug/694464
-    // for merging back into Chrome 57.
-    local_sync_backend_folder = local_sync_backend_folder.Append(
-        FILE_PATH_LITERAL("Google/Chrome/User Data"));
-  }
-#endif  // defined(OS_WIN)
-  return local_sync_backend_folder;
+  return pref_service_->GetFilePath(prefs::kLocalSyncBackendDir);
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/fake_sync_client.cc b/components/sync/driver/fake_sync_client.cc
index 16a46df..698c01f 100644
--- a/components/sync/driver/fake_sync_client.cc
+++ b/components/sync/driver/fake_sync_client.cc
@@ -48,6 +48,10 @@
   return &pref_service_;
 }
 
+base::FilePath FakeSyncClient::GetLocalSyncBackendFolder() {
+  return base::FilePath();
+}
+
 bookmarks::BookmarkModel* FakeSyncClient::GetBookmarkModel() {
   return nullptr;
 }
diff --git a/components/sync/driver/fake_sync_client.h b/components/sync/driver/fake_sync_client.h
index 8a8928d..a5e8b48 100644
--- a/components/sync/driver/fake_sync_client.h
+++ b/components/sync/driver/fake_sync_client.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/files/file_path.h"
 #include "base/macros.h"
 #include "components/sync/driver/sync_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -26,6 +27,7 @@
 
   SyncService* GetSyncService() override;
   PrefService* GetPrefService() override;
+  base::FilePath GetLocalSyncBackendFolder() override;
   bookmarks::BookmarkModel* GetBookmarkModel() override;
   favicon::FaviconService* GetFaviconService() override;
   history::HistoryService* GetHistoryService() override;
diff --git a/components/sync/driver/sync_client.h b/components/sync/driver/sync_client.h
index bf9ab4c..77d8f33e 100644
--- a/components/sync/driver/sync_client.h
+++ b/components/sync/driver/sync_client.h
@@ -67,6 +67,10 @@
   // Returns the current profile's preference service.
   virtual PrefService* GetPrefService() = 0;
 
+  // Returns the path to the folder used for storing the local sync database.
+  // It is only used when sync is running against a local backend.
+  virtual base::FilePath GetLocalSyncBackendFolder() = 0;
+
   // DataType specific service getters.
   virtual bookmarks::BookmarkModel* GetBookmarkModel() = 0;
   virtual favicon::FaviconService* GetFaviconService() = 0;
diff --git a/components/sync/driver/sync_service_base.cc b/components/sync/driver/sync_service_base.cc
index ae7467a2..8da8c4b 100644
--- a/components/sync/driver/sync_service_base.cc
+++ b/components/sync/driver/sync_service_base.cc
@@ -26,11 +26,6 @@
 const base::FilePath::CharType kSyncDataFolderName[] =
     FILE_PATH_LITERAL("Sync Data");
 
-#if defined(OS_WIN)
-const base::FilePath::CharType kLoopbackServerBackendFilename[] =
-    FILE_PATH_LITERAL("profile.pb");
-#endif
-
 EngineComponentsFactory::Switches EngineSwitchesFromCommandLine() {
   EngineComponentsFactory::Switches factory_switches = {
       EngineComponentsFactory::ENCRYPTION_KEYSTORE,
@@ -124,8 +119,8 @@
   // The first time we start up the engine we want to ensure we have a clean
   // directory, so delete any old one that might be there.
   params.delete_sync_data_folder = !IsFirstSetupComplete();
-  params.enable_local_sync_backend =
-      GetLocalSyncConfig(&params.local_sync_backend_folder);
+  params.enable_local_sync_backend = sync_prefs_.IsLocalSyncEnabled();
+  params.local_sync_backend_folder = sync_client_->GetLocalSyncBackendFolder();
   params.restored_key_for_bootstrapping =
       sync_prefs_.GetEncryptionBootstrapToken();
   params.restored_keystore_key_for_bootstrapping =
@@ -142,40 +137,6 @@
   engine_->Initialize(std::move(params));
 }
 
-bool SyncServiceBase::GetLocalSyncConfig(
-    base::FilePath* local_sync_backend_folder) const {
-  bool enable_local_sync_backend = false;
-  *local_sync_backend_folder = sync_prefs_.GetLocalSyncBackendDir();
-#if defined(OS_WIN)
-  enable_local_sync_backend = sync_prefs_.IsLocalSyncEnabled();
-  UMA_HISTOGRAM_BOOLEAN("Sync.Local.Enabled", enable_local_sync_backend);
-  if (local_sync_backend_folder->empty()) {
-    // TODO(pastarmovj): Add DIR_ROAMING_USER_DATA to PathService to simplify
-    // this code and move the logic in its right place. See crbug/657810.
-    if (!base::PathService::Get(base::DIR_APP_DATA,
-                                local_sync_backend_folder)) {
-      SYSLOG(WARNING) << "Local sync can not get the roaming profile folder.";
-      UMA_HISTOGRAM_BOOLEAN("Sync.Local.RoamingProfileUnavailable", false);
-      return false;
-    }
-    *local_sync_backend_folder = local_sync_backend_folder->Append(
-        FILE_PATH_LITERAL("Chrome/User Data"));
-  }
-  // This code as it is now will assume the same profile order is present on all
-  // machines, which is not a given. It is to be defined if only the Default
-  // profile should get this treatment or all profile as is the case now. The
-  // solution for now will be to assume profiles are created in the same order
-  // on all machines and in the future decide if only the Default one should be
-  // considered roamed.
-  // See http://crbug.com/674928.
-  *local_sync_backend_folder =
-      local_sync_backend_folder->Append(base_directory_.BaseName());
-  *local_sync_backend_folder =
-      local_sync_backend_folder->Append(kLoopbackServerBackendFilename);
-#endif  // defined(OS_WIN)
-  return enable_local_sync_backend;
-}
-
 void SyncServiceBase::ResetCryptoState() {
   crypto_ = base::MakeUnique<SyncServiceCrypto>(
       base::BindRepeating(&SyncServiceBase::NotifyObservers,
diff --git a/components/sync/driver/sync_service_base.h b/components/sync/driver/sync_service_base.h
index 96a6305..8b6d1f8 100644
--- a/components/sync/driver/sync_service_base.h
+++ b/components/sync/driver/sync_service_base.h
@@ -121,8 +121,6 @@
   base::ThreadChecker thread_checker_;
 
  private:
-  bool GetLocalSyncConfig(base::FilePath* local_sync_backend_folder) const;
-
   DISALLOW_COPY_AND_ASSIGN(SyncServiceBase);
 };
 
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h
index 48c5f6e..6f6a8ba5 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.h
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "components/sync/driver/sync_client.h"
@@ -39,6 +40,7 @@
   void Initialize() override;
   syncer::SyncService* GetSyncService() override;
   PrefService* GetPrefService() override;
+  base::FilePath GetLocalSyncBackendFolder() override;
   bookmarks::BookmarkModel* GetBookmarkModel() override;
   favicon::FaviconService* GetFaviconService() override;
   history::HistoryService* GetHistoryService() override;
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
index 8d7d4a5..92250fdf 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -186,6 +186,10 @@
   return browser_state_->GetPrefs();
 }
 
+base::FilePath IOSChromeSyncClient::GetLocalSyncBackendFolder() {
+  return base::FilePath();
+}
+
 bookmarks::BookmarkModel* IOSChromeSyncClient::GetBookmarkModel() {
   DCHECK_CURRENTLY_ON(web::WebThread::UI);
   return ios::BookmarkModelFactory::GetForBrowserState(browser_state_);
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index ce801b2..435b2c7 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -625,7 +625,7 @@
 // Shows the source of the current page.
 - (void)viewSource;
 #endif
-// Whether the given tab's url begins with the chrome prefix.
+// Whether the given tab's URL is an application specific URL.
 - (BOOL)isTabNativePage:(Tab*)tab;
 // Returns the view to use when animating a page in or out, positioning it to
 // fill the content area but not actually adding it to the view hierarchy.
@@ -2051,9 +2051,18 @@
   return tab;
 }
 
-// Whether the given tab's url begins with the chrome prefix.
+// Whether the given tab's URL is an application specific URL.
 - (BOOL)isTabNativePage:(Tab*)tab {
-  return tab && tab.url.SchemeIs(kChromeUIScheme);
+  web::WebState* webState = tab.webState;
+  if (!webState)
+    return NO;
+  web::NavigationManager* navigationManager = webState->GetNavigationManager();
+  if (!navigationManager)
+    return NO;
+  web::NavigationItem* visibleItem = navigationManager->GetVisibleItem();
+  if (!visibleItem)
+    return NO;
+  return web::GetWebClient()->IsAppSpecificURL(visibleItem->GetURL());
 }
 
 - (void)expectNewForegroundTab {
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 7582e36..6e3ab09 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -39,6 +39,7 @@
     "//base",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/collection_view",
+    "//ios/chrome/browser/ui/colors",
     "//ios/third_party/material_roboto_font_loader_ios",
     "//ui/base",
     "//url",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h
index 029790e6..8a81bc65 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h
@@ -43,9 +43,7 @@
 @property(nonatomic, readonly, assign) GURL articleURL;
 @property(nonatomic, copy) NSString* publisher;
 @property(nonatomic, assign) base::Time publishDate;
-
-// Whether the image is being fetched. This property is set by the delegate.
-@property(nonatomic, assign) BOOL imageBeingFetched;
+@property(nonatomic, weak) id<ContentSuggestionsArticleItemDelegate> delegate;
 
 @end
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
index 4749f4f..6ba227f7 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
@@ -5,21 +5,27 @@
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h"
 
 #include "base/time/time.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
+#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 namespace {
-const CGFloat kImageSize = 100;
+const CGFloat kImageSize = 72;
+// When updating this, make sure to update |layoutSubviews|.
 const CGFloat kStandardSpacing = 8;
 }
 
 @interface ContentSuggestionsArticleItem ()
 
 @property(nonatomic, copy) NSString* subtitle;
-@property(nonatomic, weak) id<ContentSuggestionsArticleItemDelegate> delegate;
+// Used to check if the image has already been fetched. There is no way to
+// discriminate between failed image download and nonexitent image. The article
+// tries to download the image only once.
+@property(nonatomic, assign) BOOL imageFetched;
 
 @end
 
@@ -35,7 +41,7 @@
 @synthesize publishDate = _publishDate;
 @synthesize suggestionIdentifier = _suggestionIdentifier;
 @synthesize delegate = _delegate;
-@synthesize imageBeingFetched = _imageBeingFetched;
+@synthesize imageFetched = _imageFetched;
 
 - (instancetype)initWithType:(NSInteger)type
                        title:(NSString*)title
@@ -55,12 +61,15 @@
 
 - (void)configureCell:(ContentSuggestionsArticleCell*)cell {
   [super configureCell:cell];
-  if (!self.image && !self.imageBeingFetched) {
+  if (!self.image && !self.imageFetched) {
+    self.imageFetched = YES;
+    // Fetch the image. During the fetch the cell's image should still be set to
+    // nil.
     [self.delegate loadImageForArticleItem:self];
   }
-  cell.titleLabel.text = _title;
-  cell.subtitleLabel.text = _subtitle;
-  cell.imageView.image = _image;
+  cell.titleLabel.text = self.title;
+  cell.subtitleLabel.text = self.subtitle;
+  cell.imageView.image = self.image;
   [cell setPublisherName:self.publisher date:self.publishDate];
 }
 
@@ -72,6 +81,9 @@
 
 @property(nonatomic, strong) UILabel* publisherLabel;
 
+// Applies the constraints on the elements. Called in the init.
+- (void)applyConstraints;
+
 @end
 
 @implementation ContentSuggestionsArticleCell
@@ -89,12 +101,14 @@
     _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
     _publisherLabel = [[UILabel alloc] initWithFrame:CGRectZero];
 
+    _titleLabel.numberOfLines = 2;
     _subtitleLabel.numberOfLines = 0;
     [_subtitleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh
                                       forAxis:UILayoutConstraintAxisVertical];
     [_titleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh
                                    forAxis:UILayoutConstraintAxisVertical];
-    _imageView.contentMode = UIViewContentModeScaleAspectFit;
+    _imageView.contentMode = UIViewContentModeScaleAspectFill;
+    _imageView.clipsToBounds = YES;
 
     _imageView.translatesAutoresizingMaskIntoConstraints = NO;
     _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
@@ -106,32 +120,14 @@
     [self.contentView addSubview:_subtitleLabel];
     [self.contentView addSubview:_publisherLabel];
 
-    [NSLayoutConstraint activateConstraints:@[
-      [_imageView.widthAnchor constraintLessThanOrEqualToConstant:kImageSize],
-      [_imageView.heightAnchor constraintLessThanOrEqualToConstant:kImageSize],
-      [_publisherLabel.topAnchor
-          constraintGreaterThanOrEqualToAnchor:_imageView.bottomAnchor
-                                      constant:kStandardSpacing],
-      [_publisherLabel.topAnchor
-          constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor
-                                      constant:kStandardSpacing],
-    ]];
+    _titleLabel.font = [MDCTypography subheadFont];
+    _subtitleLabel.font = [MDCTypography body1Font];
+    _publisherLabel.font = [MDCTypography captionFont];
 
-    ApplyVisualConstraints(
-        @[
-          @"H:|-[title]-[image]-|",
-          @"H:|-[text]-[image]",
-          @"V:|-[title]-[text]",
-          @"V:|-[image]",
-          @"H:|-[publish]-|",
-          @"V:[publish]-|",
-        ],
-        @{
-          @"image" : _imageView,
-          @"title" : _titleLabel,
-          @"text" : _subtitleLabel,
-          @"publish" : _publisherLabel,
-        });
+    _subtitleLabel.textColor = [[MDCPalette greyPalette] tint700];
+    _publisherLabel.textColor = [[MDCPalette greyPalette] tint700];
+
+    [self applyConstraints];
   }
   return self;
 }
@@ -158,12 +154,47 @@
   // Adjust the text label preferredMaxLayoutWidth when the parent's width
   // changes, for instance on screen rotation.
   CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
+
+  self.titleLabel.preferredMaxLayoutWidth =
+      parentWidth - self.imageView.bounds.size.width - 3 * kStandardSpacing;
   self.subtitleLabel.preferredMaxLayoutWidth =
-      parentWidth - self.imageView.bounds.size.width - 3 * 8;
+      parentWidth - self.imageView.bounds.size.width - 3 * kStandardSpacing;
 
   // Re-layout with the new preferred width to allow the label to adjust its
   // height.
   [super layoutSubviews];
 }
 
+#pragma mark - Private
+
+- (void)applyConstraints {
+  [NSLayoutConstraint activateConstraints:@[
+    [_imageView.widthAnchor constraintEqualToConstant:kImageSize],
+    [_imageView.heightAnchor constraintEqualToAnchor:_imageView.widthAnchor],
+    [_publisherLabel.topAnchor
+        constraintGreaterThanOrEqualToAnchor:_imageView.bottomAnchor
+                                    constant:kStandardSpacing],
+    [_publisherLabel.topAnchor
+        constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor
+                                    constant:kStandardSpacing],
+  ]];
+
+  ApplyVisualConstraintsWithMetrics(
+      @[
+        @"H:|-(space)-[title]-(space)-[image]-(space)-|",
+        @"H:|-(space)-[text]-(space)-[image]",
+        @"V:|-[title]-[text]",
+        @"V:|-[image]",
+        @"H:|-[publish]-|",
+        @"V:[publish]-|",
+      ],
+      @{
+        @"image" : _imageView,
+        @"title" : _titleLabel,
+        @"text" : _subtitleLabel,
+        @"publish" : _publisherLabel,
+      },
+      @{ @"space" : @(kStandardSpacing) });
+}
+
 @end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
index 60eb0ea..b8c0003 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
@@ -75,24 +75,31 @@
   EXPECT_EQ(image, cell.imageView.image);
 }
 
-// Tests that configureCell: does not call the delegate is |imageBeingFetched|
-// is YES even if there is no image.
+// Tests that configureCell: does not call the delegate if it fetched the image
+// once.
 TEST(ContentSuggestionsArticleItemTest, DontFetchImageIsImageIsBeingFetched) {
   // Setup.
   NSString* title = @"testTitle";
   NSString* subtitle = @"testSubtitle";
   GURL url = GURL("http://chromium.org");
-  id delegateMock =
-      OCMStrictProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate));
+  id niceDelegateMock =
+      OCMProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate));
   ContentSuggestionsArticleItem* item =
       [[ContentSuggestionsArticleItem alloc] initWithType:0
                                                     title:title
                                                  subtitle:subtitle
-                                                 delegate:delegateMock
+                                                 delegate:niceDelegateMock
                                                       url:url];
-  item.imageBeingFetched = YES;
+
+  OCMExpect([niceDelegateMock loadImageForArticleItem:item]);
   ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init];
   ASSERT_EQ(nil, item.image);
+  [item configureCell:cell];
+  ASSERT_OCMOCK_VERIFY(niceDelegateMock);
+
+  id strictDelegateMock =
+      OCMStrictProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate));
+  item.delegate = strictDelegateMock;
 
   // Action.
   [item configureCell:cell];
@@ -101,7 +108,6 @@
   EXPECT_EQ(nil, cell.imageView.image);
   EXPECT_EQ(title, cell.titleLabel.text);
   EXPECT_EQ(subtitle, cell.subtitleLabel.text);
-  EXPECT_OCMOCK_VERIFY(delegateMock);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
index 96a0e9c2..c0f4c13 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -153,21 +153,22 @@
   __weak ContentSuggestionsCollectionUpdater* weakSelf = self;
   __weak ContentSuggestionsArticleItem* weakArticle = articleItem;
   void (^imageFetchedCallback)(const gfx::Image&) = ^(const gfx::Image& image) {
+    if (image.IsEmpty()) {
+      return;
+    }
+
     ContentSuggestionsCollectionUpdater* strongSelf = weakSelf;
     ContentSuggestionsArticleItem* strongArticle = weakArticle;
     if (!strongSelf || !strongArticle) {
       return;
     }
 
-    strongArticle.imageBeingFetched = NO;
     strongArticle.image = image.CopyUIImage();
     [strongSelf.collectionViewController
         reconfigureCellsForItems:@[ strongArticle ]
          inSectionWithIdentifier:sectionIdentifier];
   };
 
-  articleItem.imageBeingFetched = YES;
-
   [self.dataSource.imageFetcher
       fetchImageForSuggestion:articleItem.suggestionIdentifier
                      callback:imageFetchedCallback];
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
index dff7d74..360521e9 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
@@ -46,7 +46,6 @@
 // the color). |spaceBeforeCaret| controls whether a space should be added
 // between the image and the caret.
 - (void)attachIconNamed:(NSString*)iconName
-     accessibilityLabel:(NSString*)accessibilityLabel
                toString:(NSMutableAttributedString*)instructionString
               withCaret:(NSMutableAttributedString*)caret
        spaceBeforeCaret:(BOOL)spaceBeforeCaret
@@ -106,18 +105,23 @@
 
     NSMutableAttributedString* instructionString =
         [[NSMutableAttributedString alloc] init];
+    NSString* accessibilityInstructionString = @":";
 
     // Add the images inside the string.
     if (IsCompact()) {
       // If the device has a compact display the share menu is accessed from the
       // toolbar menu. If it is expanded, the share menu is directly accessible.
       [self attachIconNamed:kToolbarMenuIcon
-          accessibilityLabel:l10n_util::GetNSString(IDS_IOS_TOOLBAR_SETTINGS)
                     toString:instructionString
                    withCaret:caret
             spaceBeforeCaret:NO
                       offset:iconOffset
              imageAttributes:textAttributes];
+
+      accessibilityInstructionString = [[accessibilityInstructionString
+          stringByAppendingString:l10n_util::GetNSString(
+                                      IDS_IOS_TOOLBAR_SETTINGS)]
+          stringByAppendingString:@", "];
     }
 
     // Add a space before the share icon.
@@ -127,30 +131,43 @@
                                        attributes:instructionAttributes]];
 
     [self attachIconNamed:kShareMenuIcon
-        accessibilityLabel:l10n_util::GetNSString(IDS_IOS_TOOLS_MENU_SHARE)
                   toString:instructionString
                  withCaret:caret
           spaceBeforeCaret:YES
                     offset:iconOffset
            imageAttributes:textAttributes];
 
+    accessibilityInstructionString = [[accessibilityInstructionString
+        stringByAppendingString:l10n_util::GetNSString(
+                                    IDS_IOS_TOOLS_MENU_SHARE)]
+        stringByAppendingString:@", "];
+
     // Add the "Read Later" string.
     NSAttributedString* shareMenuAction =
         [[NSAttributedString alloc] initWithString:readLater
                                         attributes:instructionAttributes];
     [instructionString appendAttributedString:shareMenuAction];
+    accessibilityInstructionString =
+        [accessibilityInstructionString stringByAppendingString:readLater];
 
+    // Marker
     NSRange iconRange =
         [[baseAttributedString string] rangeOfString:kOpenShareMarker];
     DCHECK(iconRange.location != NSNotFound);
     [baseAttributedString replaceCharactersInRange:iconRange
                               withAttributedString:instructionString];
+    NSString* accessibilityLabel =
+        l10n_util::GetNSString(IDS_IOS_READING_LIST_EMPTY_MESSAGE);
+    accessibilityLabel = [accessibilityLabel
+        stringByReplacingOccurrencesOfString:kOpenShareMarker
+                                  withString:accessibilityInstructionString];
 
     // Attach to the label.
     UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];
     label.attributedText = baseAttributedString;
     label.numberOfLines = 0;
     label.textAlignment = NSTextAlignmentCenter;
+    label.accessibilityLabel = accessibilityLabel;
     [label setTranslatesAutoresizingMaskIntoConstraints:NO];
     [self addSubview:label];
 
@@ -165,7 +182,6 @@
 }
 
 - (void)attachIconNamed:(NSString*)iconName
-     accessibilityLabel:(NSString*)accessibilityLabel
                toString:(NSMutableAttributedString*)instructionString
               withCaret:(NSMutableAttributedString*)caret
        spaceBeforeCaret:(BOOL)spaceBeforeCaret
@@ -179,7 +195,6 @@
   NSTextAttachment* toolbarIcon = [[NSTextAttachment alloc] init];
   toolbarIcon.image = [[UIImage imageNamed:iconName]
       imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
-  toolbarIcon.image.accessibilityLabel = accessibilityLabel;
   toolbarIcon.bounds = CGRectMake(0, iconOffset, kIconSize, kIconSize);
   [instructionString
       appendAttributedString:[NSAttributedString
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_toolbar.mm b/ios/chrome/browser/ui/reading_list/reading_list_toolbar.mm
index 1ccd653..c2b42ba 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_toolbar.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_toolbar.mm
@@ -38,19 +38,21 @@
 @property(nonatomic, strong) UIView* editButtonContainer;
 // Button that displays "Delete".
 @property(nonatomic, strong) UIButton* deleteButton;
+@property(nonatomic, strong) UIView* deleteButtonContainer;
 // Button that displays "Delete All Read".
 @property(nonatomic, strong) UIButton* deleteAllButton;
+@property(nonatomic, strong) UIView* deleteAllButtonContainer;
 // Button that displays "Cancel".
 @property(nonatomic, strong) UIButton* cancelButton;
+@property(nonatomic, strong) UIView* cancelButtonContainer;
 // Button that displays the mark options.
 @property(nonatomic, strong) UIButton* markButton;
+@property(nonatomic, strong) UIView* markButtonContainer;
 // Stack view for arranging the buttons.
 @property(nonatomic, strong) UIStackView* stackView;
 
 // Creates a button with a |title| and a style according to |destructive|.
-- (UIButton*)buttonWithText:(NSString*)title
-                destructive:(BOOL)isDestructive
-                positioning:(ButtonPositioning)position;
+- (UIButton*)buttonWithText:(NSString*)title destructive:(BOOL)isDestructive;
 // Set the mark button label to |text|.
 - (void)setMarkButtonText:(NSString*)text;
 // Updates the button labels to match an empty selection.
@@ -69,41 +71,93 @@
 
 @synthesize editButtonContainer = _editButtonContainer;
 @synthesize deleteButton = _deleteButton;
+@synthesize deleteButtonContainer = _deleteButtonContainer;
 @synthesize deleteAllButton = _deleteAllButton;
+@synthesize deleteAllButtonContainer = _deleteAllButtonContainer;
 @synthesize cancelButton = _cancelButton;
+@synthesize cancelButtonContainer = _cancelButtonContainer;
 @synthesize stackView = _stackView;
 @synthesize markButton = _markButton;
+@synthesize markButtonContainer = _markButtonContainer;
 @synthesize state = _state;
 @synthesize heightDelegate = _heightDelegate;
 
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    UIButton* editButton = [self
-        buttonWithText:l10n_util::GetNSString(IDS_IOS_READING_LIST_EDIT_BUTTON)
-           destructive:NO
-           positioning:Trailing];
+    NSDictionary* views = nil;
+    NSArray* constraints = nil;
 
     _deleteButton = [self buttonWithText:l10n_util::GetNSString(
                                              IDS_IOS_READING_LIST_DELETE_BUTTON)
-                             destructive:YES
-                             positioning:Leading];
+                             destructive:YES];
+    _deleteButton.translatesAutoresizingMaskIntoConstraints = NO;
+    _deleteButtonContainer = [[UIView alloc] init];
+    [_deleteButtonContainer addSubview:_deleteButton];
+    views = @{ @"button" : _deleteButton };
+    constraints = @[ @"V:|[button]|", @"H:|[button]" ];
+    ApplyVisualConstraints(constraints, views);
+    [_deleteButton.trailingAnchor
+        constraintLessThanOrEqualToAnchor:_deleteButtonContainer.trailingAnchor]
+        .active = YES;
 
     _deleteAllButton =
         [self buttonWithText:l10n_util::GetNSString(
                                  IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON)
-                 destructive:YES
-                 positioning:Leading];
+                 destructive:YES];
+    _deleteAllButton.translatesAutoresizingMaskIntoConstraints = NO;
+    _deleteAllButtonContainer = [[UIView alloc] init];
+    [_deleteAllButtonContainer addSubview:_deleteAllButton];
+    views = @{ @"button" : _deleteAllButton };
+    constraints = @[ @"V:|[button]|", @"H:|[button]" ];
+    ApplyVisualConstraints(constraints, views);
+    [_deleteAllButton.trailingAnchor
+        constraintLessThanOrEqualToAnchor:_deleteAllButtonContainer
+                                              .trailingAnchor]
+        .active = YES;
 
     _markButton = [self buttonWithText:l10n_util::GetNSString(
                                            IDS_IOS_READING_LIST_MARK_ALL_BUTTON)
-                           destructive:NO
-                           positioning:Centered];
+                           destructive:NO];
+    _markButton.translatesAutoresizingMaskIntoConstraints = NO;
+    _markButtonContainer = [[UIView alloc] init];
+    [_markButtonContainer addSubview:_markButton];
+    views = @{ @"button" : _markButton };
+    constraints = @[ @"V:|[button]|" ];
+    ApplyVisualConstraints(constraints, views);
+    [_markButton.centerXAnchor
+        constraintEqualToAnchor:_markButtonContainer.centerXAnchor]
+        .active = YES;
+    [_markButton.trailingAnchor
+        constraintLessThanOrEqualToAnchor:_markButtonContainer.trailingAnchor]
+        .active = YES;
+    [_markButton.leadingAnchor
+        constraintGreaterThanOrEqualToAnchor:_markButtonContainer.leadingAnchor]
+        .active = YES;
 
     _cancelButton = [self buttonWithText:l10n_util::GetNSString(
                                              IDS_IOS_READING_LIST_CANCEL_BUTTON)
-                             destructive:NO
-                             positioning:Trailing];
+                             destructive:NO];
+    _cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
+    _cancelButtonContainer = [[UIView alloc] init];
+    [_cancelButtonContainer addSubview:_cancelButton];
+    views = @{ @"button" : _cancelButton };
+    constraints = @[ @"V:|[button]|", @"H:[button]|" ];
+    ApplyVisualConstraints(constraints, views);
+    [_cancelButton.leadingAnchor
+        constraintGreaterThanOrEqualToAnchor:_cancelButtonContainer
+                                                 .leadingAnchor]
+        .active = YES;
+
+    UIButton* editButton = [self
+        buttonWithText:l10n_util::GetNSString(IDS_IOS_READING_LIST_EDIT_BUTTON)
+           destructive:NO];
+    editButton.translatesAutoresizingMaskIntoConstraints = NO;
+    _editButtonContainer = [[UIView alloc] initWithFrame:CGRectZero];
+    [_editButtonContainer addSubview:editButton];
+    views = @{ @"button" : editButton };
+    constraints = @[ @"V:|[button]|", @"H:[button]|" ];
+    ApplyVisualConstraints(constraints, views);
 
     [editButton addTarget:nil
                    action:@selector(enterEditingModePressed)
@@ -125,16 +179,9 @@
                       action:@selector(exitEditingModePressed)
             forControlEvents:UIControlEventTouchUpInside];
 
-    _editButtonContainer = [[UIView alloc] initWithFrame:CGRectZero];
-    [_editButtonContainer addSubview:editButton];
-    editButton.translatesAutoresizingMaskIntoConstraints = NO;
-    NSDictionary* views = @{ @"button" : editButton };
-    NSArray* constraints = @[ @"V:|[button]|", @"H:[button]|" ];
-    ApplyVisualConstraints(constraints, views);
-
     _stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
-      _editButtonContainer, _deleteButton, _deleteAllButton, _markButton,
-      _cancelButton
+      _editButtonContainer, _deleteButtonContainer, _deleteAllButtonContainer,
+      _markButtonContainer, _cancelButtonContainer
     ]];
     _stackView.axis = UILayoutConstraintAxisHorizontal;
     _stackView.alignment = UIStackViewAlignmentFill;
@@ -159,10 +206,10 @@
 
 - (void)setEditing:(BOOL)editing {
   self.editButtonContainer.hidden = editing;
-  self.deleteButton.hidden = YES;
-  self.deleteAllButton.hidden = !editing;
-  self.cancelButton.hidden = !editing;
-  self.markButton.hidden = !editing;
+  self.deleteButtonContainer.hidden = YES;
+  self.deleteAllButtonContainer.hidden = !editing;
+  self.cancelButtonContainer.hidden = !editing;
+  self.markButtonContainer.hidden = !editing;
 
   [self updateHeight];
 }
@@ -231,9 +278,7 @@
                               IDS_IOS_READING_LIST_MARK_BUTTON)];
 }
 
-- (UIButton*)buttonWithText:(NSString*)title
-                destructive:(BOOL)isDestructive
-                positioning:(ButtonPositioning)position {
+- (UIButton*)buttonWithText:(NSString*)title destructive:(BOOL)isDestructive {
   UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
   button.contentEdgeInsets = UIEdgeInsetsMake(0, 8, 0, 8);
   [button setTitle:title forState:UIControlStateNormal];
@@ -251,31 +296,7 @@
   [[button titleLabel]
       setFont:[[MDCTypography fontLoader] regularFontOfSize:14]];
 
-  UIControlContentHorizontalAlignment horizontalAlignement;
-
-  switch (position) {
-    case Leading:
-      if (UseRTLLayout()) {
-        horizontalAlignement = UIControlContentHorizontalAlignmentRight;
-      } else {
-        horizontalAlignement = UIControlContentHorizontalAlignmentLeft;
-      }
-      break;
-
-    case Centered:
-      horizontalAlignement = UIControlContentHorizontalAlignmentCenter;
-      break;
-
-    case Trailing:
-      if (UseRTLLayout()) {
-        horizontalAlignement = UIControlContentHorizontalAlignmentLeft;
-      } else {
-        horizontalAlignement = UIControlContentHorizontalAlignmentRight;
-      }
-      break;
-  }
-
-  button.contentHorizontalAlignment = horizontalAlignement;
+  button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
   button.titleLabel.textAlignment = NSTextAlignmentCenter;
 
   return button;
@@ -288,7 +309,7 @@
 - (void)updateHeight {
   for (UIButton* button in
        @[ _deleteButton, _deleteAllButton, _markButton, _cancelButton ]) {
-    if (!button.hidden) {
+    if (!button.superview.hidden) {
       CGFloat rect = [button.titleLabel.text
                          cr_pixelAlignedSizeWithFont:button.titleLabel.font]
                          .width;
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index e98358fb..f0ab24a7 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -5625,7 +5625,9 @@
   ASSERT_TRUE(altsvc_vector.empty());
 }
 
-TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameWithEmptyOriginOnZeroStream) {
+// An ALTSVC frame on stream 0 with empty origin MUST be ignored.
+// (RFC 7838 Section 4)
+TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameWithEmptyOriginOnStreamZero) {
   SpdyAltSvcIR altsvc_ir(0);
   altsvc_ir.add_altsvc(alternative_service_);
   AddSocketData(altsvc_ir);
@@ -5644,6 +5646,29 @@
   ASSERT_TRUE(altsvc_vector.empty());
 }
 
+// An ALTSVC frame on a stream other than stream 0 with non-empty origin MUST be
+// ignored.  (RFC 7838 Section 4)
+TEST_F(AltSvcFrameTest,
+       DoNotProcessAltSvcFrameWithNonEmptyOriginOnNonZeroStream) {
+  SpdyAltSvcIR altsvc_ir(1);
+  altsvc_ir.add_altsvc(alternative_service_);
+  altsvc_ir.set_origin("https://mail.example.org");
+  AddSocketData(altsvc_ir);
+  AddSSLSocketData();
+
+  CreateNetworkSession();
+  CreateSecureSpdySession();
+
+  base::RunLoop().RunUntilIdle();
+
+  const url::SchemeHostPort session_origin("https", test_url_.host(),
+                                           test_url_.EffectiveIntPort());
+  AlternativeServiceVector altsvc_vector =
+      spdy_session_pool_->http_server_properties()->GetAlternativeServices(
+          session_origin);
+  ASSERT_TRUE(altsvc_vector.empty());
+}
+
 TEST_F(AltSvcFrameTest, ProcessAltSvcFrameOnActiveStream) {
   SpdyAltSvcIR altsvc_ir(1);
   altsvc_ir.add_altsvc(alternative_service_);
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
index b86dd26..db00f7da 100755
--- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
+++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -18,6 +18,11 @@
 NONPROPERTY_FIELDS = set([
     # Style can not be shared.
     'unique',
+    # Whether this style is affected by these pseudo-classes.
+    'affectedByFocus',
+    'affectedByHover',
+    'affectedByActive',
+    'affectedByDrag',
 ])
 
 
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
index 4bb1437..621e4e3 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -38,6 +38,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <memory>
 #include "core/CSSPropertyNames.h"
 #include "core/CSSValueKeywords.h"
 #include "core/StyleBuilderFunctions.h"
@@ -53,6 +54,7 @@
 #include "core/css/CSSPendingSubstitutionValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSPropertyMetadata.h"
+#include "core/css/CSSValueIDMappings.h"
 #include "core/css/CSSVariableReferenceValue.h"
 #include "core/css/PropertyRegistration.h"
 #include "core/css/PropertyRegistry.h"
@@ -79,7 +81,6 @@
 #include "wtf/PtrUtil.h"
 #include "wtf/StdLibExtras.h"
 #include "wtf/Vector.h"
-#include <memory>
 
 namespace blink {
 
@@ -759,11 +760,8 @@
           ContentData::create(state.styleImage(CSSPropertyContent, *item));
     } else if (item->isCounterValue()) {
       const CSSCounterValue* counterValue = toCSSCounterValue(item.get());
-      EListStyleType listStyleType = EListStyleType::kNone;
-      CSSValueID listStyleIdent = counterValue->listStyle();
-      if (listStyleIdent != CSSValueNone)
-        listStyleType =
-            static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
+      const auto listStyleType =
+          cssValueIDToPlatformEnum<EListStyleType>(counterValue->listStyle());
       std::unique_ptr<CounterContent> counter =
           WTF::wrapUnique(new CounterContent(
               AtomicString(counterValue->identifier()), listStyleType,
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 3903fb7..71a827109 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -273,11 +273,6 @@
 
     unsigned m_emptyState : 1;
 
-    unsigned m_affectedByFocus : 1;
-    unsigned m_affectedByHover : 1;
-    unsigned m_affectedByActive : 1;
-    unsigned m_affectedByDrag : 1;
-
     // 64 bits
 
     unsigned m_isLink : 1;
@@ -310,10 +305,6 @@
     m_nonInheritedData.m_unique = false;
     m_nonInheritedData.m_emptyState = false;
     m_nonInheritedData.m_hasViewportUnits = false;
-    m_nonInheritedData.m_affectedByFocus = false;
-    m_nonInheritedData.m_affectedByHover = false;
-    m_nonInheritedData.m_affectedByActive = false;
-    m_nonInheritedData.m_affectedByDrag = false;
     m_nonInheritedData.m_isLink = false;
     m_nonInheritedData.m_hasRemUnits = false;
   }
@@ -2457,20 +2448,6 @@
   bool hasRemUnits() const { return m_nonInheritedData.m_hasRemUnits; }
   void setHasRemUnits() const { m_nonInheritedData.m_hasRemUnits = true; }
 
-  bool affectedByFocus() const { return m_nonInheritedData.m_affectedByFocus; }
-  void setAffectedByFocus() { m_nonInheritedData.m_affectedByFocus = true; }
-
-  bool affectedByHover() const { return m_nonInheritedData.m_affectedByHover; }
-  void setAffectedByHover() { m_nonInheritedData.m_affectedByHover = true; }
-
-  bool affectedByActive() const {
-    return m_nonInheritedData.m_affectedByActive;
-  }
-  void setAffectedByActive() { m_nonInheritedData.m_affectedByActive = true; }
-
-  bool affectedByDrag() const { return m_nonInheritedData.m_affectedByDrag; }
-  void setAffectedByDrag() { m_nonInheritedData.m_affectedByDrag = true; }
-
   bool emptyState() const { return m_nonInheritedData.m_emptyState; }
   void setEmptyState(bool b) {
     setUnique();
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
index 742f845..b534f51 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -282,8 +282,8 @@
   base::TimeTicks next_delayed_task =
       main_thread_only().delayed_incoming_queue.top().delayed_run_time;
   if (next_delayed_task == delayed_run_time && IsQueueEnabled()) {
-    main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time,
-                                                        now);
+    main_thread_only().time_domain->ScheduleDelayedWork(
+        this, {delayed_run_time, pending_task.sequence_num}, now);
   }
 
   TraceQueueSize(false);
@@ -414,8 +414,8 @@
   return main_thread_only().delayed_incoming_queue.top().delayed_run_time;
 }
 
-base::Optional<base::TimeTicks> TaskQueueImpl::WakeUpForDelayedWork(
-    LazyNow* lazy_now) {
+base::Optional<TaskQueueImpl::DelayedWakeUp>
+TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) {
   // Enqueue all delayed tasks that should be running now, skipping any that
   // have been canceled.
   while (!main_thread_only().delayed_incoming_queue.empty()) {
@@ -434,8 +434,11 @@
   }
 
   // Make sure the next wake up is scheduled.
-  if (!main_thread_only().delayed_incoming_queue.empty())
-    return main_thread_only().delayed_incoming_queue.top().delayed_run_time;
+  if (!main_thread_only().delayed_incoming_queue.empty()) {
+    return DelayedWakeUp{
+        main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+        main_thread_only().delayed_incoming_queue.top().sequence_num};
+  }
 
   return base::nullopt;
 }
@@ -587,7 +590,9 @@
 
   if (IsQueueEnabled() && !main_thread_only().delayed_incoming_queue.empty()) {
     time_domain->ScheduleDelayedWork(
-        this, main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+        this,
+        {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+         main_thread_only().delayed_incoming_queue.top().sequence_num},
         time_domain->Now());
   }
 }
@@ -817,7 +822,8 @@
     if (!main_thread_only().delayed_incoming_queue.empty()) {
       main_thread_only().time_domain->ScheduleDelayedWork(
           this,
-          main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+          {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+           main_thread_only().delayed_incoming_queue.top().sequence_num},
           main_thread_only().time_domain->Now());
     }
     // Note the selector calls TaskQueueManager::OnTaskQueueEnabled which posts
@@ -864,7 +870,8 @@
     if (IsQueueEnabled()) {
       main_thread_only().time_domain->ScheduleDelayedWork(
           this,
-          main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+          {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
+           main_thread_only().delayed_incoming_queue.top().sequence_num},
           main_thread_only().time_domain->Now());
     }
   }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
index 8381157..79503356b 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -111,6 +111,21 @@
     EnqueueOrder enqueue_order_;
   };
 
+  // Represents a time at which a task wants to run. Tasks scheduled for the
+  // same point in time will be ordered by their sequence numbers.
+  struct DelayedWakeUp {
+    base::TimeTicks time;
+    int sequence_num;
+
+    bool operator<=(const DelayedWakeUp& other) const {
+      if (time == other.time) {
+        DCHECK_NE(sequence_num, other.sequence_num);
+        return (sequence_num - other.sequence_num) < 0;
+      }
+      return time < other.time;
+    }
+  };
+
   // TaskQueue implementation.
   void UnregisterTaskQueue() override;
   bool RunsTasksOnCurrentThread() const override;
@@ -177,9 +192,9 @@
   }
 
   // Enqueues any delayed tasks which should be run now on the
-  // |delayed_work_queue|. Returns the deadline if a subsequent wakeup is
-  // required. Must be called from the main thread.
-  base::Optional<base::TimeTicks> WakeUpForDelayedWork(LazyNow* lazy_now);
+  // |delayed_work_queue|. Returns the subsequent wakeup that is required, if
+  // any. Must be called from the main thread.
+  base::Optional<DelayedWakeUp> WakeUpForDelayedWork(LazyNow* lazy_now);
 
   base::TimeTicks scheduled_time_domain_wakeup() const {
     return main_thread_only().scheduled_time_domain_wakeup;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
index 9f8c909..5c68b3d 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
@@ -31,9 +31,10 @@
   CancelDelayedWork(queue);
 }
 
-void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
-                                     base::TimeTicks delayed_run_time,
-                                     base::TimeTicks now) {
+void TimeDomain::ScheduleDelayedWork(
+    internal::TaskQueueImpl* queue,
+    internal::TaskQueueImpl::DelayedWakeUp wake_up,
+    base::TimeTicks now) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
   DCHECK_EQ(queue->GetTimeDomain(), this);
   DCHECK(queue->IsQueueEnabled());
@@ -43,18 +44,17 @@
     DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks());
 
     // O(log n)
-    delayed_wakeup_queue_.ChangeKey(queue->heap_handle(),
-                                    {delayed_run_time, queue});
+    delayed_wakeup_queue_.ChangeKey(queue->heap_handle(), {wake_up, queue});
   } else {
     // O(log n)
-    delayed_wakeup_queue_.insert({delayed_run_time, queue});
+    delayed_wakeup_queue_.insert({wake_up, queue});
   }
 
-  queue->set_scheduled_time_domain_wakeup(delayed_run_time);
+  queue->set_scheduled_time_domain_wakeup(wake_up.time);
 
   // If |queue| is the first wakeup then request the wakeup.
   if (delayed_wakeup_queue_.min().queue == queue)
-    RequestWakeupAt(now, delayed_run_time);
+    RequestWakeupAt(now, wake_up.time);
 
   if (observer_)
     observer_->OnTimeDomainHasDelayedWork(queue);
@@ -75,34 +75,34 @@
 
   DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks());
   DCHECK(!delayed_wakeup_queue_.empty());
-  base::TimeTicks prev_first_wakeup = delayed_wakeup_queue_.min().time;
+  base::TimeTicks prev_first_wakeup = delayed_wakeup_queue_.min().wake_up.time;
 
   // O(log n)
   delayed_wakeup_queue_.erase(queue->heap_handle());
 
   if (delayed_wakeup_queue_.empty()) {
     CancelWakeupAt(prev_first_wakeup);
-  } else if (prev_first_wakeup != delayed_wakeup_queue_.min().time) {
+  } else if (prev_first_wakeup != delayed_wakeup_queue_.min().wake_up.time) {
     CancelWakeupAt(prev_first_wakeup);
-    RequestWakeupAt(Now(), delayed_wakeup_queue_.min().time);
+    RequestWakeupAt(Now(), delayed_wakeup_queue_.min().wake_up.time);
   }
 }
 
 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
-  // Wake up any queues with pending delayed work.  Note std::multipmap stores
+  // Wake up any queues with pending delayed work.  Note std::multimap stores
   // the elements sorted by key, so the begin() iterator points to the earliest
   // queue to wakeup.
   while (!delayed_wakeup_queue_.empty() &&
-         delayed_wakeup_queue_.min().time <= lazy_now->Now()) {
+         delayed_wakeup_queue_.min().wake_up.time <= lazy_now->Now()) {
     internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue;
-    base::Optional<base::TimeTicks> next_wakeup =
+    base::Optional<internal::TaskQueueImpl::DelayedWakeUp> next_wake_up =
         queue->WakeUpForDelayedWork(lazy_now);
 
-    if (next_wakeup) {
+    if (next_wake_up) {
       // O(log n)
-      delayed_wakeup_queue_.ReplaceMin({next_wakeup.value(), queue});
-      queue->set_scheduled_time_domain_wakeup(next_wakeup.value());
+      delayed_wakeup_queue_.ReplaceMin({*next_wake_up, queue});
+      queue->set_scheduled_time_domain_wakeup(next_wake_up->time);
     } else {
       // O(log n)
       delayed_wakeup_queue_.pop();
@@ -116,7 +116,7 @@
   if (delayed_wakeup_queue_.empty())
     return false;
 
-  *out_time = delayed_wakeup_queue_.min().time;
+  *out_time = delayed_wakeup_queue_.min().wake_up.time;
   return true;
 }
 
@@ -134,7 +134,7 @@
   state->SetString("name", GetName());
   state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size());
   if (!delayed_wakeup_queue_.empty()) {
-    base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now();
+    base::TimeDelta delay = delayed_wakeup_queue_.min().wake_up.time - Now();
     state->SetDouble("next_delay_ms", delay.InMillisecondsF());
   }
   AsValueIntoInternal(state);
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.h b/third_party/WebKit/Source/platform/scheduler/base/time_domain.h
index c2b828a8b..4c96597 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.h
@@ -94,7 +94,7 @@
   // TimeDomain reaches |delayed_run_time|.  This supersedes any previously
   // registered wakeup for |queue|.
   void ScheduleDelayedWork(internal::TaskQueueImpl* queue,
-                           base::TimeTicks delayed_run_time,
+                           internal::TaskQueueImpl::DelayedWakeUp wake_up,
                            base::TimeTicks now);
 
   // Cancels any scheduled calls to TaskQueueImpl::WakeUpForDelayedWork for
@@ -137,14 +137,12 @@
   }
 
  private:
-  struct DelayedWakeup {
-    base::TimeTicks time;
+  struct ScheduledDelayedWakeUp {
+    internal::TaskQueueImpl::DelayedWakeUp wake_up;
     internal::TaskQueueImpl* queue;
 
-    bool operator<=(const DelayedWakeup& other) const {
-      if (time == other.time)
-        return queue <= other.queue;
-      return time < other.time;
+    bool operator<=(const ScheduledDelayedWakeUp& other) const {
+      return wake_up <= other.wake_up;
     }
 
     void SetHeapHandle(HeapHandle handle) {
@@ -161,7 +159,7 @@
     }
   };
 
-  IntrusiveHeap<DelayedWakeup> delayed_wakeup_queue_;
+  IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wakeup_queue_;
 
   Observer* const observer_;  // NOT OWNED.
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
index c8b6acb..1c47328 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
@@ -94,7 +94,7 @@
   base::TimeTicks delayed_runtime = time_domain_->Now() + delay;
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, delayed_runtime));
   base::TimeTicks now = time_domain_->Now();
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {now + delay, 0}, now);
 
   base::TimeTicks next_scheduled_runtime;
   EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime));
@@ -115,7 +115,8 @@
   base::TimeTicks delayed_runtime2 = time_domain_->Now() + delay2;
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, delayed_runtime1));
   base::TimeTicks now = time_domain_->Now();
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {delayed_runtime1, 0},
+                                    now);
 
   base::TimeTicks next_scheduled_runtime;
   EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime));
@@ -126,7 +127,8 @@
   // Now scheduler a later wakeup, which should replace the previously requested
   // one.
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, delayed_runtime2));
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {delayed_runtime2, 0},
+                                    now);
 
   EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime));
   EXPECT_EQ(delayed_runtime2, next_scheduled_runtime);
@@ -159,19 +161,19 @@
   // RequestWakeupAt should always be called if there are no other wakeups.
   base::TimeTicks now = time_domain_->Now();
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, now + delay1));
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {now + delay1, 0}, now);
 
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   // RequestWakeupAt should not be called when scheduling later tasks.
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, _)).Times(0);
-  time_domain_->ScheduleDelayedWork(task_queue2.get(), now + delay2, now);
-  time_domain_->ScheduleDelayedWork(task_queue3.get(), now + delay3, now);
+  time_domain_->ScheduleDelayedWork(task_queue2.get(), {now + delay2, 0}, now);
+  time_domain_->ScheduleDelayedWork(task_queue3.get(), {now + delay3, 0}, now);
 
   // RequestWakeupAt should be called when scheduling earlier tasks.
   Mock::VerifyAndClearExpectations(time_domain_.get());
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, now + delay4));
-  time_domain_->ScheduleDelayedWork(task_queue4.get(), now + delay4, now);
+  time_domain_->ScheduleDelayedWork(task_queue4.get(), {now + delay4, 0}, now);
 
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
@@ -191,9 +193,9 @@
   base::TimeTicks now = time_domain_->Now();
   base::TimeTicks wakeup1 = now + base::TimeDelta::FromMilliseconds(10);
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, wakeup1)).Times(1);
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), wakeup1, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {wakeup1, 0}, now);
   base::TimeTicks wakeup2 = now + base::TimeDelta::FromMilliseconds(100);
-  time_domain_->ScheduleDelayedWork(task_queue2_.get(), wakeup2, now);
+  time_domain_->ScheduleDelayedWork(task_queue2_.get(), {wakeup2, 0}, now);
 
   TaskQueue* next_task_queue;
   EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
@@ -222,7 +224,8 @@
   base::TimeTicks now = time_domain_->Now();
   base::TimeTicks delayed_runtime = now + delay;
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, delayed_runtime));
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {delayed_runtime, 0},
+                                    now);
 
   base::TimeTicks next_run_time;
   ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time));
@@ -239,12 +242,42 @@
   ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time));
 }
 
+TEST_F(TimeDomainTest, WakeupReadyDelayedQueuesWithIdenticalRuntimes) {
+  int sequence_num = 0;
+  base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50);
+  base::TimeTicks now = time_domain_->Now();
+  base::TimeTicks delayed_runtime = now + delay;
+  EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, delayed_runtime));
+  EXPECT_CALL(*time_domain_.get(), CancelWakeupAt(delayed_runtime));
+
+  scoped_refptr<internal::TaskQueueImpl> task_queue2 = make_scoped_refptr(
+      new internal::TaskQueueImpl(nullptr, time_domain_.get(),
+                                  TaskQueue::Spec(TaskQueue::QueueType::TEST),
+                                  "test.category", "test.category"));
+
+  time_domain_->ScheduleDelayedWork(task_queue2.get(),
+                                    {delayed_runtime, ++sequence_num}, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(),
+                                    {delayed_runtime, ++sequence_num}, now);
+
+  LazyNow lazy_now = time_domain_->CreateLazyNow();
+  time_domain_->WakeupReadyDelayedQueues(&lazy_now);
+
+  // The second task queue should wake up first since it has a lower sequence
+  // number.
+  TaskQueue* next_task_queue;
+  EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
+  EXPECT_EQ(task_queue2.get(), next_task_queue);
+
+  task_queue2->UnregisterTaskQueue();
+}
+
 TEST_F(TimeDomainTest, CancelDelayedWork) {
   base::TimeTicks now = time_domain_->Now();
   base::TimeTicks run_time = now + base::TimeDelta::FromMilliseconds(20);
 
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, run_time));
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {run_time, 0}, now);
 
   TaskQueue* next_task_queue;
   EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
@@ -265,11 +298,11 @@
   base::TimeTicks run_time1 = now + base::TimeDelta::FromMilliseconds(20);
   base::TimeTicks run_time2 = now + base::TimeDelta::FromMilliseconds(40);
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, run_time1));
-  time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time1, now);
+  time_domain_->ScheduleDelayedWork(task_queue_.get(), {run_time1, 0}, now);
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, _)).Times(0);
-  time_domain_->ScheduleDelayedWork(task_queue2.get(), run_time2, now);
+  time_domain_->ScheduleDelayedWork(task_queue2.get(), {run_time2, 0}, now);
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   TaskQueue* next_task_queue;
@@ -327,7 +360,7 @@
   EXPECT_CALL(*time_domain_.get(), RequestWakeupAt(_, _));
   base::TimeTicks now = time_domain_->Now();
   time_domain_->ScheduleDelayedWork(
-      task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now);
+      task_queue_.get(), {now + base::TimeDelta::FromMilliseconds(10), 0}, now);
 }
 
 }  // namespace scheduler
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 4696764..27aaf12 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -98498,6 +98498,7 @@
   <int value="609112512" label="touch-selection-strategy"/>
   <int value="610545308" label="enable-potentially-annoying-security-features"/>
   <int value="624317932" label="print-pdf-as-image"/>
+  <int value="624368375" label="OmniboxEntitySuggestions:enabled"/>
   <int value="625273056" label="disable-boot-animation"/>
   <int value="628302973" label="NTPSnippets:enabled"/>
   <int value="630947363" label="touch-events"/>
@@ -98610,6 +98611,7 @@
   <int value="1114629582" label="enable-floating-virtual-keyboard"/>
   <int value="1118109174" label="enable-launcher-search-provider-api"/>
   <int value="1127183523" label="PassiveEventListenersDueToFling:enabled"/>
+  <int value="1127427821" label="OmniboxEntitySuggestions:disabled"/>
   <int value="1129888794" label="ash-touch-hud"/>
   <int value="1133635187" label="force-gpu-rasterization"/>
   <int value="1139226452" label="enable-nacl-debug"/>