diff --git a/DEPS b/DEPS
index 7aeee83..44a9e76 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '5ec87e41b4b216167e449f2bf477459e93d72907',
+  'v8_revision': 'f914089eae2ea692c6ae29d1ee4d1fe8aea59629',
   # 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.
@@ -238,7 +238,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'c205a943e9645b0d6addc475184f9aed24001aa7', # commit position 19551
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'd19f019f2cb6b170e2b6ba784372b6512d2cf84a', # commit position 19556
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc
index 10c5636..73e43cabe 100644
--- a/base/debug/task_annotator.cc
+++ b/base/debug/task_annotator.cc
@@ -49,11 +49,17 @@
   // variable itself will have the expected value when displayed by the
   // optimizer in an optimized build. Look at a memory dump of the stack.
   static constexpr int kStackTaskTraceSnapshotSize =
-      std::tuple_size<decltype(pending_task->task_backtrace)>::value + 1;
+      std::tuple_size<decltype(pending_task->task_backtrace)>::value + 3;
   std::array<const void*, kStackTaskTraceSnapshotSize> task_backtrace;
-  task_backtrace[0] = pending_task->posted_from.program_counter();
+
+  // Store a marker to locate |task_backtrace| content easily on a memory
+  // dump.
+  task_backtrace.front() = reinterpret_cast<void*>(0xefefefefefefefef);
+  task_backtrace.back() = reinterpret_cast<void*>(0xfefefefefefefefe);
+
+  task_backtrace[1] = pending_task->posted_from.program_counter();
   std::copy(pending_task->task_backtrace.begin(),
-            pending_task->task_backtrace.end(), task_backtrace.begin() + 1);
+            pending_task->task_backtrace.end(), task_backtrace.begin() + 2);
   debug::Alias(&task_backtrace);
 
   std::move(pending_task->task).Run();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java
index a554745..73f73031 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java
@@ -414,7 +414,7 @@
             for (URI supportedOrigin : method.supportedOrigins) {
                 Set<URI> supportedAppMethodNames =
                         mOriginToUriDefaultMethodsMapping.get(supportedOrigin);
-                assert supportedAppMethodNames != null;
+                if (supportedAppMethodNames == null) continue;
 
                 for (URI supportedAppMethodName : supportedAppMethodNames) {
                     PaymentMethod supportedAppMethod =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index ff29d562..ea984a0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -151,6 +151,7 @@
     private boolean mExitedDueToUnsupportedMode;
     private boolean mExitingCct;
     private boolean mPaused;
+    private boolean mStopped;
     private int mRestoreSystemUiVisibilityFlag = -1;
     private Integer mRestoreOrientation = null;
     private long mNativeVrShellDelegate;
@@ -508,6 +509,7 @@
         mVrClassesWrapper = wrapper;
         // If an activity isn't resumed at the point, it must have been paused.
         mPaused = ApplicationStatus.getStateForActivity(activity) != ActivityState.RESUMED;
+        mStopped = ApplicationStatus.getStateForActivity(activity) == ActivityState.STOPPED;
         updateVrSupportLevel(null);
         mNativeVrShellDelegate = nativeInit();
         createNonPresentingNativeContext();
@@ -941,20 +943,19 @@
     @CalledByNative
     private boolean exitWebVRPresent() {
         if (!mInVr) return false;
+        if (mAutopresentWebVr) {
+            // For autopresent from Daydream home, we do NOT want to show ChromeVR. So if we
+            // ever exit WebVR for whatever reason (navigation, call exitPresent etc), go back to
+            // Daydream home.
+            mVrDaydreamApi.launchVrHomescreen();
+            return true;
+        }
         if (!isVrShellEnabled(mVrSupportLevel) || !isDaydreamCurrentViewer()
                 || !activitySupportsVrBrowsing(mActivity)) {
             if (isDaydreamCurrentViewer() && showDoff(false /* optional */)) return false;
             shutdownVr(true /* disableVrMode */, true /* stayingInChrome */);
         } else {
-            if (mAutopresentWebVr) {
-                // For autopresent from Daydream home, we do NOT want to show ChromeVR. So if we
-                // ever exit WebVR for whatever reason(navigation, call exitPresent etc), go back to
-                // Daydream home.
-                mVrDaydreamApi.launchVrHomescreen();
-                return true;
-            }
             mVrBrowserUsed = true;
-            mAutopresentWebVr = false;
             mVrShell.setWebVrModeEnabled(false, false);
         }
         return true;
@@ -1064,6 +1065,7 @@
     }
 
     private void onStart() {
+        mStopped = false;
         if (mDonSucceeded) {
             // We're about to enter VR, so set the VR Mode as early as possible to avoid screen
             // brightness flickering while in the headset.
@@ -1073,6 +1075,7 @@
     }
 
     private void onStop() {
+        mStopped = true;
         cancelPendingVrEntry();
         assert !mCancellingEntryAnimation;
         // We defer pausing of VrShell until the app is stopped to keep head tracking working for
@@ -1203,17 +1206,18 @@
     @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
     public void shutdownVr(boolean disableVrMode, boolean stayingInChrome) {
         cancelPendingVrEntry();
-        if (mAutopresentWebVr && handleFinishAutopresentation()) return;
+        // Ensure shutdownVr runs if we're stopping.
+        if (handleFinishAutopresentation() && !mStopped) return;
+        mAutopresentWebVr = false;
+
         if (!mInVr) return;
+        mInVr = false;
 
         if (mShowingDaydreamDoff) {
             onExitVrResult(true);
             return;
         }
 
-        mInVr = false;
-        mAutopresentWebVr = false;
-
         // The user has exited VR.
         RecordUserAction.record("VR.DOFF");
 
@@ -1259,14 +1263,13 @@
     /* package */ void exitCct() {
         if (mShowingDaydreamDoff) return;
         assert mActivity instanceof CustomTabActivity;
-
-        if (mInVrAtChromeLaunch != null) {
-            if (!mInVrAtChromeLaunch && showDoff(true /* optional */)) {
-                mExitingCct = true;
-                return;
-            }
-            // Started chrome in VR mode.
-            shutdownVr(false /* disableVrMode */, false /* stayingInChrome */);
+        if (mAutopresentWebVr || (mInVrAtChromeLaunch != null && mInVrAtChromeLaunch)) {
+            ((CustomTabActivity) mActivity).finishAndClose(false);
+            return;
+        }
+        if (showDoff(true /* optional */)) {
+            mExitingCct = true;
+        } else {
             ((CustomTabActivity) mActivity).finishAndClose(false);
         }
     }
@@ -1302,13 +1305,11 @@
      * Returns true if finishing auto-presentation was handled.
      */
     private boolean handleFinishAutopresentation() {
-        assert mAutopresentWebVr;
-        mAutopresentWebVr = false;
-        if (mActivity instanceof CustomTabActivity) {
-            exitCct();
-            return true;
-        }
-        return false;
+        if (!mAutopresentWebVr) return false;
+        // Should only autopresent CustomTabActivity for now.
+        assert mActivity instanceof CustomTabActivity;
+        exitCct();
+        return true;
     }
 
     private static void startFeedback(Tab tab) {
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc
index 05c87fe..30492e1 100644
--- a/chrome/browser/android/webapk/webapk_installer.cc
+++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -289,11 +289,11 @@
       base::android::ConvertUTF8ToJavaString(env, token);
   base::android::ScopedJavaLocalRef<jstring> java_url =
       base::android::ConvertUTF8ToJavaString(env, start_url_.spec());
-  base::android::ScopedJavaLocalRef<jobject> java_primary_icon =
-      gfx::ConvertToJavaBitmap(&install_primary_icon_);
 
   if (task_type_ == WebApkInstaller::INSTALL) {
     webapk::TrackRequestTokenDuration(install_duration_timer_->Elapsed());
+    base::android::ScopedJavaLocalRef<jobject> java_primary_icon =
+        gfx::ConvertToJavaBitmap(&install_primary_icon_);
     Java_WebApkInstaller_installWebApkAsync(
         env, java_ref_, java_webapk_package, version, java_title, java_token,
         java_url, install_shortcut_info_->source, java_primary_icon);
diff --git a/chrome/browser/chromeos/drive/fileapi/fileapi_worker.h b/chrome/browser/chromeos/drive/fileapi/fileapi_worker.h
index f267d0a5..9bfc4bfc 100644
--- a/chrome/browser/chromeos/drive/fileapi/fileapi_worker.h
+++ b/chrome/browser/chromeos/drive/fileapi/fileapi_worker.h
@@ -50,10 +50,11 @@
 typedef base::Callback<
     void(base::File::Error result,
          const base::File::Info& file_info)> GetFileInfoCallback;
-typedef base::Callback<
-    void(base::File::Error result,
-         const std::vector<storage::DirectoryEntry>& file_list,
-         bool has_more)> ReadDirectoryCallback;
+typedef base::RepeatingCallback<void(
+    base::File::Error result,
+    std::vector<storage::DirectoryEntry> file_list,
+    bool has_more)>
+    ReadDirectoryCallback;
 typedef base::Callback<void(base::File::Error result,
                             const base::File::Info& file_info,
                             const base::FilePath& snapshot_file_path,
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
index 5d62b9de..9ad1324 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
@@ -103,11 +103,11 @@
 void OnReadDirectory(
     const storage::AsyncFileUtil::ReadDirectoryCallback& callback,
     base::File::Error result,
-    const storage::AsyncFileUtil::EntryList& entry_list,
+    storage::AsyncFileUtil::EntryList entry_list,
     bool has_more) {
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::BindOnce(callback, result, entry_list, has_more));
+      base::BindOnce(callback, result, std::move(entry_list), has_more));
 }
 
 // Executes CreateDirectory on the UI thread.
@@ -340,8 +340,8 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::BindOnce(&ReadDirectoryOnUIThread, base::Passed(&context), url,
-                     base::Bind(&OnReadDirectory, callback)));
+      base::BindOnce(&ReadDirectoryOnUIThread, std::move(context), url,
+                     base::BindRepeating(&OnReadDirectory, callback)));
 }
 
 void ProviderAsyncFileUtil::Touch(
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
index 892e8e2..602ead13 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
@@ -70,7 +70,7 @@
   }
 
   void OnReadDirectory(base::File::Error error,
-                       const storage::AsyncFileUtil::EntryList& file_list,
+                       storage::AsyncFileUtil::EntryList file_list,
                        bool has_more) {
     result_.reset(new base::File::Error(error));
   }
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc
index ed342aa..23766f7 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc
@@ -41,9 +41,11 @@
   class Event {
    public:
     Event(base::File::Error result,
-          const storage::AsyncFileUtil::EntryList& entry_list,
+          storage::AsyncFileUtil::EntryList entry_list,
           bool has_more)
-        : result_(result), entry_list_(entry_list), has_more_(has_more) {}
+        : result_(result),
+          entry_list_(std::move(entry_list)),
+          has_more_(has_more) {}
     virtual ~Event() {}
 
     base::File::Error result() { return result_; }
@@ -64,9 +66,10 @@
   virtual ~CallbackLogger() {}
 
   void OnReadDirectory(base::File::Error result,
-                       const storage::AsyncFileUtil::EntryList& entry_list,
+                       storage::AsyncFileUtil::EntryList entry_list,
                        bool has_more) {
-    events_.push_back(base::MakeUnique<Event>(result, entry_list, has_more));
+    events_.push_back(
+        base::MakeUnique<Event>(result, std::move(entry_list), has_more));
   }
 
   std::vector<std::unique_ptr<Event>>& events() { return events_; }
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source.cc b/chrome/browser/chromeos/fileapi/recent_download_source.cc
index d6e08bb..e5da2b3c 100644
--- a/chrome/browser/chromeos/fileapi/recent_download_source.cc
+++ b/chrome/browser/chromeos/fileapi/recent_download_source.cc
@@ -27,12 +27,13 @@
 void OnReadDirectoryOnIOThread(
     const storage::FileSystemOperation::ReadDirectoryCallback& callback,
     base::File::Error result,
-    const storage::FileSystemOperation::FileEntryList& entries,
+    storage::FileSystemOperation::FileEntryList entries,
     bool has_more) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::BindOnce(callback, result, entries, has_more));
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(callback, result, std::move(entries), has_more));
 }
 
 void ReadDirectoryOnIOThread(
@@ -42,7 +43,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   file_system_context->operation_runner()->ReadDirectory(
-      url, base::Bind(&OnReadDirectoryOnIOThread, callback));
+      url, base::BindRepeating(&OnReadDirectoryOnIOThread, callback));
 }
 
 void OnGetMetadataOnIOThread(
@@ -118,7 +119,7 @@
 void RecentDownloadSource::OnReadDirectory(
     const base::FilePath& path,
     base::File::Error result,
-    const storage::FileSystemOperation::FileEntryList& entries,
+    storage::FileSystemOperation::FileEntryList entries,
     bool has_more) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(params_.has_value());
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source.h b/chrome/browser/chromeos/fileapi/recent_download_source.h
index 6fc91b9..4b96e225 100644
--- a/chrome/browser/chromeos/fileapi/recent_download_source.h
+++ b/chrome/browser/chromeos/fileapi/recent_download_source.h
@@ -43,11 +43,10 @@
   static const char kLoadHistogramName[];
 
   void ScanDirectory(const base::FilePath& path);
-  void OnReadDirectory(
-      const base::FilePath& path,
-      base::File::Error result,
-      const storage::FileSystemOperation::FileEntryList& entries,
-      bool has_more);
+  void OnReadDirectory(const base::FilePath& path,
+                       base::File::Error result,
+                       storage::FileSystemOperation::FileEntryList entries,
+                       bool has_more);
   void OnGetMetadata(const storage::FileSystemURL& url,
                      base::File::Error result,
                      const base::File::Info& info);
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 3d999311..abcb32fa 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -1100,16 +1100,16 @@
   storage::FileSystemURL url = context_->CrackURL(project_url);
 
   context_->operation_runner()->ReadDirectory(
-      url, base::Bind(&DeveloperPrivateLoadDirectoryFunction::
-                      ReadDirectoryByFileSystemAPICb,
-                      this, project_path, destination_path));
+      url, base::BindRepeating(&DeveloperPrivateLoadDirectoryFunction::
+                                   ReadDirectoryByFileSystemAPICb,
+                               this, project_path, destination_path));
 }
 
 void DeveloperPrivateLoadDirectoryFunction::ReadDirectoryByFileSystemAPICb(
     const base::FilePath& project_path,
     const base::FilePath& destination_path,
     base::File::Error status,
-    const storage::FileSystemOperation::FileEntryList& file_list,
+    storage::FileSystemOperation::FileEntryList file_list,
     bool has_more) {
   if (status != base::File::FILE_OK) {
     DLOG(ERROR) << "Error in copying files from sync filesystem.";
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h
index 864853b..ac72496 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.h
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -509,7 +509,7 @@
       const base::FilePath& project_path,
       const base::FilePath& destination_path,
       base::File::Error result,
-      const storage::FileSystemOperation::FileEntryList& file_list,
+      storage::FileSystemOperation::FileEntryList file_list,
       bool has_more);
 
   void SnapshotFileCallback(
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
index fb69729..a6f37c07 100644
--- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
+++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
@@ -1225,7 +1225,7 @@
     const bool exclusive,
     const CreateDirectorySuccessCallback& success_callback,
     const ErrorCallback& error_callback,
-    const storage::AsyncFileUtil::EntryList& /* entries */,
+    storage::AsyncFileUtil::EntryList /* entries */,
     const bool has_more) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
@@ -1647,7 +1647,7 @@
 
 void MTPDeviceDelegateImplLinux::OnDidFillFileCache(
     const base::FilePath& path,
-    const storage::AsyncFileUtil::EntryList& /* entries */,
+    storage::AsyncFileUtil::EntryList /* entries */,
     bool has_more) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   DCHECK(path.IsParent(pending_tasks_.front().path));
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h
index 5218e87d..7a4c63a7 100644
--- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h
+++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h
@@ -206,7 +206,7 @@
       const bool exclusive,
       const CreateDirectorySuccessCallback& success_callback,
       const ErrorCallback& error_callback,
-      const storage::AsyncFileUtil::EntryList& entries,
+      storage::AsyncFileUtil::EntryList entries,
       const bool has_more);
 
   // Called when ReadDirectory succeeds.
@@ -383,10 +383,9 @@
                       const base::File::Info& file_info, int bytes_read);
 
   // Called when FillFileCache() succeeds.
-  void OnDidFillFileCache(
-      const base::FilePath& path,
-      const storage::AsyncFileUtil::EntryList& /* entries */,
-      bool has_more);
+  void OnDidFillFileCache(const base::FilePath& path,
+                          storage::AsyncFileUtil::EntryList /* entries */,
+                          bool has_more);
 
   // Called when FillFileCache() fails.
   void OnFillFileCacheFailed(base::File::Error error);
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
index 4700f71..ddb74b001 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
@@ -71,9 +71,9 @@
 void OnDidCheckMediaForReadDirectory(
     const AsyncFileUtil::ReadDirectoryCallback& callback,
     bool has_more,
-    const AsyncFileUtil::EntryList& file_list) {
+    AsyncFileUtil::EntryList file_list) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  callback.Run(base::File::FILE_OK, file_list, has_more);
+  callback.Run(base::File::FILE_OK, std::move(file_list), has_more);
 }
 
 // Called when CreateDirectory method call failed.
@@ -649,21 +649,19 @@
 void DeviceMediaAsyncFileUtil::OnDidReadDirectory(
     base::SequencedTaskRunner* task_runner,
     const AsyncFileUtil::ReadDirectoryCallback& callback,
-    const AsyncFileUtil::EntryList& file_list,
+    AsyncFileUtil::EntryList file_list,
     bool has_more) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (!validate_media_files()) {
-    OnDidCheckMediaForReadDirectory(callback, has_more, file_list);
+    OnDidCheckMediaForReadDirectory(callback, has_more, std::move(file_list));
     return;
   }
 
   base::PostTaskAndReplyWithResult(
-      task_runner,
-      FROM_HERE,
-      base::Bind(&MediaPathFilterWrapper::FilterMediaEntries,
-                 media_path_filter_wrapper_,
-                 file_list),
-      base::Bind(&OnDidCheckMediaForReadDirectory, callback, has_more));
+      task_runner, FROM_HERE,
+      base::BindOnce(&MediaPathFilterWrapper::FilterMediaEntries,
+                     media_path_filter_wrapper_, std::move(file_list)),
+      base::BindOnce(&OnDidCheckMediaForReadDirectory, callback, has_more));
 }
 
 void DeviceMediaAsyncFileUtil::OnDidCopyFileLocal(
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
index 3874caec..664553b 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
@@ -164,11 +164,10 @@
   // |file_list| will have only a subset of all contents (the subsets reported
   // in any two calls are disjoint), and |has_more| will be true, except for
   // the last chunk.
-  void OnDidReadDirectory(
-      base::SequencedTaskRunner* task_runner,
-      const ReadDirectoryCallback& callback,
-      const EntryList& file_list,
-      bool has_more);
+  void OnDidReadDirectory(base::SequencedTaskRunner* task_runner,
+                          const ReadDirectoryCallback& callback,
+                          EntryList file_list,
+                          bool has_more);
 
   // Called when MoveFileLocal method call succeeds. |callback| is invoked to
   // complete the MoveFileLocal request.
diff --git a/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
index 94f1ac5f..e13f3d5 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
@@ -47,12 +47,13 @@
 void ReadDirectoryTestHelperCallback(
     base::RunLoop* run_loop,
     FileSystemOperation::FileEntryList* contents,
-    bool* completed, base::File::Error error,
-    const FileSystemOperation::FileEntryList& file_list,
+    bool* completed,
+    base::File::Error error,
+    FileSystemOperation::FileEntryList file_list,
     bool has_more) {
   DCHECK(!*completed);
   *completed = (!has_more && error == base::File::FILE_OK);
-  *contents = file_list;
+  *contents = std::move(file_list);
   run_loop->Quit();
 }
 
@@ -64,8 +65,8 @@
   DCHECK(completed);
   base::RunLoop run_loop;
   runner->ReadDirectory(
-      url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents,
-                      completed));
+      url, base::BindRepeating(&ReadDirectoryTestHelperCallback, &run_loop,
+                               contents, completed));
   run_loop.Run();
 }
 
diff --git a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
index 746c3ba..92a1e7d 100644
--- a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
+++ b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
@@ -37,8 +37,8 @@
   typedef base::Closure CreateDirectorySuccessCallback;
 
   // A callback to be called when ReadDirectory method call succeeds.
-  typedef base::Callback<
-      void(const storage::AsyncFileUtil::EntryList& file_list, bool has_more)>
+  typedef base::RepeatingCallback<
+      void(storage::AsyncFileUtil::EntryList file_list, bool has_more)>
       ReadDirectorySuccessCallback;
 
   // A callback to be called when GetFileInfo/ReadDirectory/CreateSnapshot
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
index b141efb..c5a25bfea 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
@@ -90,7 +90,7 @@
 void DidReadDirectory(std::set<base::FilePath::StringType>* content,
                       bool* completed,
                       base::File::Error error,
-                      const FileEntryList& file_list,
+                      FileEntryList file_list,
                       bool has_more) {
   EXPECT_TRUE(!*completed);
   *completed = !has_more;
@@ -237,7 +237,7 @@
   FileSystemURL url = CreateURL(FPL(""));
   bool completed = false;
   operation_runner()->ReadDirectory(
-      url, base::Bind(&DidReadDirectory, &content, &completed));
+      url, base::BindRepeating(&DidReadDirectory, &content, &completed));
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(completed);
   EXPECT_EQ(6u, content.size());
diff --git a/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
index 106471cb..227f7ca 100644
--- a/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
@@ -142,12 +142,13 @@
 void ReadDirectoryTestHelperCallback(
     base::RunLoop* run_loop,
     FileSystemOperation::FileEntryList* contents,
-    bool* completed, base::File::Error error,
-    const FileSystemOperation::FileEntryList& file_list,
+    bool* completed,
+    base::File::Error error,
+    FileSystemOperation::FileEntryList file_list,
     bool has_more) {
   DCHECK(!*completed);
   *completed = !has_more && error == base::File::FILE_OK;
-  *contents = file_list;
+  *contents = std::move(file_list);
   run_loop->Quit();
 }
 
@@ -159,8 +160,8 @@
   DCHECK(completed);
   base::RunLoop run_loop;
   runner->ReadDirectory(
-      url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents,
-                      completed));
+      url, base::BindRepeating(&ReadDirectoryTestHelperCallback, &run_loop,
+                               contents, completed));
   run_loop.Run();
 }
 
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
index 2af5719f..ed617da41 100644
--- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
+++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
@@ -199,20 +199,20 @@
   }
 
   void OnReadDir(base::WaitableEvent* event,
-                 const storage::AsyncFileUtil::EntryList& files,
+                 storage::AsyncFileUtil::EntryList files,
                  bool has_more) {
     error_ = base::File::FILE_OK;
     ASSERT_FALSE(has_more);
-    file_list_ = files;
+    file_list_ = std::move(files);
     event->Signal();
   }
 
   void OverlappedOnReadDir(base::WaitableEvent* event,
-                           const storage::AsyncFileUtil::EntryList& files,
+                           storage::AsyncFileUtil::EntryList files,
                            bool has_more) {
     overlapped_error_ = base::File::FILE_OK;
     ASSERT_FALSE(has_more);
-    overlapped_file_list_ = files;
+    overlapped_file_list_ = std::move(files);
     event->Signal();
   }
 
@@ -246,12 +246,10 @@
                              base::WaitableEvent::InitialState::NOT_SIGNALED);
     delegate_->ReadDirectory(
         path,
-        base::Bind(&MTPDeviceDelegateImplMacTest::OnReadDir,
-                   base::Unretained(this),
-                   &wait),
+        base::BindRepeating(&MTPDeviceDelegateImplMacTest::OnReadDir,
+                            base::Unretained(this), &wait),
         base::Bind(&MTPDeviceDelegateImplMacTest::OnError,
-                   base::Unretained(this),
-                   &wait));
+                   base::Unretained(this), &wait));
     scoped_task_environment_.RunUntilIdle();
     wait.Wait();
     return error_;
@@ -330,22 +328,17 @@
 
   delegate_->ReadDirectory(
       base::FilePath(kDevicePath),
-      base::Bind(&MTPDeviceDelegateImplMacTest::OnReadDir,
-                 base::Unretained(this),
-                 &wait),
-      base::Bind(&MTPDeviceDelegateImplMacTest::OnError,
-                 base::Unretained(this),
+      base::BindRepeating(&MTPDeviceDelegateImplMacTest::OnReadDir,
+                          base::Unretained(this), &wait),
+      base::Bind(&MTPDeviceDelegateImplMacTest::OnError, base::Unretained(this),
                  &wait));
 
   delegate_->ReadDirectory(
       base::FilePath(kDevicePath),
-      base::Bind(&MTPDeviceDelegateImplMacTest::OverlappedOnReadDir,
-                 base::Unretained(this),
-                 &wait),
+      base::BindRepeating(&MTPDeviceDelegateImplMacTest::OverlappedOnReadDir,
+                          base::Unretained(this), &wait),
       base::Bind(&MTPDeviceDelegateImplMacTest::OverlappedOnError,
-                 base::Unretained(this),
-                 &wait));
-
+                 base::Unretained(this), &wait));
 
   // Signal the delegate that no files are coming.
   delegate_->NoMoreItems();
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
index a899394..2c386936 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -520,24 +520,9 @@
         configData.translatedStrings.searchboxPlaceholder;
 
     if (configData.isVoiceSearchEnabled) {
-      $(IDS.FAKEBOX_SPEECH).hidden = false;
-      $(IDS.FAKEBOX_SPEECH).title =
-          configData.translatedStrings.fakeboxSpeechTooltip;
-
-      speech.init(configData);
-
-      $(IDS.FAKEBOX_SPEECH).onmouseup = function(event) {
-        // If propagated, closes the overlay (click on the background).
-        event.stopPropagation();
-        speech.toggleStartStop();
-      };
-      window.addEventListener('keydown', speech.onKeyDown);
-
-      if (searchboxApiHandle.onfocuschange) {
-        throw new Error('OnFocusChange handler already set on searchbox.');
-      }
-
-      searchboxApiHandle.onfocuschange = speech.onOmniboxFocused;
+      speech.init(
+          configData.googleBaseUrl, configData.translatedStrings,
+          $(IDS.FAKEBOX_SPEECH), searchboxApiHandle);
     }
 
     // Listener for updating the key capture state.
diff --git a/chrome/browser/resources/local_ntp/voice.js b/chrome/browser/resources/local_ntp/voice.js
index 6fd1801..3e8623c 100644
--- a/chrome/browser/resources/local_ntp/voice.js
+++ b/chrome/browser/resources/local_ntp/voice.js
@@ -114,7 +114,7 @@
  */
 speech.State_ = {
   // Initial state of the controller. Is never re-entered.
-  // The only state from which the speech.init() method can be called.
+  // The only state from which the |speech.init()| method can be called.
   // The UI overlay is hidden, recognition is inactive.
   UNINITIALIZED: -1,
   // Represents a ready to be activated state. If voice search is unsuccessful
@@ -257,33 +257,51 @@
 
 
 /**
- * Initializes the speech module.
- * @param {!Object} configData The NTP configuration.
+ * Initialize the speech module as part of the local NTP. Adds event handlers
+ * and shows the fakebox speech microphone icon.
+ * @param {!string} googleBaseUrl Base URL for sending queries to Search.
+ * @param {!Object} translatedStrings Dictionary of localized string messages.
+ * @param {!HTMLElement} fakeboxMicrophoneElem Fakebox microphone icon element.
+ * @param {!Object} searchboxApiHandle SearchBox API handle.
  */
-speech.init = function(configData) {
+speech.init = function(
+    googleBaseUrl, translatedStrings, fakeboxMicrophoneElem,
+    searchboxApiHandle) {
   if (speech.currentState_ != speech.State_.UNINITIALIZED) {
     throw new Error(
         'Trying to re-initialize speech when not in UNINITIALIZED state.');
   }
 
-  speech.googleBaseUrl_ = configData.googleBaseUrl;
-
-  // Set translations map.
-  speech.messages = {
-    audioError: configData.translatedStrings.audioError,
-    details: configData.translatedStrings.details,
-    languageError: configData.translatedStrings.languageError,
-    learnMore: configData.translatedStrings.learnMore,
-    listening: configData.translatedStrings.listening,
-    networkError: configData.translatedStrings.networkError,
-    noTranslation: configData.translatedStrings.noTranslation,
-    noVoice: configData.translatedStrings.noVoice,
-    permissionError: configData.translatedStrings.permissionError,
-    ready: configData.translatedStrings.ready,
-    tryAgain: configData.translatedStrings.tryAgain,
-    waiting: configData.translatedStrings.waiting,
+  // Initialize event handlers.
+  fakeboxMicrophoneElem.hidden = false;
+  fakeboxMicrophoneElem.title = translatedStrings.fakeboxMicrophoneTooltip;
+  fakeboxMicrophoneElem.onmouseup = function(event) {
+    // If propagated, closes the overlay (click on the background).
+    event.stopPropagation();
+    speech.toggleStartStop();
   };
+  window.addEventListener('keydown', speech.onKeyDown);
+  if (searchboxApiHandle.onfocuschange) {
+    throw new Error('OnFocusChange handler already set on searchbox.');
+  }
+  searchboxApiHandle.onfocuschange = speech.onOmniboxFocused;
 
+  // Initialize speech internal state.
+  speech.googleBaseUrl_ = googleBaseUrl;
+  speech.messages = {
+    audioError: translatedStrings.audioError,
+    details: translatedStrings.details,
+    languageError: translatedStrings.languageError,
+    learnMore: translatedStrings.learnMore,
+    listening: translatedStrings.listening,
+    networkError: translatedStrings.networkError,
+    noTranslation: translatedStrings.noTranslation,
+    noVoice: translatedStrings.noVoice,
+    permissionError: translatedStrings.permissionError,
+    ready: translatedStrings.ready,
+    tryAgain: translatedStrings.tryAgain,
+    waiting: translatedStrings.waiting,
+  };
   view.init(speech.onClick_);
   speech.initWebkitSpeech_();
   speech.reset_();
@@ -291,6 +309,27 @@
 
 
 /**
+ * Resets the internal state of Voice Search and disables the speech
+ * recognition interface. Only used for testing.
+ * @param {HTMLElement} fakeboxMicrophoneElem Fakebox microphone icon element.
+ * @param {!Object} searchboxApiHandle SearchBox API handle.
+ * @private
+ */
+speech.uninit_ = function(fakeboxMicrophoneElem, searchboxApiHandle) {
+  speech.reset_();
+  speech.googleBaseUrl_ = null;
+  speech.messages = {};
+  speech.currentState_ = speech.State_.UNINITIALIZED;
+  fakeboxMicrophoneElem.hidden = true;
+  fakeboxMicrophoneElem.title = '';
+  fakeboxMicrophoneElem.onmouseup = null;
+  window.removeEventListener('keydown', speech.onKeyDown);
+  searchboxApiHandle.onfocuschange = null;
+  speech.recognition_ = null;
+};
+
+
+/**
  * Initializes and configures the speech recognition API.
  * @private
  */
@@ -381,10 +420,6 @@
   speech.interimResult_ = '';
   speech.finalResult_ = '';
   speech.currentState_ = speech.State_.READY;
-
-  // TODO(oskopek): Is this even needed? Avoid calling it twice
-  // on a |speech.abort_()| call.
-  speech.recognition_.abort();
 };
 
 
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 52b468d2..3e50a383 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -122,7 +122,7 @@
     AddString(translated_strings.get(), "audioError",
               IDS_NEW_TAB_VOICE_AUDIO_ERROR);
     AddString(translated_strings.get(), "details", IDS_NEW_TAB_VOICE_DETAILS);
-    AddString(translated_strings.get(), "fakeboxSpeechTooltip",
+    AddString(translated_strings.get(), "fakeboxMicrophoneTooltip",
               IDS_TOOLTIP_MIC_SEARCH);
     AddString(translated_strings.get(), "languageError",
               IDS_NEW_TAB_VOICE_LANGUAGE_ERROR);
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
index f50dc78..55d88459 100644
--- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
+++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
@@ -138,16 +138,16 @@
 }
 
 void OnReadDirectory(CannedSyncableFileSystem::FileEntryList* entries_out,
-                     const CannedSyncableFileSystem::StatusCallback& callback,
+                     CannedSyncableFileSystem::StatusCallback callback,
                      base::File::Error error,
-                     const storage::FileSystemOperation::FileEntryList& entries,
+                     storage::FileSystemOperation::FileEntryList entries,
                      bool has_more) {
   DCHECK(entries_out);
   entries_out->reserve(entries_out->size() + entries.size());
   std::copy(entries.begin(), entries.end(), std::back_inserter(*entries_out));
 
   if (!has_more)
-    callback.Run(error);
+    std::move(callback).Run(error);
 }
 
 class WriteHelper {
@@ -634,7 +634,7 @@
   EXPECT_TRUE(io_task_runner_->RunsTasksInCurrentSequence());
   EXPECT_TRUE(is_filesystem_opened_);
   operation_runner()->ReadDirectory(
-      url, base::Bind(&OnReadDirectory, entries, callback));
+      url, base::BindRepeating(&OnReadDirectory, entries, callback));
 }
 
 void CannedSyncableFileSystem::DoWrite(
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index 2a09eb8..ae081ed3 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -18,7 +18,6 @@
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h"
 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h"
-#import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h"
 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_views_presenter.h"
 #import "chrome/browser/ui/cocoa/image_button_cell.h"
@@ -749,8 +748,13 @@
   // Convert the point to the container view's frame, and adjust for animation.
   NSPoint anchorInContainer =
       [containerView_ convertPoint:anchor fromView:view];
-  anchorInContainer.x -= NSMinX([containerView_ frame]) -
-      NSMinX([containerView_ animationEndFrame]);
+  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
+    anchorInContainer.x += NSMaxX([containerView_ frame]) -
+                           NSMaxX([containerView_ animationEndFrame]);
+  } else {
+    anchorInContainer.x -= NSMinX([containerView_ frame]) -
+                           NSMinX([containerView_ animationEndFrame]);
+  }
 
   return [containerView_ convertPoint:anchorInContainer toView:nil];
 }
diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
index 3cc5352f..0bb1af0 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
@@ -16,6 +16,7 @@
 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
 #import "chrome/browser/ui/cocoa/extensions/extension_view_mac.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
+#import "chrome/browser/ui/cocoa/l10n_util.h"
 #include "chrome/common/url_constants.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/browser_context.h"
@@ -350,7 +351,11 @@
                                   info_bubble::kBubbleArrowWidth / 2.0,
                               info_bubble::kBubbleArrowHeight / 2.0);
   offsets = [extensionView_ convertSize:offsets toView:nil];
-  windowOrigin.x -= NSWidth(frame) - offsets.width;
+  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
+    windowOrigin.x -= offsets.width;
+  } else {
+    windowOrigin.x -= NSWidth(frame) - offsets.width;
+  }
   windowOrigin.y -= NSHeight(frame) - offsets.height;
   frame.origin = windowOrigin;
 
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index be22e2a9..4d66eba4 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -1231,9 +1231,6 @@
 
 copy("cronet_package_copy") {
   sources = [
-    "$root_out_dir/lib.java/components/cronet/android/cronet_api.jar",
-    "$root_out_dir/lib.java/components/cronet/android/cronet_impl_common_java.jar",
-    "$root_out_dir/lib.java/components/cronet/android/cronet_impl_platform_java.jar",
     "$target_gen_dir/cronet_impl_native_proguard.cfg",
     "//AUTHORS",
     "//chrome/VERSION",
@@ -1252,6 +1249,43 @@
   ]
 }
 
+template("copy_java8_jars") {
+  _deps = []
+  foreach(dep, invoker.deps) {
+    _dep_name = get_label_info(dep, "name")
+    _source_jar = get_label_info(dep, "target_gen_dir") + "/" + _dep_name +
+                  "__compile_java.javac.jar"
+    _output_jar = "$_package_dir/" + _dep_name + ".jar"
+    _copy_dep = ":" + _dep_name + "__compile_java__javac"
+    _copy_target_name = "${target_name}_${dep}"
+
+    copy(_copy_target_name) {
+      sources = [
+        _source_jar,
+      ]
+      outputs = [
+        _output_jar,
+      ]
+      deps = [
+        _copy_dep,
+      ]
+    }
+    _deps += [ ":" + _copy_target_name ]
+  }
+
+  group(target_name) {
+    deps = _deps
+  }
+}
+
+copy_java8_jars("copy_cronet_java8_jars") {
+  deps = [
+    ":cronet_api_java",
+    ":cronet_impl_common_java",
+    ":cronet_impl_platform_java",
+  ]
+}
+
 action("cronet_combine_proguard_flags") {
   script = "//components/cronet/tools/generate_proguard_file.py"
   sources = [
@@ -1447,6 +1481,7 @@
       (!(target_cpu == "arm" && arm_version == 7) || !arm_use_neon)) {
     deps = [
       ":api_static_checks",
+      ":copy_cronet_java8_jars",
       ":cronet_package_copy",
       ":cronet_package_copy_native_lib",
       ":cronet_package_copy_native_lib_unstripped",
diff --git a/components/ntp_snippets/remote/json_request.cc b/components/ntp_snippets/remote/json_request.cc
index 8627c49c..206c846c 100644
--- a/components/ntp_snippets/remote/json_request.cc
+++ b/components/ntp_snippets/remote/json_request.cc
@@ -76,7 +76,7 @@
 bool IsSendingUserClassEnabled() {
   return variations::GetVariationParamByFeatureAsBool(
       ntp_snippets::kArticleSuggestionsFeature, kSendUserClassName,
-      /*default_value=*/false);
+      /*default_value=*/true);
 }
 
 // Translate the BCP 47 |language_code| into a posix locale string.
diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc
index 2374899..9df19870 100644
--- a/content/browser/fileapi/fileapi_message_filter.cc
+++ b/content/browser/fileapi/fileapi_message_filter.cc
@@ -333,8 +333,8 @@
   }
 
   operations_[request_id] = operation_runner()->ReadDirectory(
-      url, base::Bind(&FileAPIMessageFilter::DidReadDirectory,
-                      this, request_id));
+      url, base::BindRepeating(&FileAPIMessageFilter::DidReadDirectory, this,
+                               request_id));
 }
 
 void FileAPIMessageFilter::OnWrite(int request_id,
@@ -501,11 +501,12 @@
 void FileAPIMessageFilter::DidReadDirectory(
     int request_id,
     base::File::Error result,
-    const std::vector<storage::DirectoryEntry>& entries,
+    std::vector<storage::DirectoryEntry> entries,
     bool has_more) {
   if (result == base::File::FILE_OK) {
     if (!entries.empty() || !has_more)
-      Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more));
+      Send(new FileSystemMsg_DidReadDirectory(request_id, std::move(entries),
+                                              has_more));
   } else {
     DCHECK(!has_more);
     Send(new FileSystemMsg_DidFail(request_id, result));
diff --git a/content/browser/fileapi/fileapi_message_filter.h b/content/browser/fileapi/fileapi_message_filter.h
index 07a9c7738..a4766ee87 100644
--- a/content/browser/fileapi/fileapi_message_filter.h
+++ b/content/browser/fileapi/fileapi_message_filter.h
@@ -128,7 +128,7 @@
                                   const base::File::Info& info);
   void DidReadDirectory(int request_id,
                         base::File::Error result,
-                        const std::vector<storage::DirectoryEntry>& entries,
+                        std::vector<storage::DirectoryEntry> entries,
                         bool has_more);
   void DidWrite(int request_id,
                 base::File::Error result,
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc
index 43ff7b4..2d89495 100644
--- a/content/browser/loader/resource_scheduler.cc
+++ b/content/browser/loader/resource_scheduler.cc
@@ -43,6 +43,11 @@
 const base::Feature kPrioritySupportedRequestsDelayable{
     "PrioritySupportedRequestsDelayable", base::FEATURE_ENABLED_BY_DEFAULT};
 
+// When enabled, low-priority H2 and QUIC requests are throttled, but only
+// when the parser is in head.
+const base::Feature kHeadPrioritySupportedRequestsDelayable{
+    "HeadPriorityRequestsDelayable", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // In the event that many resource requests are started quickly, this feature
 // will periodically yield (e.g., delaying starting of requests) by posting a
 // task and waiting for the task to run to resume. This allows other
@@ -398,6 +403,7 @@
 class ResourceScheduler::Client {
  public:
   Client(bool priority_requests_delayable,
+         bool head_priority_requests_delayable,
          bool yielding_scheduler_enabled,
          int max_requests_before_yielding,
          const net::NetworkQualityEstimator* const network_quality_estimator,
@@ -408,6 +414,7 @@
         in_flight_delayable_count_(0),
         total_layout_blocking_count_(0),
         priority_requests_delayable_(priority_requests_delayable),
+        head_priority_requests_delayable_(head_priority_requests_delayable),
         num_skipped_scans_due_to_scheduled_start_(0),
         started_requests_since_yielding_(0),
         did_scheduler_yield_(false),
@@ -667,7 +674,8 @@
       attributes |= kAttributeLayoutBlocking;
     } else if (request->url_request()->priority() <
                kDelayablePriorityThreshold) {
-      if (priority_requests_delayable_) {
+      if (priority_requests_delayable_ ||
+          (head_priority_requests_delayable_ && !has_html_body_)) {
         // Resources below the delayable priority threshold that are considered
         // delayable.
         attributes |= kAttributeDelayable;
@@ -782,7 +790,11 @@
 
     const net::HostPortPair& host_port_pair = request->host_port_pair();
 
-    if (!priority_requests_delayable_) {
+    bool priority_delayable =
+        priority_requests_delayable_ ||
+        (head_priority_requests_delayable_ && !has_html_body_);
+
+    if (!priority_delayable) {
       if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme))
         return ShouldStartOrYieldRequest();
 
@@ -948,6 +960,10 @@
   // be delayed.
   bool priority_requests_delayable_;
 
+  // True if requests to servers that support priorities (e.g., H2/QUIC) can
+  // be delayed while the parser is in head.
+  bool head_priority_requests_delayable_;
+
   // The number of LoadAnyStartablePendingRequests scans that were skipped due
   // to smarter task scheduling around reprioritization.
   int num_skipped_scans_due_to_scheduled_start_;
@@ -984,12 +1000,18 @@
 ResourceScheduler::ResourceScheduler()
     : priority_requests_delayable_(
           base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)),
+      head_priority_requests_delayable_(base::FeatureList::IsEnabled(
+          kHeadPrioritySupportedRequestsDelayable)),
       yielding_scheduler_enabled_(
           base::FeatureList::IsEnabled(kNetworkSchedulerYielding)),
       max_requests_before_yielding_(base::GetFieldTrialParamByFeatureAsInt(
           kNetworkSchedulerYielding,
           kMaxRequestsBeforeYieldingParam,
-          kMaxRequestsBeforeYieldingDefault)) {}
+          kMaxRequestsBeforeYieldingDefault)) {
+  // Don't run the two experiments together.
+  if (priority_requests_delayable_ && head_priority_requests_delayable_)
+    priority_requests_delayable_ = false;
+}
 
 ResourceScheduler::~ResourceScheduler() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1050,8 +1072,9 @@
   DCHECK(!base::ContainsKey(client_map_, client_id));
 
   Client* client = new Client(
-      priority_requests_delayable_, yielding_scheduler_enabled_,
-      max_requests_before_yielding_, network_quality_estimator, this);
+      priority_requests_delayable_, head_priority_requests_delayable_,
+      yielding_scheduler_enabled_, max_requests_before_yielding_,
+      network_quality_estimator, this);
   client_map_[client_id] = client;
 }
 
diff --git a/content/browser/loader/resource_scheduler.h b/content/browser/loader/resource_scheduler.h
index 6d9ab7c7..9e34b0a3 100644
--- a/content/browser/loader/resource_scheduler.h
+++ b/content/browser/loader/resource_scheduler.h
@@ -222,6 +222,10 @@
   // be delayed.
   bool priority_requests_delayable_;
 
+  // True if requests to servers that support priorities (e.g., H2/QUIC) can
+  // be delayed while the parser is in head.
+  bool head_priority_requests_delayable_;
+
   // True if the scheduler should yield between several successive calls to
   // start resource requests.
   bool yielding_scheduler_enabled_;
diff --git a/content/browser/loader/resource_scheduler_unittest.cc b/content/browser/loader/resource_scheduler_unittest.cc
index b4ba5587..879ff97 100644
--- a/content/browser/loader/resource_scheduler_unittest.cc
+++ b/content/browser/loader/resource_scheduler_unittest.cc
@@ -57,11 +57,14 @@
 const int kBackgroundChildId = 35;
 const int kBackgroundRouteId = 43;
 
+// Sync below with cc file.
 const char kPrioritySupportedRequestsDelayable[] =
     "PrioritySupportedRequestsDelayable";
-
+const char kHeadPrioritySupportedRequestsDelayable[] =
+    "HeadPriorityRequestsDelayable";
 const char kNetworkSchedulerYielding[] = "NetworkSchedulerYielding";
-const int kMaxRequestsBeforeYielding = 5;  // sync with .cc.
+const int kMaxRequestsBeforeYielding = 5;
+const size_t kMaxNumDelayableRequestsPerHostPerClient = 6;
 
 class TestRequest : public ResourceThrottle::Delegate {
  public:
@@ -682,6 +685,220 @@
   high.reset();
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(low2->started());
+  EXPECT_TRUE(low_spdy->started());
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenNotDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine("",
+                                          kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+  http_server_properties_.SetSupportsSpdy(
+      url::SchemeHostPort("https", "spdyhost", 443), true);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kPrioritySupportedRequestsDelayable,
+      kHeadPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+  http_server_properties_.SetSupportsSpdy(
+      url::SchemeHostPort("https", "spdyhost", 443), true);
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
+
+  // Only kMaxNumDelayableRequestsPerHostPerClient in body.
+  for (size_t i = 0; i < requests.size(); ++i) {
+    if (i < kMaxNumDelayableRequestsPerHostPerClient)
+      EXPECT_TRUE(requests[i]->started());
+    else
+      EXPECT_FALSE(requests[i]->started());
+  }
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenHeadDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kHeadPrioritySupportedRequestsDelayable,
+      kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+  http_server_properties_.SetSupportsSpdy(
+      url::SchemeHostPort("https", "spdyhost", 443), true);
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
+}
+
+TEST_F(ResourceSchedulerTest, ThrottlesHeadWhenHeadDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kHeadPrioritySupportedRequestsDelayable,
+      kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+  http_server_properties_.SetSupportsSpdy(
+      url::SchemeHostPort("https", "spdyhost", 443), true);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
+
+  // While in head, only one low-priority request is allowed.
+  for (size_t i = 0u; i < requests.size(); ++i) {
+    if (i == 0u)
+      EXPECT_TRUE(requests[i]->started());
+    else
+      EXPECT_FALSE(requests[i]->started());
+  }
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenNotDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine("",
+                                          kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("http://host/low", net::LOWEST));
+
+  // Now the scheduler realizes these requests are for a spdy proxy.
+  scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kPrioritySupportedRequestsDelayable,
+      kHeadPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("http://host/low", net::LOWEST));
+
+  // Now the scheduler realizes these requests are for a spdy proxy.
+  scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // Only kMaxNumDelayableRequestsPerHostPerClient in body.
+  for (size_t i = 0; i < requests.size(); ++i) {
+    if (i < kMaxNumDelayableRequestsPerHostPerClient)
+      EXPECT_TRUE(requests[i]->started());
+    else
+      EXPECT_FALSE(requests[i]->started());
+  }
+}
+
+TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenHeadDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kHeadPrioritySupportedRequestsDelayable,
+      kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("http://host/low", net::LOWEST));
+
+  // Now the scheduler realizes these requests are for a spdy proxy.
+  scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
+}
+
+TEST_F(ResourceSchedulerTest, ThrottlesHeadForSpdyProxyWhenHeadDelayable) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      kHeadPrioritySupportedRequestsDelayable,
+      kPrioritySupportedRequestsDelayable);
+
+  InitializeScheduler();
+
+  // Add more than max-per-host low-priority requests.
+  std::vector<std::unique_ptr<TestRequest>> requests;
+  for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
+    requests.push_back(NewRequest("http://host/low", net::LOWEST));
+
+  // Now the scheduler realizes these requests are for a spdy proxy.
+  scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // While in head, only one low-priority request is allowed.
+  for (size_t i = 0u; i < requests.size(); ++i) {
+    if (i == 0u)
+      EXPECT_TRUE(requests[i]->started());
+    else
+      EXPECT_FALSE(requests[i]->started());
+  }
+
+  // Body has been reached.
+  scheduler()->OnWillInsertBody(kChildId, kRouteId);
+  base::RunLoop().RunUntilIdle();
+
+  // No throttling.
+  for (const auto& request : requests)
+    EXPECT_TRUE(request->started());
 }
 
 TEST_F(ResourceSchedulerTest, SpdyLowBlocksOtherLowUntilBodyInserted) {
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc
index 2b25d828..bb3d446 100644
--- a/content/browser/plugin_private_storage_helper.cc
+++ b/content/browser/plugin_private_storage_helper.cc
@@ -86,7 +86,7 @@
   void OnFileSystemOpened(base::File::Error result);
   void OnDirectoryRead(const std::string& root,
                        base::File::Error result,
-                       const storage::AsyncFileUtil::EntryList& file_list,
+                       storage::AsyncFileUtil::EntryList file_list,
                        bool has_more);
   void OnFileInfo(const std::string& file_name,
                   base::File::Error result,
@@ -150,14 +150,14 @@
           filesystem_context_);
   file_util->ReadDirectory(
       std::move(operation_context), filesystem_context_->CrackURL(GURL(root)),
-      base::Bind(&PluginPrivateDataByOriginChecker::OnDirectoryRead,
-                 base::Unretained(this), root));
+      base::BindRepeating(&PluginPrivateDataByOriginChecker::OnDirectoryRead,
+                          base::Unretained(this), root));
 }
 
 void PluginPrivateDataByOriginChecker::OnDirectoryRead(
     const std::string& root,
     base::File::Error result,
-    const storage::AsyncFileUtil::EntryList& file_list,
+    storage::AsyncFileUtil::EntryList file_list,
     bool has_more) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DVLOG(3) << __func__ << " result: " << result
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index 68be4e2..b22f85da 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -202,11 +202,13 @@
     const std::string& raw_device_id,
     const std::string& device_id_for_renderer) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  UMALogDeviceAuthorizationTime(auth_start_time);
+
   auto auth_data = authorizations_.find(stream_id);
   if (auth_data == authorizations_.end())
     return;  // Stream was closed before finishing authorization
 
-  UMALogDeviceAuthorizationTime(auth_start_time);
   if (status == media::OUTPUT_DEVICE_STATUS_OK) {
     auth_data->second.first = true;
     auth_data->second.second = raw_device_id;
diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
index ea05dc4..db1ace0 100644
--- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
+++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
@@ -209,10 +209,9 @@
       new storage::FileSystemOperation::FileEntryList;
   GetFileSystemContext()->operation_runner()->ReadDirectory(
       GetFileSystemURL(),
-      base::Bind(&PepperInternalFileRefBackend::ReadDirectoryComplete,
-                 weak_factory_.GetWeakPtr(),
-                 reply_context,
-                 base::Owned(accumulated_file_list)));
+      base::BindRepeating(&PepperInternalFileRefBackend::ReadDirectoryComplete,
+                          weak_factory_.GetWeakPtr(), reply_context,
+                          base::Owned(accumulated_file_list)));
   return PP_OK_COMPLETIONPENDING;
 }
 
@@ -220,7 +219,7 @@
     ppapi::host::ReplyMessageContext context,
     storage::FileSystemOperation::FileEntryList* accumulated_file_list,
     base::File::Error error,
-    const storage::FileSystemOperation::FileEntryList& file_list,
+    storage::FileSystemOperation::FileEntryList file_list,
     bool has_more) {
   accumulated_file_list->insert(
       accumulated_file_list->end(), file_list.begin(), file_list.end());
diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
index 95734fe..deab6c7 100644
--- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
+++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
@@ -68,7 +68,7 @@
       ppapi::host::ReplyMessageContext context,
       storage::FileSystemOperation::FileEntryList* accumulated_file_list,
       base::File::Error error,
-      const storage::FileSystemOperation::FileEntryList& file_list,
+      storage::FileSystemOperation::FileEntryList file_list,
       bool has_more);
 
   scoped_refptr<storage::FileSystemContext> GetFileSystemContext() const;
diff --git a/content/renderer/media/audio_renderer_sink_cache_unittest.cc b/content/renderer/media/audio_renderer_sink_cache_unittest.cc
index fc19e2b..ae8f117 100644
--- a/content/renderer/media/audio_renderer_sink_cache_unittest.cc
+++ b/content/renderer/media/audio_renderer_sink_cache_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread.h"
-#include "build/build_config.h"
 #include "content/renderer/media/audio_renderer_sink_cache_impl.h"
 #include "media/audio/audio_device_description.h"
 #include "media/base/audio_parameters.h"
@@ -306,14 +305,7 @@
 
 // Check that a sink created on one thread in response to GetSinkInfo can be
 // used on another thread.
-// Flaky on Linux TSan Tests. https://crbug.com/753228
-#if defined(OS_LINUX)
-#define MAYBE_MultithreadedAccess DISABLED_MultithreadedAccess
-#else
-#define MAYBE_MultithreadedAccess MultithreadedAccess
-#endif
-
-TEST_F(AudioRendererSinkCacheTest, MAYBE_MultithreadedAccess) {
+TEST_F(AudioRendererSinkCacheTest, MultithreadedAccess) {
   EXPECT_EQ(0, sink_count());
 
   base::Thread thread1("thread1");
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h
index 9f53ff94..8b0d7f7 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -95,6 +95,14 @@
 // Waits for there to be |count| number of incognito tabs. If the condition is
 // not met within a timeout, a GREYAssert is induced.
 + (void)waitForIncognitoTabCount:(NSUInteger)count;
+
+// Waits for there to be a web view containing a blocked |image_id|.  When
+// blocked, the image element will be smaller than the actual image size.
++ (void)waitForWebViewContainingBlockedImageElementWithID:(std::string)imageID;
+
+// Waits for there to be a web view containing loaded image with |image_id|.
+// When loaded, the image element will have the same size as actual image.
++ (void)waitForWebViewContainingLoadedImageElementWithID:(std::string)imageID;
 @end
 
 #endif  // IOS_CHROME_TEST_EARL_GREY_CHROME_EARL_GREY_H_
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
index 5e46264..d57746ef 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -227,4 +227,18 @@
              @"Failed waiting for incognito tab count to become %" PRIuNS,
              count);
 }
+
++ (void)waitForWebViewContainingBlockedImageElementWithID:(std::string)imageID {
+  GREYAssert(web::test::WaitForWebViewContainingImage(
+                 imageID, chrome_test_util::GetCurrentWebState(),
+                 web::test::IMAGE_STATE_BLOCKED),
+             @"Failed waiting for web view blocked image %s", imageID.c_str());
+}
+
++ (void)waitForWebViewContainingLoadedImageElementWithID:(std::string)imageID {
+  GREYAssert(web::test::WaitForWebViewContainingImage(
+                 imageID, chrome_test_util::GetCurrentWebState(),
+                 web::test::IMAGE_STATE_LOADED),
+             @"Failed waiting for web view loaded image %s", imageID.c_str());
+}
 @end
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm
index d6490834..29f360c 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -10,8 +10,6 @@
 
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#import "base/test/ios/wait_util.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h"
@@ -29,7 +27,6 @@
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
-#import "ios/testing/wait_util.h"
 #import "ios/web/public/block_types.h"
 #import "ios/web/public/test/earl_grey/web_view_matchers.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/web/public/test/earl_grey/web_view_matchers.mm b/ios/web/public/test/earl_grey/web_view_matchers.mm
index 75458a5..5c53385f 100644
--- a/ios/web/public/test/earl_grey/web_view_matchers.mm
+++ b/ios/web/public/test/earl_grey/web_view_matchers.mm
@@ -26,12 +26,13 @@
 using testing::kWaitForDownloadTimeout;
 using testing::WaitUntilConditionOrTimeout;
 
+// TODO(crbug.com/757982): Remove this class, after LoadImage() is removed.
 // A helper delegate class that allows downloading responses with invalid
 // SSL certs.
-@interface TestURLSessionDelegate : NSObject<NSURLSessionDelegate>
+@interface TestURLSessionDelegateDeprecated : NSObject<NSURLSessionDelegate>
 @end
 
-@implementation TestURLSessionDelegate
+@implementation TestURLSessionDelegateDeprecated
 
 - (void)URLSession:(NSURLSession*)session
     didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge
@@ -64,8 +65,8 @@
 UIImage* LoadImage(const GURL& image_url) {
   __block UIImage* image;
   __block NSError* error;
-  TestURLSessionDelegate* session_delegate =
-      [[TestURLSessionDelegate alloc] init];
+  TestURLSessionDelegateDeprecated* session_delegate =
+      [[TestURLSessionDelegateDeprecated alloc] init];
   NSURLSessionConfiguration* session_config =
       [NSURLSessionConfiguration defaultSessionConfiguration];
   NSURLSession* session =
diff --git a/ios/web/public/test/web_view_content_test_util.h b/ios/web/public/test/web_view_content_test_util.h
index d6bed179..160abbaf 100644
--- a/ios/web/public/test/web_view_content_test_util.h
+++ b/ios/web/public/test/web_view_content_test_util.h
@@ -10,6 +10,14 @@
 namespace web {
 namespace test {
 
+// Enum describing loaded/blocked state of an image html element.
+enum ImageStateElement {
+  // Element was not loaded by WebState.
+  IMAGE_STATE_BLOCKED = 1,
+  // Element was fullt loaded by WebState.
+  IMAGE_STATE_LOADED,
+};
+
 // Returns true if there is a web view for |web_state| that contains |text|.
 // Otherwise, returns false.
 bool IsWebViewContainingText(web::WebState* web_state, const std::string& text);
@@ -19,6 +27,11 @@
 bool WaitForWebViewContainingText(web::WebState* web_state,
                                   std::string text) WARN_UNUSED_RESULT;
 
+// Waits for a web view with the corresponding |image_id| and |image_state|, in
+// the given |web_state|.
+bool WaitForWebViewContainingImage(std::string image_id,
+                                   web::WebState* web_state,
+                                   ImageStateElement image_state);
 }  // namespace test
 }  // namespace web
 
diff --git a/ios/web/public/test/web_view_content_test_util.mm b/ios/web/public/test/web_view_content_test_util.mm
index 83b8a7b..3a6863d 100644
--- a/ios/web/public/test/web_view_content_test_util.mm
+++ b/ios/web/public/test/web_view_content_test_util.mm
@@ -5,14 +5,71 @@
 #import "ios/web/public/test/web_view_content_test_util.h"
 
 #import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
 
+#include "base/strings/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
 #import "ios/testing/wait_util.h"
 #import "ios/web/public/test/web_view_interaction_test_util.h"
+#import "net/base/mac/url_conversions.h"
+
+using testing::kWaitForDownloadTimeout;
+using testing::WaitUntilConditionOrTimeout;
+
+// A helper delegate class that allows downloading responses with invalid
+// SSL certs.
+@interface TestURLSessionDelegate : NSObject<NSURLSessionDelegate>
+@end
+
+@implementation TestURLSessionDelegate
+
+- (void)URLSession:(NSURLSession*)session
+    didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge
+      completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
+                                  NSURLCredential*))completionHandler {
+  SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
+  completionHandler(NSURLSessionAuthChallengeUseCredential,
+                    [NSURLCredential credentialForTrust:serverTrust]);
+}
+
+@end
 
 namespace {
 // Script that returns document.body as a string.
 char kGetDocumentBodyJavaScript[] =
     "document.body ? document.body.textContent : null";
+
+// Fetches the image from |image_url|.
+UIImage* LoadImage(const GURL& image_url) {
+  __block UIImage* image;
+  __block NSError* error;
+  TestURLSessionDelegate* session_delegate =
+      [[TestURLSessionDelegate alloc] init];
+  NSURLSessionConfiguration* session_config =
+      [NSURLSessionConfiguration ephemeralSessionConfiguration];
+  NSURLSession* session =
+      [NSURLSession sessionWithConfiguration:session_config
+                                    delegate:session_delegate
+                               delegateQueue:nil];
+  id completion_handler = ^(NSData* data, NSURLResponse*, NSError* task_error) {
+    error = task_error;
+    image = [[UIImage alloc] initWithData:data];
+  };
+
+  NSURLSessionDataTask* task =
+      [session dataTaskWithURL:net::NSURLWithGURL(image_url)
+             completionHandler:completion_handler];
+  [task resume];
+
+  bool task_completed = WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{
+    return image || error;
+  });
+
+  if (!task_completed) {
+    return nil;
+  }
+  return image;
+}
 }
 
 using testing::WaitUntilConditionOrTimeout;
@@ -38,5 +95,57 @@
   });
 }
 
+bool WaitForWebViewContainingImage(std::string image_id,
+                                   web::WebState* web_state,
+                                   ImageStateElement image_state) {
+  std::string get_url_script =
+      base::StringPrintf("document.getElementById('%s').src", image_id.c_str());
+  std::unique_ptr<base::Value> url_as_value =
+      web::test::ExecuteJavaScript(web_state, get_url_script);
+  std::string url_as_string;
+  if (!url_as_value->GetAsString(&url_as_string))
+    return false;
+
+  UIImage* image = LoadImage(GURL(url_as_string));
+  if (!image)
+    return false;
+
+  CGSize expected_size = image.size;
+
+  return WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{
+    NSString* const kGetElementAttributesScript =
+        [NSString stringWithFormat:
+                      @"var image = document.getElementById('%@');"
+                      @"var imageHeight = image.height;"
+                      @"var imageWidth = image.width;"
+                      @"JSON.stringify({"
+                      @"  height:imageHeight,"
+                      @"  width:imageWidth"
+                      @"});",
+                      base::SysUTF8ToNSString(image_id)];
+    std::unique_ptr<base::Value> value = web::test::ExecuteJavaScript(
+        web_state, base::SysNSStringToUTF8(kGetElementAttributesScript));
+    std::string result;
+    if (value && value->GetAsString(&result)) {
+      NSString* evaluation_result = base::SysUTF8ToNSString(result);
+      NSData* image_attributes_as_data =
+          [evaluation_result dataUsingEncoding:NSUTF8StringEncoding];
+      NSDictionary* image_attributes =
+          [NSJSONSerialization JSONObjectWithData:image_attributes_as_data
+                                          options:0
+                                            error:nil];
+      CGFloat height = [image_attributes[@"height"] floatValue];
+      CGFloat width = [image_attributes[@"width"] floatValue];
+      switch (image_state) {
+        case IMAGE_STATE_BLOCKED:
+          return height < expected_size.height && width < expected_size.width;
+        case IMAGE_STATE_LOADED:
+          return height == expected_size.height && width == expected_size.width;
+      }
+    }
+    return false;
+  });
+}
+
 }  // namespace test
 }  // namespace web
diff --git a/storage/browser/fileapi/async_file_util.h b/storage/browser/fileapi/async_file_util.h
index e8add062..c8e6fad1 100644
--- a/storage/browser/fileapi/async_file_util.h
+++ b/storage/browser/fileapi/async_file_util.h
@@ -67,10 +67,9 @@
            const base::File::Info& file_info)> GetFileInfoCallback;
 
   typedef std::vector<DirectoryEntry> EntryList;
-  typedef base::Callback<
-      void(base::File::Error result,
-           const EntryList& file_list,
-           bool has_more)> ReadDirectoryCallback;
+  typedef base::RepeatingCallback<
+      void(base::File::Error result, EntryList file_list, bool has_more)>
+      ReadDirectoryCallback;
 
   typedef base::Callback<void(
       base::File::Error result,
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job.cc b/storage/browser/fileapi/file_system_dir_url_request_job.cc
index de0857a..9f1a90a 100644
--- a/storage/browser/fileapi/file_system_dir_url_request_job.cc
+++ b/storage/browser/fileapi/file_system_dir_url_request_job.cc
@@ -103,8 +103,8 @@
     return;
   }
   file_system_context_->operation_runner()->ReadDirectory(
-      url_, base::Bind(&FileSystemDirURLRequestJob::DidReadDirectory,
-                       weak_factory_.GetWeakPtr()));
+      url_, base::BindRepeating(&FileSystemDirURLRequestJob::DidReadDirectory,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void FileSystemDirURLRequestJob::DidAttemptAutoMount(base::File::Error result) {
@@ -118,7 +118,7 @@
 
 void FileSystemDirURLRequestJob::DidReadDirectory(
     base::File::Error result,
-    const std::vector<DirectoryEntry>& entries,
+    std::vector<DirectoryEntry> entries,
     bool has_more) {
   if (result != base::File::FILE_OK) {
     int rv = net::ERR_FILE_NOT_FOUND;
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job.h b/storage/browser/fileapi/file_system_dir_url_request_job.h
index 65bcf79..1a105014 100644
--- a/storage/browser/fileapi/file_system_dir_url_request_job.h
+++ b/storage/browser/fileapi/file_system_dir_url_request_job.h
@@ -51,7 +51,7 @@
   void StartAsync();
   void DidAttemptAutoMount(base::File::Error result);
   void DidReadDirectory(base::File::Error result,
-                        const std::vector<DirectoryEntry>& entries,
+                        std::vector<DirectoryEntry> entries,
                         bool has_more);
 
   // Reads metadata for the |index|-th entry in the directory. Must be called
diff --git a/storage/browser/fileapi/file_system_operation.h b/storage/browser/fileapi/file_system_operation.h
index 51068286..f2d77f33 100644
--- a/storage/browser/fileapi/file_system_operation.h
+++ b/storage/browser/fileapi/file_system_operation.h
@@ -88,10 +88,9 @@
   // Used for ReadDirectory(). |result| is the return code of the operation,
   // |file_list| is the list of files read, and |has_more| is true if some files
   // are yet to be read.
-  typedef base::Callback<
-      void(base::File::Error result,
-           const FileEntryList& file_list,
-           bool has_more)> ReadDirectoryCallback;
+  typedef base::RepeatingCallback<
+      void(base::File::Error result, FileEntryList file_list, bool has_more)>
+      ReadDirectoryCallback;
 
   // Used for CreateSnapshotFile(). (Please see the comment at
   // CreateSnapshotFile() below for how the method is called)
diff --git a/storage/browser/fileapi/file_system_operation_impl_unittest.cc b/storage/browser/fileapi/file_system_operation_impl_unittest.cc
index 1271231..aa82eab9 100644
--- a/storage/browser/fileapi/file_system_operation_impl_unittest.cc
+++ b/storage/browser/fileapi/file_system_operation_impl_unittest.cc
@@ -182,12 +182,11 @@
   }
 
   FileSystemOperation::ReadDirectoryCallback RecordReadDirectoryCallback(
-      const base::Closure& closure,
+      base::RepeatingClosure closure,
       base::File::Error* status) {
-    return base::Bind(&FileSystemOperationImplTest::DidReadDirectory,
-                      weak_factory_.GetWeakPtr(),
-                      closure,
-                      status);
+    return base::BindRepeating(&FileSystemOperationImplTest::DidReadDirectory,
+                               weak_factory_.GetWeakPtr(), std::move(closure),
+                               status);
   }
 
   FileSystemOperation::GetMetadataCallback RecordMetadataCallback(
@@ -215,12 +214,12 @@
     closure.Run();
   }
 
-  void DidReadDirectory(const base::Closure& closure,
+  void DidReadDirectory(base::RepeatingClosure closure,
                         base::File::Error* status,
                         base::File::Error actual,
-                        const std::vector<storage::DirectoryEntry>& entries,
+                        std::vector<storage::DirectoryEntry> entries,
                         bool /* has_more */) {
-    entries_ = entries;
+    entries_ = std::move(entries);
     *status = actual;
     closure.Run();
   }
diff --git a/storage/browser/fileapi/file_system_operation_runner.cc b/storage/browser/fileapi/file_system_operation_runner.cc
index 7ac92c3..8f332a9 100644
--- a/storage/browser/fileapi/file_system_operation_runner.cc
+++ b/storage/browser/fileapi/file_system_operation_runner.cc
@@ -227,15 +227,14 @@
   OperationHandle handle =
       BeginOperation(std::move(operation), scope.AsWeakPtr());
   if (!operation_raw) {
-    DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(),
-                     false);
+    DidReadDirectory(handle, std::move(callback), error,
+                     std::vector<DirectoryEntry>(), false);
     return handle.id;
   }
   PrepareForRead(handle.id, url);
   operation_raw->ReadDirectory(
-      url,
-      base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(),
-                 handle, callback));
+      url, base::BindRepeating(&FileSystemOperationRunner::DidReadDirectory,
+                               AsWeakPtr(), handle, callback));
   return handle.id;
 }
 
@@ -588,17 +587,17 @@
     const OperationHandle& handle,
     const ReadDirectoryCallback& callback,
     base::File::Error rv,
-    const std::vector<DirectoryEntry>& entries,
+    std::vector<DirectoryEntry> entries,
     bool has_more) {
   if (handle.scope) {
     finished_operations_.insert(handle.id);
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory,
-                              AsWeakPtr(), handle, callback, rv,
-                              entries, has_more));
+        FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidReadDirectory,
+                                  AsWeakPtr(), handle, callback, rv,
+                                  std::move(entries), has_more));
     return;
   }
-  callback.Run(rv, entries, has_more);
+  callback.Run(rv, std::move(entries), has_more);
   if (rv != base::File::FILE_OK || !has_more)
     FinishOperation(handle.id);
 }
diff --git a/storage/browser/fileapi/file_system_operation_runner.h b/storage/browser/fileapi/file_system_operation_runner.h
index eb96fd2..3d08dc5 100644
--- a/storage/browser/fileapi/file_system_operation_runner.h
+++ b/storage/browser/fileapi/file_system_operation_runner.h
@@ -269,7 +269,7 @@
   void DidReadDirectory(const OperationHandle& handle,
                         const ReadDirectoryCallback& callback,
                         base::File::Error rv,
-                        const std::vector<DirectoryEntry>& entries,
+                        std::vector<DirectoryEntry> entries,
                         bool has_more);
   void DidWrite(const OperationHandle& handle,
                 const WriteCallback& callback,
diff --git a/storage/browser/fileapi/recursive_operation_delegate.cc b/storage/browser/fileapi/recursive_operation_delegate.cc
index 5b11f4e..b2a5a977 100644
--- a/storage/browser/fileapi/recursive_operation_delegate.cc
+++ b/storage/browser/fileapi/recursive_operation_delegate.cc
@@ -98,16 +98,14 @@
   const FileSystemURL& parent = pending_directory_stack_.top().front();
   pending_directory_stack_.push(std::queue<FileSystemURL>());
   operation_runner()->ReadDirectory(
-      parent,
-      base::Bind(&RecursiveOperationDelegate::DidReadDirectory,
-                 AsWeakPtr(), parent));
+      parent, base::BindRepeating(&RecursiveOperationDelegate::DidReadDirectory,
+                                  AsWeakPtr(), parent));
 }
 
-void RecursiveOperationDelegate::DidReadDirectory(
-    const FileSystemURL& parent,
-    base::File::Error error,
-    const FileEntryList& entries,
-    bool has_more) {
+void RecursiveOperationDelegate::DidReadDirectory(const FileSystemURL& parent,
+                                                  base::File::Error error,
+                                                  FileEntryList entries,
+                                                  bool has_more) {
   DCHECK(!pending_directory_stack_.empty());
 
   if (canceled_ || error != base::File::FILE_OK) {
diff --git a/storage/browser/fileapi/recursive_operation_delegate.h b/storage/browser/fileapi/recursive_operation_delegate.h
index dc4362e..aa47b72 100644
--- a/storage/browser/fileapi/recursive_operation_delegate.h
+++ b/storage/browser/fileapi/recursive_operation_delegate.h
@@ -133,7 +133,7 @@
   void DidProcessDirectory(base::File::Error error);
   void DidReadDirectory(const FileSystemURL& parent,
                         base::File::Error error,
-                        const FileEntryList& entries,
+                        FileEntryList entries,
                         bool has_more);
   void ProcessPendingFiles();
   void DidProcessFile(const FileSystemURL& url, base::File::Error error);
diff --git a/storage/browser/test/async_file_test_helper.cc b/storage/browser/test/async_file_test_helper.cc
index 034759c..837d1554 100644
--- a/storage/browser/test/async_file_test_helper.cc
+++ b/storage/browser/test/async_file_test_helper.cc
@@ -65,7 +65,7 @@
                            base::File::Error* result_out,
                            FileEntryList* entries_out,
                            base::File::Error result,
-                           const FileEntryList& entries,
+                           FileEntryList entries,
                            bool has_more) {
   *result_out = result;
   entries_out->insert(entries_out->end(), entries.begin(), entries.end());
@@ -150,7 +150,8 @@
   entries->clear();
   base::RunLoop run_loop;
   context->operation_runner()->ReadDirectory(
-      url, base::Bind(&ReadDirectoryCallback, &run_loop, &result, entries));
+      url,
+      base::BindRepeating(&ReadDirectoryCallback, &run_loop, &result, entries));
   run_loop.Run();
   return result;
 }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-parsing.html b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-parsing.html
new file mode 100644
index 0000000..308ff43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-parsing.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: ::slotted pseudo parsing</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="styleElm">
+</style>
+<script>
+  function parse_selector(selector_text) {
+    try {
+      styleElm.sheet.insertRule(selector_text+"{}");
+      styleElm.sheet.deleteRule(0);
+      return true;
+    } catch (ex) {
+      return false;
+    }
+  }
+
+  function test_valid_selector(selector_text) {
+    test(function(){
+      assert_true(parse_selector(selector_text));
+    }, "Should be a valid selector: '" + selector_text + "'");
+  }
+
+  function test_invalid_selector(selector_text) {
+    test(function(){
+      assert_false(parse_selector(selector_text));
+    }, "Should be an invalid selector: '" + selector_text + "'");
+  }
+
+  test_invalid_selector("::slotted");
+  test_invalid_selector("::slotted()");
+  test_invalid_selector("::slotted(*).class");
+  test_invalid_selector("::slotted(*)#id {}");
+  test_invalid_selector("::slotted(*)[attr]");
+  test_invalid_selector("::slotted(*):hover");
+  test_invalid_selector("::slotted(*):read-only");
+  test_invalid_selector("::slotted(*)::slotted(*)");
+  test_invalid_selector("::slotted(*)::before::slotted(*)");
+  test_invalid_selector("::slotted(*) span");
+
+  test_valid_selector("::slotted(*)");
+  test_valid_selector("::slotted(div)");
+  test_valid_selector("::slotted([attr]:hover)");
+  test_valid_selector("::slotted(:not(.a))");
+
+  // Allow tree-abiding pseudo elements after ::slotted
+  test_valid_selector("::slotted(*)::before");
+  test_valid_selector("::slotted(*)::after");
+
+  // Other pseudo elements not valid after ::slotted
+  test_invalid_selector("::slotted(*)::first-line");
+  test_invalid_selector("::slotted(*)::first-letter");
+  test_invalid_selector("::slotted(*)::selection");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element-ref.html
new file mode 100644
index 0000000..63677cf4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: pseudo element after ::slotted - reference</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<div>PASS</div>
+<div>PASS</div>
+<div style="color:green">PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element.html b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element.html
new file mode 100644
index 0000000..08e6dcc0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css-scoping/slotted-with-pseudo-element.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: pseudo element after ::slotted</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="match" href="slotted-with-pseudo-element-ref.html">
+<div id="host1"><span></span></div>
+<div id="host2"><span></span></div>
+<div id="host3"><span></span></div>
+<style>
+  #host3 > span::before { content: "PASS" }
+</style>
+<script>
+  function attachShadowWithSlottedStyle(host, styleString) {
+    var root = host.attachShadow({mode:"open"});
+    root.innerHTML = "<style>"+styleString+"</style><slot/>";
+  }
+
+  attachShadowWithSlottedStyle(host1, "::slotted(span)::before { content: 'PASS' }");
+  attachShadowWithSlottedStyle(host2, "::slotted(span)::after { content: 'PASS' }");
+  attachShadowWithSlottedStyle(host3, "::slotted(span)::before { content: 'FAIL'; color: green }");
+</script>
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.h b/third_party/WebKit/Source/core/css/FontFaceSet.h
index a9275645..e479e3a 100644
--- a/third_party/WebKit/Source/core/css/FontFaceSet.h
+++ b/third_party/WebKit/Source/core/css/FontFaceSet.h
@@ -60,7 +60,7 @@
   virtual size_t size() const = 0;
   virtual AtomicString status() const = 0;
 
-  DEFINE_INLINE_VIRTUAL_TRACE() {}
+  DEFINE_INLINE_VIRTUAL_TRACE() { EventTargetWithInlineData::Trace(visitor); }
 
  protected:
   // Iterable overrides.
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
index 25e4149..e63fd00 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -210,6 +210,11 @@
     return true;
   if (compound_pseudo_element == CSSSelector::kPseudoContent)
     return simple_selector.Match() != CSSSelector::kPseudoElement;
+  if (compound_pseudo_element == CSSSelector::kPseudoSlotted) {
+    return simple_selector.Match() == CSSSelector::kPseudoElement &&
+           (simple_selector.GetPseudoType() == CSSSelector::kPseudoBefore ||
+            simple_selector.GetPseudoType() == CSSSelector::kPseudoAfter);
+  }
   if (simple_selector.Match() != CSSSelector::kPseudoClass)
     return false;
   CSSSelector::PseudoType pseudo = simple_selector.GetPseudoType();
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
index b11ccb80..5859814 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
@@ -148,10 +148,13 @@
 }
 
 TEST(CSSSelectorParserTest, ValidSimpleAfterPseudoElementInCompound) {
-  const char* test_cases[] = {
-      "::-webkit-volume-slider:hover", "::selection:window-inactive",
-      "::-webkit-scrollbar:disabled", "::-webkit-volume-slider:not(:hover)",
-      "::-webkit-scrollbar:not(:horizontal)"};
+  const char* test_cases[] = {"::-webkit-volume-slider:hover",
+                              "::selection:window-inactive",
+                              "::-webkit-scrollbar:disabled",
+                              "::-webkit-volume-slider:not(:hover)",
+                              "::-webkit-scrollbar:not(:horizontal)",
+                              "::slotted(span)::before",
+                              "::slotted(div)::after"};
 
   for (auto test_case : test_cases) {
     CSSTokenizer tokenizer(test_case);
@@ -174,7 +177,14 @@
       "::shadow:not(::after)",
       "::-webkit-scrollbar:vertical:not(:first-child)",
       "video::-webkit-media-text-track-region-container.scrolling",
-      "div ::before.a"};
+      "div ::before.a",
+      "::slotted(div):hover",
+      "::slotted(div)::slotted(span)",
+      "::slotted(div)::before:hover",
+      "::slotted(div)::before::slotted(span)",
+      "::slotted(*)::first-letter",
+      "::slotted(.class)::first-line",
+      "::slotted([attr])::-webkit-scrollbar"};
 
   for (auto test_case : test_cases) {
     CSSTokenizer tokenizer(test_case);
diff --git a/third_party/WebKit/Source/core/events/EventTarget.h b/third_party/WebKit/Source/core/events/EventTarget.h
index 5c8b23bd..d597cad 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.h
+++ b/third_party/WebKit/Source/core/events/EventTarget.h
@@ -222,12 +222,7 @@
   friend class EventListenerIterator;
 };
 
-// EventTargetData is a GCed object, so it should not be used as a part of
-// object. However, we intentionally use it as a part of object for performance,
-// assuming that no one extracts a pointer of
-// EventTargetWithInlineData::m_eventTargetData and store it to a Member etc.
-class GC_PLUGIN_IGNORE("513199") CORE_EXPORT EventTargetWithInlineData
-    : public EventTarget {
+class CORE_EXPORT EventTargetWithInlineData : public EventTarget {
  public:
   ~EventTargetWithInlineData() override {}
 
@@ -246,7 +241,11 @@
   EventTargetData& EnsureEventTargetData() final { return event_target_data_; }
 
  private:
-  EventTargetData event_target_data_;
+  // EventTargetData is a GCed object, so it should not be used as a part of
+  // object. However, we intentionally use it as a part of object for
+  // performance, assuming that no one extracts a pointer of
+  // EventTargetWithInlineData::m_eventTargetData and store it to a Member etc.
+  GC_PLUGIN_IGNORE("513199") EventTargetData event_target_data_;
 };
 
 // FIXME: These macros should be split into separate DEFINE and DECLARE
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
index eef23fce..c3986a37 100644
--- a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
@@ -16,6 +16,7 @@
 #include "core/testing/DummyModulator.h"
 #include "core/testing/DummyPageHolder.h"
 #include "core/workers/MainThreadWorkletGlobalScope.h"
+#include "core/workers/MainThreadWorkletReportingProxy.h"
 #include "platform/heap/Handle.h"
 #include "platform/loader/fetch/ResourceFetcher.h"
 #include "platform/loader/testing/FetchTestingPlatformSupport.h"
@@ -131,6 +132,7 @@
  protected:
   ScopedTestingPlatformSupport<FetchTestingPlatformSupport> platform_;
   std::unique_ptr<DummyPageHolder> dummy_page_holder_;
+  std::unique_ptr<MainThreadWorkletReportingProxy> reporting_proxy_;
   Persistent<ResourceFetcher> fetcher_;
   Persistent<ModuleScriptLoaderTestModulator> modulator_;
   Persistent<MainThreadWorkletGlobalScope> global_scope_;
@@ -153,10 +155,12 @@
 }
 
 void ModuleScriptLoaderTest::InitializeForWorklet() {
+  reporting_proxy_ =
+      WTF::MakeUnique<MainThreadWorkletReportingProxy>(&GetDocument());
   global_scope_ = new MainThreadWorkletGlobalScope(
       &GetFrame(), KURL(kParsedURLString, "https://example.test/worklet.js"),
       "fake user agent", GetDocument().GetSecurityOrigin(),
-      ToIsolate(&GetDocument()));
+      ToIsolate(&GetDocument()), *reporting_proxy_);
   global_scope_->ScriptController()->InitializeContextIfNeeded("Dummy Context");
   global_scope_->SetModuleResponsesMapProxyForTesting(
       WorkletModuleResponsesMapProxy::Create(
diff --git a/third_party/WebKit/Source/core/workers/BUILD.gn b/third_party/WebKit/Source/core/workers/BUILD.gn
index 27d3114..655db1e 100644
--- a/third_party/WebKit/Source/core/workers/BUILD.gn
+++ b/third_party/WebKit/Source/core/workers/BUILD.gn
@@ -26,6 +26,8 @@
     "InstalledScriptsManager.h",
     "MainThreadWorkletGlobalScope.cpp",
     "MainThreadWorkletGlobalScope.h",
+    "MainThreadWorkletReportingProxy.cpp",
+    "MainThreadWorkletReportingProxy.h",
     "ParentFrameTaskRunners.cpp",
     "ParentFrameTaskRunners.h",
     "SharedWorker.cpp",
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
index ba04ac5..899b65b 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
@@ -18,30 +18,18 @@
     const KURL& url,
     const String& user_agent,
     RefPtr<SecurityOrigin> security_origin,
-    v8::Isolate* isolate)
+    v8::Isolate* isolate,
+    WorkerReportingProxy& reporting_proxy)
     : WorkletGlobalScope(url,
                          user_agent,
                          std::move(security_origin),
                          isolate,
-                         nullptr /* worker_clients */),
+                         nullptr /* worker_clients */,
+                         reporting_proxy),
       ContextClient(frame) {}
 
 MainThreadWorkletGlobalScope::~MainThreadWorkletGlobalScope() {}
 
-void MainThreadWorkletGlobalScope::ReportFeature(WebFeature feature) {
-  DCHECK(IsMainThread());
-  // A parent document is on the same thread, so just record API use in the
-  // document's UseCounter.
-  UseCounter::Count(GetFrame(), feature);
-}
-
-void MainThreadWorkletGlobalScope::ReportDeprecation(WebFeature feature) {
-  DCHECK(IsMainThread());
-  // A parent document is on the same thread, so just record API use in the
-  // document's UseCounter.
-  Deprecation::CountDeprecation(GetFrame(), feature);
-}
-
 WorkerThread* MainThreadWorkletGlobalScope::GetThread() const {
   NOTREACHED();
   return nullptr;
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
index 1fe0d96..5e44d380 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
@@ -14,6 +14,7 @@
 
 class ConsoleMessage;
 class LocalFrame;
+class WorkerReportingProxy;
 
 class CORE_EXPORT MainThreadWorkletGlobalScope
     : public WorkletGlobalScope,
@@ -25,13 +26,12 @@
                                const KURL&,
                                const String& user_agent,
                                RefPtr<SecurityOrigin>,
-                               v8::Isolate*);
+                               v8::Isolate*,
+                               WorkerReportingProxy&);
   ~MainThreadWorkletGlobalScope() override;
   bool IsMainThreadWorkletGlobalScope() const final { return true; }
 
   // WorkerOrWorkletGlobalScope
-  void ReportFeature(WebFeature) override;
-  void ReportDeprecation(WebFeature) override;
   WorkerThread* GetThread() const final;
 
   void Terminate();
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.cpp
new file mode 100644
index 0000000..6a0db9c
--- /dev/null
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.cpp
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/workers/MainThreadWorkletReportingProxy.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/Deprecation.h"
+#include "core/frame/UseCounter.h"
+
+namespace blink {
+
+MainThreadWorkletReportingProxy::MainThreadWorkletReportingProxy(
+    Document* document)
+    : document_(document) {}
+
+void MainThreadWorkletReportingProxy::CountFeature(WebFeature feature) {
+  DCHECK(IsMainThread());
+  // A parent document is on the same thread, so just record API use in the
+  // document's UseCounter.
+  UseCounter::Count(document_->GetFrame(), feature);
+}
+
+void MainThreadWorkletReportingProxy::CountDeprecation(WebFeature feature) {
+  DCHECK(IsMainThread());
+  // A parent document is on the same thread, so just record API use in the
+  // document's UseCounter.
+  Deprecation::CountDeprecation(document_->GetFrame(), feature);
+}
+
+void MainThreadWorkletReportingProxy::DidTerminateWorkerThread() {
+  // MainThreadWorklet does not start and terminate a thread.
+  NOTREACHED();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.h b/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.h
new file mode 100644
index 0000000..f969c1f
--- /dev/null
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletReportingProxy.h
@@ -0,0 +1,31 @@
+// 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 MainThreadWorkletReportingProxy_h
+#define MainThreadWorkletReportingProxy_h
+
+#include "core/workers/WorkerReportingProxy.h"
+
+namespace blink {
+
+class Document;
+
+class CORE_EXPORT MainThreadWorkletReportingProxy
+    : public WorkerReportingProxy {
+ public:
+  explicit MainThreadWorkletReportingProxy(Document*);
+  ~MainThreadWorkletReportingProxy() override = default;
+
+  // Implements WorkerReportingProxy.
+  void CountFeature(WebFeature) override;
+  void CountDeprecation(WebFeature) override;
+  void DidTerminateWorkerThread() override;
+
+ private:
+  Persistent<Document> document_;
+};
+
+}  // namespace blink
+
+#endif  // MainThreadWorkletReportingProxy_h
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
index c36fba88..5438647 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
@@ -7,38 +7,31 @@
 #include "core/frame/UseCounter.h"
 #include "core/testing/DummyPageHolder.h"
 #include "core/workers/MainThreadWorkletGlobalScope.h"
+#include "core/workers/MainThreadWorkletReportingProxy.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
-class MainThreadWorkletGlobalScopeForTest
-    : public MainThreadWorkletGlobalScope {
+class MainThreadWorkletReportingProxyForTest final
+    : public MainThreadWorkletReportingProxy {
  public:
-  MainThreadWorkletGlobalScopeForTest(LocalFrame* frame,
-                                      const KURL& url,
-                                      const String& user_agent,
-                                      RefPtr<SecurityOrigin> security_origin,
-                                      v8::Isolate* isolate)
-      : MainThreadWorkletGlobalScope(frame,
-                                     url,
-                                     user_agent,
-                                     std::move(security_origin),
-                                     isolate),
+  explicit MainThreadWorkletReportingProxyForTest(Document* document)
+      : MainThreadWorkletReportingProxy(document),
         reported_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {}
 
-  void ReportFeature(WebFeature feature) override {
+  void CountFeature(WebFeature feature) override {
     // Any feature should be reported only one time.
     EXPECT_FALSE(reported_features_.QuickGet(static_cast<int>(feature)));
     reported_features_.QuickSet(static_cast<int>(feature));
-    MainThreadWorkletGlobalScope::ReportFeature(feature);
+    MainThreadWorkletReportingProxy::CountFeature(feature);
   }
 
-  void ReportDeprecation(WebFeature feature) final {
+  void CountDeprecation(WebFeature feature) override {
     // Any feature should be reported only one time.
     EXPECT_FALSE(reported_features_.QuickGet(static_cast<int>(feature)));
     reported_features_.QuickSet(static_cast<int>(feature));
-    MainThreadWorkletGlobalScope::ReportDeprecation(feature);
+    MainThreadWorkletReportingProxy::CountDeprecation(feature);
   }
 
  private:
@@ -51,9 +44,11 @@
     KURL url(kParsedURLString, "https://example.com/");
     page_ = DummyPageHolder::Create();
     security_origin_ = SecurityOrigin::Create(url);
+    reporting_proxy_ = WTF::MakeUnique<MainThreadWorkletReportingProxyForTest>(
+        page_->GetFrame().GetDocument());
     global_scope_ = new MainThreadWorkletGlobalScope(
         &page_->GetFrame(), url, "fake user agent", security_origin_.Get(),
-        ToIsolate(page_->GetFrame().GetDocument()));
+        ToIsolate(page_->GetFrame().GetDocument()), *reporting_proxy_);
   }
 
   void TearDown() override { global_scope_->Terminate(); }
@@ -61,6 +56,7 @@
  protected:
   RefPtr<SecurityOrigin> security_origin_;
   std::unique_ptr<DummyPageHolder> page_;
+  std::unique_ptr<MainThreadWorkletReportingProxyForTest> reporting_proxy_;
   Persistent<MainThreadWorkletGlobalScope> global_scope_;
 };
 
@@ -77,7 +73,7 @@
   EXPECT_TRUE(UseCounter::IsCounted(document, kFeature1));
 
   // API use should be reported to the Document only one time. See comments in
-  // MainThreadGlobalScopeForTest::ReportFeature.
+  // MainThreadWorkletReportingProxyForTest::ReportFeature.
   UseCounter::Count(global_scope_, kFeature1);
 
   // This feature is randomly selected from Deprecation::deprecationMessage().
@@ -90,7 +86,7 @@
   EXPECT_TRUE(UseCounter::IsCounted(document, kFeature2));
 
   // API use should be reported to the Document only one time. See comments in
-  // MainThreadWorkletGlobalScopeForTest::ReportDeprecation.
+  // MainThreadWorkletReportingProxyForTest::ReportDeprecation.
   Deprecation::CountDeprecation(global_scope_, kFeature2);
 }
 
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.cpp
index 22962be..d1455041 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.cpp
@@ -28,25 +28,14 @@
                          user_agent,
                          std::move(security_origin),
                          isolate,
-                         worker_clients),
+                         worker_clients,
+                         thread->GetWorkerReportingProxy()),
       thread_(thread) {}
 
 ThreadedWorkletGlobalScope::~ThreadedWorkletGlobalScope() {
   DCHECK(!thread_);
 }
 
-void ThreadedWorkletGlobalScope::ReportFeature(WebFeature feature) {
-  DCHECK(IsContextThread());
-  DCHECK(thread_);
-  thread_->GetWorkerReportingProxy().CountFeature(feature);
-}
-
-void ThreadedWorkletGlobalScope::ReportDeprecation(WebFeature feature) {
-  DCHECK(IsContextThread());
-  DCHECK(thread_);
-  thread_->GetWorkerReportingProxy().CountDeprecation(feature);
-}
-
 void ThreadedWorkletGlobalScope::Dispose() {
   DCHECK(IsContextThread());
   WorkletGlobalScope::Dispose();
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.h
index 945f7e1..d73ea58 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletGlobalScope.h
@@ -16,8 +16,6 @@
  public:
   ~ThreadedWorkletGlobalScope() override;
   void Dispose() override;
-  void ReportFeature(WebFeature) override;
-  void ReportDeprecation(WebFeature) override;
 
   // ExecutionContext
   bool IsThreadedWorkletGlobalScope() const final { return true; }
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index 21c98ecf0..99226ad 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -97,13 +97,13 @@
   CachedMetadataHandler* handler = CreateWorkerScriptCachedMetadataHandler(
       script_url, cached_meta_data.get());
   DCHECK(!source_code.IsNull());
-  GetThread()->GetWorkerReportingProxy().WillEvaluateWorkerScript(
+  ReportingProxy().WillEvaluateWorkerScript(
       source_code.length(),
       cached_meta_data.get() ? cached_meta_data->size() : 0);
   bool success = ScriptController()->Evaluate(
       ScriptSourceCode(source_code, script_url), nullptr /* error_event */,
       handler, v8_cache_options);
-  GetThread()->GetWorkerReportingProxy().DidEvaluateWorkerScript(success);
+  ReportingProxy().DidEvaluateWorkerScript(success);
 }
 
 void WorkerGlobalScope::Dispose() {
@@ -128,18 +128,6 @@
   WorkerOrWorkletGlobalScope::Dispose();
 }
 
-void WorkerGlobalScope::ReportFeature(WebFeature feature) {
-  DCHECK(IsContextThread());
-  DCHECK(thread_);
-  thread_->GetWorkerReportingProxy().CountFeature(feature);
-}
-
-void WorkerGlobalScope::ReportDeprecation(WebFeature feature) {
-  DCHECK(IsContextThread());
-  DCHECK(thread_);
-  thread_->GetWorkerReportingProxy().CountDeprecation(feature);
-}
-
 void WorkerGlobalScope::ExceptionUnhandled(int exception_id) {
   ErrorEvent* event = pending_error_events_.Take(exception_id);
   DCHECK(event);
@@ -237,7 +225,7 @@
     ErrorEvent* error_event = nullptr;
     CachedMetadataHandler* handler(CreateWorkerScriptCachedMetadataHandler(
         complete_url, cached_meta_data.get()));
-    GetThread()->GetWorkerReportingProxy().WillEvaluateImportedScript(
+    ReportingProxy().WillEvaluateImportedScript(
         source_code.length(), cached_meta_data ? cached_meta_data->size() : 0);
     ScriptController()->Evaluate(ScriptSourceCode(source_code, response_url),
                                  &error_event, handler, v8_cache_options_);
@@ -337,7 +325,7 @@
 
 void WorkerGlobalScope::AddConsoleMessage(ConsoleMessage* console_message) {
   DCHECK(IsContextThread());
-  GetThread()->GetWorkerReportingProxy().ReportConsoleMessage(
+  ReportingProxy().ReportConsoleMessage(
       console_message->Source(), console_message->Level(),
       console_message->Message(), console_message->Location());
   GetThread()->GetConsoleMessageStorage()->AddConsoleMessage(this,
@@ -382,7 +370,9 @@
     std::unique_ptr<SecurityOrigin::PrivilegeData>
         starter_origin_privilage_data,
     WorkerClients* worker_clients)
-    : WorkerOrWorkletGlobalScope(thread->GetIsolate(), worker_clients),
+    : WorkerOrWorkletGlobalScope(thread->GetIsolate(),
+                                 worker_clients,
+                                 thread->GetWorkerReportingProxy()),
       url_(url),
       user_agent_(user_agent),
       v8_cache_options_(kV8CacheOptionsDefault),
@@ -433,8 +423,8 @@
 void WorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
   int next_id = ++last_pending_error_event_id_;
   pending_error_events_.Set(next_id, event);
-  GetThread()->GetWorkerReportingProxy().ReportException(
-      event->MessageForConsole(), event->Location()->Clone(), next_id);
+  ReportingProxy().ReportException(event->MessageForConsole(),
+                                   event->Location()->Clone(), next_id);
 }
 
 void WorkerGlobalScope::RemoveURLFromMemoryCache(const KURL& url) {
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index 09f56d8..b150862 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -86,8 +86,6 @@
                              V8CacheOptions) final;
   bool IsClosing() const final { return closing_; }
   virtual void Dispose();
-  void ReportFeature(WebFeature) final;
-  void ReportDeprecation(WebFeature) final;
   WorkerThread* GetThread() const final { return thread_; }
 
   void ExceptionUnhandled(int exception_id);
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
index 117baf3..6a463f17 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
@@ -21,10 +21,12 @@
 
 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(
     v8::Isolate* isolate,
-    WorkerClients* worker_clients)
+    WorkerClients* worker_clients,
+    WorkerReportingProxy& reporting_proxy)
     : worker_clients_(worker_clients),
       script_controller_(
           WorkerOrWorkletScriptController::Create(this, isolate)),
+      reporting_proxy_(reporting_proxy),
       used_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {
   if (worker_clients_)
     worker_clients_->ReattachThread();
@@ -33,15 +35,17 @@
 WorkerOrWorkletGlobalScope::~WorkerOrWorkletGlobalScope() = default;
 
 void WorkerOrWorkletGlobalScope::CountFeature(WebFeature feature) {
+  DCHECK(IsContextThread());
   DCHECK_NE(WebFeature::kOBSOLETE_PageDestruction, feature);
   DCHECK_GT(WebFeature::kNumberOfFeatures, feature);
   if (used_features_.QuickGet(static_cast<int>(feature)))
     return;
   used_features_.QuickSet(static_cast<int>(feature));
-  ReportFeature(feature);
+  ReportingProxy().CountFeature(feature);
 }
 
 void WorkerOrWorkletGlobalScope::CountDeprecation(WebFeature feature) {
+  DCHECK(IsContextThread());
   DCHECK_NE(WebFeature::kOBSOLETE_PageDestruction, feature);
   DCHECK_GT(WebFeature::kNumberOfFeatures, feature);
   if (used_features_.QuickGet(static_cast<int>(feature)))
@@ -53,8 +57,7 @@
   AddConsoleMessage(
       ConsoleMessage::Create(kDeprecationMessageSource, kWarningMessageLevel,
                              Deprecation::DeprecationMessage(feature)));
-
-  ReportDeprecation(feature);
+  ReportingProxy().CountDeprecation(feature);
 }
 
 ResourceFetcher* WorkerOrWorkletGlobalScope::GetResourceFetcher() {
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
index f28fe1a..d111177 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
@@ -15,11 +15,14 @@
 class ResourceFetcher;
 class ScriptWrappable;
 class WorkerOrWorkletScriptController;
+class WorkerReportingProxy;
 class WorkerThread;
 
 class CORE_EXPORT WorkerOrWorkletGlobalScope : public ExecutionContext {
  public:
-  WorkerOrWorkletGlobalScope(v8::Isolate*, WorkerClients*);
+  WorkerOrWorkletGlobalScope(v8::Isolate*,
+                             WorkerClients*,
+                             WorkerReportingProxy&);
   virtual ~WorkerOrWorkletGlobalScope();
 
   // ExecutionContext
@@ -69,17 +72,17 @@
     return script_controller_.Get();
   }
 
-  DECLARE_VIRTUAL_TRACE();
+  WorkerReportingProxy& ReportingProxy() { return reporting_proxy_; }
 
- protected:
-  virtual void ReportFeature(WebFeature) = 0;
-  virtual void ReportDeprecation(WebFeature) = 0;
+  DECLARE_VIRTUAL_TRACE();
 
  private:
   CrossThreadPersistent<WorkerClients> worker_clients_;
   Member<ResourceFetcher> resource_fetcher_;
   Member<WorkerOrWorkletScriptController> script_controller_;
 
+  WorkerReportingProxy& reporting_proxy_;
+
   // This is the set of features that this worker has used.
   BitVector used_features_;
 };
diff --git a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
index f3e40f46..8c4e9fb 100644
--- a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
+++ b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
@@ -32,6 +32,7 @@
 #define WorkerReportingProxy_h
 
 #include <memory>
+#include "bindings/core/v8/SourceLocation.h"
 #include "core/CoreExport.h"
 #include "core/frame/UseCounter.h"
 #include "core/inspector/ConsoleTypes.h"
@@ -41,7 +42,6 @@
 
 namespace blink {
 
-class SourceLocation;
 class WorkerOrWorkletGlobalScope;
 
 // APIs used by workers to report console and worker activity.
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
index 87da7b6..fa954aa 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
@@ -24,8 +24,9 @@
                                        const String& user_agent,
                                        RefPtr<SecurityOrigin> security_origin,
                                        v8::Isolate* isolate,
-                                       WorkerClients* worker_clients)
-    : WorkerOrWorkletGlobalScope(isolate, worker_clients),
+                                       WorkerClients* worker_clients,
+                                       WorkerReportingProxy& reporting_proxy)
+    : WorkerOrWorkletGlobalScope(isolate, worker_clients, reporting_proxy),
       url_(url),
       user_agent_(user_agent) {
   SetSecurityOrigin(std::move(security_origin));
@@ -46,9 +47,13 @@
     return;
   }
   DCHECK(!cached_meta_data);
+  // TODO(nhiroki): Call WorkerReportingProxy::WillEvaluateWorkerScript() or
+  // something like that (e.g., WillEvaluateModuleScript()).
   ScriptController()->Evaluate(ScriptSourceCode(source_code, script_url),
                                nullptr /* error_event */,
                                nullptr /* cache_handler */, v8_cache_options);
+  // TODO(nhiroki): Call WorkerReportingProxy::DidEvaluateWorkerScript() or
+  // something like that (e.g., DidEvaluateModuleScript()).
 }
 
 v8::Local<v8::Object> WorkletGlobalScope::Wrap(
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
index 65aa9b2..37f39fa 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
@@ -25,6 +25,7 @@
 class Modulator;
 class WorkletModuleResponsesMap;
 class WorkletPendingTasks;
+class WorkerReportingProxy;
 
 class CORE_EXPORT WorkletGlobalScope
     : public GarbageCollectedFinalized<WorkletGlobalScope>,
@@ -108,7 +109,8 @@
                      const String& user_agent,
                      RefPtr<SecurityOrigin>,
                      v8::Isolate*,
-                     WorkerClients*);
+                     WorkerClients*,
+                     WorkerReportingProxy&);
 
  private:
   const KURL& VirtualURL() const final { return url_; }
diff --git a/third_party/WebKit/Source/core/workers/WorkletModuleTreeClient.cpp b/third_party/WebKit/Source/core/workers/WorkletModuleTreeClient.cpp
index 36be131..2762fde 100644
--- a/third_party/WebKit/Source/core/workers/WorkletModuleTreeClient.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkletModuleTreeClient.cpp
@@ -34,8 +34,12 @@
     return;
   }
 
+  // TODO(nhiroki): Call WorkerReportingProxy::WillEvaluateWorkerScript() or
+  // something like that (e.g., WillEvaluateModuleScript()).
   // Step 4: "Run a module script given script."
   modulator_->ExecuteModule(module_script);
+  // TODO(nhiroki): Call WorkerReportingProxy::DidEvaluateWorkerScript() or
+  // something like that (e.g., DidEvaluateModuleScript()).
 
   // Step 5: "Queue a task on outsideSettings's responsible event loop to run
   // these steps:"
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
index f92299a..47624929 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
@@ -28,12 +28,13 @@
     const String& user_agent,
     PassRefPtr<SecurityOrigin> security_origin,
     v8::Isolate* isolate,
+    WorkerReportingProxy& reporting_proxy,
     PaintWorkletPendingGeneratorRegistry* pending_generator_registry,
     size_t global_scope_number) {
   PaintWorkletGlobalScope* paint_worklet_global_scope =
       new PaintWorkletGlobalScope(frame, url, user_agent,
                                   std::move(security_origin), isolate,
-                                  pending_generator_registry);
+                                  reporting_proxy, pending_generator_registry);
   String context_name("PaintWorklet #");
   context_name.append(String::Number(global_scope_number));
   paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded(
@@ -51,12 +52,14 @@
     const String& user_agent,
     PassRefPtr<SecurityOrigin> security_origin,
     v8::Isolate* isolate,
+    WorkerReportingProxy& reporting_proxy,
     PaintWorkletPendingGeneratorRegistry* pending_generator_registry)
     : MainThreadWorkletGlobalScope(frame,
                                    url,
                                    user_agent,
                                    std::move(security_origin),
-                                   isolate),
+                                   isolate,
+                                   reporting_proxy),
       pending_generator_registry_(pending_generator_registry) {}
 
 PaintWorkletGlobalScope::~PaintWorkletGlobalScope() {}
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
index c0ffe68a..dab7a2e 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
@@ -17,6 +17,7 @@
 
 class CSSPaintDefinition;
 class ExceptionState;
+class WorkerReportingProxy;
 
 class MODULES_EXPORT PaintWorkletGlobalScope final
     : public MainThreadWorkletGlobalScope {
@@ -29,6 +30,7 @@
                                          const String& user_agent,
                                          PassRefPtr<SecurityOrigin>,
                                          v8::Isolate*,
+                                         WorkerReportingProxy&,
                                          PaintWorkletPendingGeneratorRegistry*,
                                          size_t global_scope_number);
   ~PaintWorkletGlobalScope() override;
@@ -51,6 +53,7 @@
                           const String& user_agent,
                           PassRefPtr<SecurityOrigin>,
                           v8::Isolate*,
+                          WorkerReportingProxy&,
                           PaintWorkletPendingGeneratorRegistry*);
 
   // The implementation of the "paint definition" concept:
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
index 83d66a2..eda8c12 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
@@ -24,9 +24,10 @@
     size_t global_scope_number) {
   DCHECK(IsMainThread());
   Document* document = frame->GetDocument();
+  reporting_proxy_ = WTF::MakeUnique<MainThreadWorkletReportingProxy>(document);
   global_scope_ = PaintWorkletGlobalScope::Create(
       frame, document->Url(), document->UserAgent(),
-      document->GetSecurityOrigin(), ToIsolate(document),
+      document->GetSecurityOrigin(), ToIsolate(document), *reporting_proxy_,
       pending_generator_registry, global_scope_number);
 }
 
@@ -50,8 +51,9 @@
 void PaintWorkletGlobalScopeProxy::TerminateWorkletGlobalScope() {
   DCHECK(IsMainThread());
   global_scope_->Terminate();
-  // Nullify the global scope to cut a potential reference cycle.
+  // Nullify these fields to cut a potential reference cycle.
   global_scope_ = nullptr;
+  reporting_proxy_.reset();
 }
 
 CSSPaintDefinition* PaintWorkletGlobalScopeProxy::FindDefinition(
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
index 6e451ffb..1534af2 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
@@ -7,6 +7,7 @@
 
 #include "core/workers/WorkletGlobalScopeProxy.h"
 
+#include "core/workers/MainThreadWorkletReportingProxy.h"
 #include "modules/ModulesExport.h"
 #include "modules/csspaint/PaintWorkletGlobalScope.h"
 
@@ -45,6 +46,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
+  std::unique_ptr<MainThreadWorkletReportingProxy> reporting_proxy_;
   Member<PaintWorkletGlobalScope> global_scope_;
 };
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
index 42874b9a..a14a81e 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.cpp
@@ -102,4 +102,9 @@
   visitor->Trace(observer_ids_);
 }
 
+DEFINE_TRACE_WRAPPERS(IDBObserver) {
+  visitor->TraceWrappers(callback_);
+  ScriptWrappable::TraceWrappers(visitor);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.h b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.h
index 27a87cc..1573b7db 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObserver.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObserver.h
@@ -8,6 +8,7 @@
 #include "modules/ModulesExport.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/ScriptWrappable.h"
+#include "platform/bindings/TraceWrapperMember.h"
 #include "platform/heap/Handle.h"
 #include "public/platform/WebVector.h"
 #include "public/platform/modules/indexeddb/WebIDBTypes.h"
@@ -37,11 +38,12 @@
   void unobserve(IDBDatabase*, ExceptionState&);
 
   DECLARE_TRACE();
+  DECLARE_TRACE_WRAPPERS();
 
  private:
   explicit IDBObserver(IDBObserverCallback*);
 
-  Member<IDBObserverCallback> callback_;
+  TraceWrapperMember<IDBObserverCallback> callback_;
   HeapHashMap<int32_t, WeakMember<IDBDatabase>> observer_ids_;
 };
 
diff --git a/third_party/libpng/OWNERS b/third_party/libpng/OWNERS
index 312b5da..6b9f107 100644
--- a/third_party/libpng/OWNERS
+++ b/third_party/libpng/OWNERS
@@ -1,4 +1,3 @@
-msarett@chromium.org
 scroggo@chromium.org
 
 # COMPONENT: Internals>Images>Codecs
diff --git a/third_party/zlib/OWNERS b/third_party/zlib/OWNERS
index 8d825bf6..3dd8bfb 100644
--- a/third_party/zlib/OWNERS
+++ b/third_party/zlib/OWNERS
@@ -1,7 +1,6 @@
 agl@chromium.org
 cblume@chromium.org
 gavinp@chromium.org
-msarett@chromium.org
 mtklein@chromium.org
 scroggo@chromium.org
 
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
index 55373cc..8bf0f74 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "build/build_config.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h"
@@ -47,6 +48,18 @@
   AnnotationInstance* instance;
 };
 
+// Removes all occurances of a charcter from a string and returns the modified
+// string.
+std::string RemoveChar(const std::string& source, char removee) {
+  std::string output;
+  output.reserve(source.length());
+  for (const char* current = source.data(); *current; current++) {
+    if (*current != removee)
+      output += *current;
+  }
+  return output;
+}
+
 const std::string kBlockTypes[] = {"ASSIGNMENT", "ANNOTATION", "CALL"};
 
 const base::FilePath kSafeListPath(
@@ -165,12 +178,15 @@
   if (!safe_list_loaded_ && !LoadSafeList())
     return false;
   // Remove possible carriage return characters before splitting lines.
-  base::RemoveChars(clang_tool_raw_output_, "\r", &clang_tool_raw_output_);
+  // Not using base::RemoveChars as the input is ~47M and the implementation is
+  // too slow for it.
   std::vector<std::string> lines =
-      base::SplitString(clang_tool_raw_output_, "\n", base::KEEP_WHITESPACE,
-                        base::SPLIT_WANT_ALL);
+      base::SplitString(RemoveChar(clang_tool_raw_output_, '\r'), "\n",
+                        base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
   for (unsigned int current = 0; current < lines.size(); current++) {
-    if (lines[current].empty())
+    // All blocks reported by clang tool start with '====', so we can ignore
+    // all lines that do not start with a '='.
+    if (lines[current].empty() || lines[current][0] != '=')
       continue;
 
     std::string block_type;
@@ -184,10 +200,9 @@
       }
     }
 
-    if (block_type.empty()) {
-      LOG(ERROR) << "Unexpected token at line: " << current;
-      return false;
-    }
+    // If not starting a valid block, ignore the line.
+    if (block_type.empty())
+      continue;
 
     // Get the block.
     current++;
@@ -473,9 +488,15 @@
   std::string gn_output;
   if (gn_file_for_test_.empty()) {
     // Check if the file including this function is part of Chrome build.
-    const base::CommandLine::CharType* args[] = {FILE_PATH_LITERAL("gn"),
-                                                 FILE_PATH_LITERAL("refs"),
-                                                 FILE_PATH_LITERAL("--all")};
+    const base::CommandLine::CharType* args[] = {
+#if defined(OS_WIN)
+      FILE_PATH_LITERAL("gn.bat"),
+#else
+      FILE_PATH_LITERAL("gn"),
+#endif
+      FILE_PATH_LITERAL("refs"),
+      FILE_PATH_LITERAL("--all")
+    };
 
     base::CommandLine cmdline(3, args);
     cmdline.AppendArgPath(build_path_);
@@ -484,12 +505,10 @@
     base::FilePath original_path;
     base::GetCurrentDirectory(&original_path);
     base::SetCurrentDirectory(source_path_);
-
     if (!base::GetAppOutput(cmdline, &gn_output)) {
       LOG(ERROR) << "Could not run gn to get dependencies.";
       gn_output.clear();
     }
-
     base::SetCurrentDirectory(original_path);
   } else {
     if (!base::ReadFileToString(gn_file_for_test_, &gn_output)) {
diff --git a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
index 449a5463..40fe7db 100644
--- a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
+++ b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
@@ -65,5 +65,9 @@
 
   delete[] blob.data;
 
-  return 0;
+  // v8::SnapshotCreator used in WebV8ContextSnapshot makes it complex how to
+  // manage lifetime of v8::Isolate, gin::IsolateHolder, and
+  // blink::V8PerIsolateData. Now we complete all works at this point, and can
+  // exit without releasing all those instances correctly.
+  _exit(0);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/app_state_controller.js b/ui/file_manager/file_manager/foreground/js/app_state_controller.js
index a38d143..35f4acb1 100644
--- a/ui/file_manager/file_manager/foreground/js/app_state_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/app_state_controller.js
@@ -28,9 +28,35 @@
    * @private
    */
   this.viewOptions_ = null;
+
+  /**
+   * Preferred sort field of file list. This will be ignored in the Recent
+   * folder, since it always uses descendant order of date-mofidied.
+   * @private {string}
+   */
+  this.fileListSortField_ = AppStateController.DEFAULT_SORT_FIELD;
+
+  /**
+   * Preferred sort direction of file list. This will be ignored in the Recent
+   * folder, since it always uses descendant order of date-mofidied.
+   * @private {string}
+   */
+  this.fileListSortDirection_ = AppStateController.DEFAULT_SORT_DIRECTION;
 };
 
 /**
+ * Default sort field of the file list.
+ * @const {string}
+ */
+AppStateController.DEFAULT_SORT_FIELD = 'modificationTime';
+
+/**
+ * Default sort direction of the file list.
+ * @const {string}
+ */
+AppStateController.DEFAULT_SORT_DIRECTION = 'desc';
+
+/**
  * @return {Promise}
  */
 AppStateController.prototype.loadInitialViewOptions = function() {
@@ -82,16 +108,19 @@
   ui.listContainer.table.addEventListener(
       'column-resize-end', this.saveViewOptions.bind(this));
   directoryModel.getFileList().addEventListener(
-      'permuted', this.saveViewOptions.bind(this));
+      'sorted', this.onFileListSorted_.bind(this));
   directoryModel.addEventListener(
       'directory-changed', this.onDirectoryChanged_.bind(this));
 
   // Restore preferences.
   this.ui_.setCurrentListType(
       this.viewOptions_.listType || ListContainer.ListType.DETAIL);
+  if (this.viewOptions_.sortField)
+    this.fileListSortField_ = this.viewOptions_.sortField;
+  if (this.viewOptions_.sortDirection)
+    this.fileListSortDirection_ = this.viewOptions_.sortDirection;
   this.directoryModel_.getFileList().sort(
-      this.viewOptions_.sortField || 'modificationTime',
-      this.viewOptions_.sortDirection || 'desc');
+      this.fileListSortField_, this.fileListSortDirection_);
   if (this.viewOptions_.columnConfig) {
     this.ui_.listContainer.table.columnModel.restoreColumnConfig(
         this.viewOptions_.columnConfig);
@@ -102,10 +131,9 @@
  * Saves current view option.
  */
 AppStateController.prototype.saveViewOptions = function() {
-  var sortStatus = this.directoryModel_.getFileList().sortStatus;
   var prefs = {
-    sortField: sortStatus.field,
-    sortDirection: sortStatus.direction,
+    sortField: this.fileListSortField_,
+    sortDirection: this.fileListSortDirection_,
     columnConfig: {},
     listType: this.ui_.listContainer.currentListType,
   };
@@ -127,10 +155,46 @@
   }
 };
 
+AppStateController.prototype.onFileListSorted_ = function() {
+  var currentDirectory = this.directoryModel_.getCurrentDirEntry();
+  if (!currentDirectory)
+    return;
+
+  // Update preferred sort field and direction only when the current directory
+  // is not Recent folder.
+  if (!util.isRecentRoot(currentDirectory)) {
+    var currentSortStatus = this.directoryModel_.getFileList().sortStatus;
+    this.fileListSortField_ = currentSortStatus.field;
+    this.fileListSortDirection_ = currentSortStatus.direction;
+  }
+  this.saveViewOptions();
+};
+
 /**
+ * @param {Event} event
  * @private
  */
-AppStateController.prototype.onDirectoryChanged_ = function() {
+AppStateController.prototype.onDirectoryChanged_ = function(event) {
+  if (!event.newDirEntry)
+    return;
+
+  // Sort the file list by:
+  // 1) 'date-mofidied' and 'desc' order on Recent folder.
+  // 2) preferred field and direction on other folders.
+  var isOnRecent = util.isRecentRoot(event.newDirEntry);
+  var isOnRecentBefore =
+      event.previousDirEntry && util.isRecentRoot(event.previousDirEntry);
+  if (isOnRecent != isOnRecentBefore) {
+    if (isOnRecent) {
+      this.directoryModel_.getFileList().sort(
+          AppStateController.DEFAULT_SORT_FIELD,
+          AppStateController.DEFAULT_SORT_DIRECTION);
+    } else {
+      this.directoryModel_.getFileList().sort(
+          this.fileListSortField_, this.fileListSortDirection_);
+    }
+  }
+
   // TODO(mtomasz): Consider remembering the selection.
   util.updateAppState(
       this.directoryModel_.getCurrentDirEntry() ?
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
index 4c81944..9c117ce 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -235,13 +235,38 @@
  * @this {cr.ui.ListSelectionController}
  */
 filelist.handleTap = function(e, index, eventType) {
-  if (index == -1) {
+  var isTap = eventType == FileTapHandler.TapEvent.TAP ||
+      eventType == FileTapHandler.TapEvent.LONG_TAP ||
+      eventType == FileTapHandler.TapEvent.TWO_FINGER_TAP;
+  if (isTap && index == -1) {
     return false;
   }
+
   var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
       (this.selectionModel);
-  var isTap = eventType == FileTapHandler.TapEvent.TAP ||
-      eventType == FileTapHandler.TapEvent.LONG_TAP;
+  if (eventType == FileTapHandler.TapEvent.TWO_FINGER_TAP) {
+    // Prepare to open the context menu in the same manner as the right click.
+    // If the target is any of the selected files, open a one for those files.
+    // If the target is a non-selected file, cancel current selection and open
+    // context menu for the single file.
+    // Otherwise (when the target is the background), for the current folder.
+    var indexSelected = sm.getIndexSelected(index);
+    if (!indexSelected) {
+      // Prepare to open context menu of the new item by selecting only it.
+      if (sm.getCheckSelectMode()) {
+        // Unselect all items once to ensure that the check-select mode is
+        // terminated.
+        sm.unselectAll();
+      }
+      sm.beginChange();
+      sm.selectedIndex = index;
+      sm.endChange();
+    }
+
+    // Context menu will be opened for the selected files by the following
+    // 'contextmenu' event.
+    return false;
+  }
   if (eventType == FileTapHandler.TapEvent.TAP &&
       e.target.classList.contains('detail-checkmark')) {
     // Single tap on the checkbox in the list view mode should toggle select,
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_tap_handler.js b/ui/file_manager/file_manager/foreground/js/ui/file_tap_handler.js
index 7305a157..035d75f 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_tap_handler.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_tap_handler.js
@@ -30,6 +30,12 @@
    * @type {boolean}
    * @private
    */
+  this.isTwoFingerTap_ = false;
+
+  /**
+   * @type {boolean}
+   * @private
+   */
   this.hasLongPressProcessed_ = false;
 
   /**
@@ -59,7 +65,14 @@
    * @type {number|undefined}
    * @private
    */
-  this.activeTouch_ = undefined;
+  this.activeTouchId_ = undefined;
+
+  /**
+   * The index of the item which is being touched by the active touch. This is
+   * valid only when |activeTouchId_| is defined.
+   * @type {number}
+   */
+  this.activeItemIndex_ = -1;
 }
 
 /**
@@ -87,7 +100,8 @@
 FileTapHandler.TapEvent = {
   TAP: 'tap',
   LONG_PRESS: 'longpress',
-  LONG_TAP: 'longtap'
+  LONG_TAP: 'longtap',
+  TWO_FINGER_TAP: 'twofingertap'
 };
 
 /**
@@ -106,16 +120,12 @@
 FileTapHandler.prototype.handleTouchEvents = function(event, index, callback) {
   switch (event.type) {
     case 'touchstart':
-      // Only process single touches.  If there is already a touch happening, or
-      // two simultaneous touches then just ignore them.
-      if (event.touches.length > 1) {
-        // Note that we could cancel an active touch here.  That would make
-        // simultaneous touch behave similar to near-simultaneous. However, if
-        // the user is dragging something, an accidental second touch could be
-        // quite disruptive if it cancelled their drag.  Better to just ignore
-        // it.
-
-        // Invalidate current touch to distinguish it from normal tap.
+      // Only track the position of the single touch. However, we detect a
+      // two-finger tap for opening a context menu of the target.
+      if (event.touches.length == 2) {
+        this.isTwoFingerTap_ = true;
+        return false;
+      } else if (event.touches.length > 2) {
         this.tapStarted_ = false;
         return false;
       }
@@ -123,16 +133,18 @@
       // It's still possible there could be an active "touch" if the user is
       // simultaneously using a mouse and a touch input.
       // TODO(yamaguchi): add this after adding handler for touchcancel that
-      // can reset this.activeTouch_ to undefined.
-      // if (this.activeTouch_ !== undefined)
+      // can reset this.activeTouchId_ to undefined.
+      // if (this.activeTouchId_ !== undefined)
       //   return;
       var touch = event.targetTouches[0];
-      this.activeTouch_ = touch.identifier;
+      this.activeTouchId_ = touch.identifier;
       this.startTouchX_ = this.lastTouchX_ = touch.clientX;
       this.startTouchY_ = this.lastTouchY_ = touch.clientY;
 
       this.tapStarted_ = true;
+      this.activeItemIndex_ = index;
       this.isLongTap_ = false;
+      this.isTwoFingerTap_ = false;
       this.hasLongPressProcessed_ = false;
       this.longTapDetectorTimerId_ = setTimeout(function() {
         this.longTapDetectorTimerId_ = -1;
@@ -146,6 +158,8 @@
       break;
 
     case 'touchmove':
+      if (this.activeTouchId_ === undefined)
+        break;
       var touch = this.findActiveTouch_(event.changedTouches);
       if (!touch)
         break;
@@ -173,7 +187,7 @@
 
     case 'touchend':
       // Mark as no longer being touched
-      this.activeTouch_ = undefined;
+      this.activeTouchId_ = undefined;
       if (this.longTapDetectorTimerId_ != -1) {
         clearTimeout(this.longTapDetectorTimerId_);
         this.longTapDetectorTimerId_ = -1;
@@ -181,13 +195,24 @@
       if (!this.tapStarted_)
         break;
       if (this.isLongTap_) {
+        // The item at the touch start position is treated as the target item,
+        // rather than the one at the touch end position. Note that |index| is
+        // the latter.
         if (this.hasLongPressProcessed_ ||
-            callback(event, index, FileTapHandler.TapEvent.LONG_TAP)) {
+            callback(
+                event, this.activeItemIndex_,
+                FileTapHandler.TapEvent.LONG_TAP)) {
           event.preventDefault();
           return true;
         }
       } else {
-        if (callback(event, index, FileTapHandler.TapEvent.TAP)) {
+        // The item at the touch start position of the active touch is treated
+        // as the target item. In case of the two-finger tap, the first touch
+        // point points to the target.
+        if (callback(
+                event, this.activeItemIndex_,
+                this.isTwoFingerTap_ ? FileTapHandler.TapEvent.TWO_FINGER_TAP :
+                                       FileTapHandler.TapEvent.TAP)) {
           event.preventDefault();
           return true;
         }
@@ -206,11 +231,11 @@
  * @private
  */
 FileTapHandler.prototype.findActiveTouch_ = function(touches) {
-  assert(this.activeTouch_ !== undefined, 'Expecting an active touch');
+  assert(this.activeTouchId_ !== undefined, 'Expecting an active touch');
   // A TouchList isn't actually an array, so we shouldn't use
   // Array.prototype.filter/some, etc.
   for (var i = 0; i < touches.length; i++) {
-    if (touches[i].identifier == this.activeTouch_)
+    if (touches[i].identifier == this.activeTouchId_)
       return touches[i];
   }
   return undefined;