diff --git a/DEPS b/DEPS
index 49bc735..b2773db 100644
--- a/DEPS
+++ b/DEPS
@@ -176,7 +176,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': '2af5f573918e2f46a0df5e9ceea380a52de7e45a',
+  'v8_revision': '814c68a96da7afea756c9f8aea57244f017bd715',
   # 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.
@@ -184,7 +184,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '7f9c9a7fc00143cb5ad26a0bb5cb6950db4a1e58',
+  'angle_revision': 'dc98ca69edd0a803eed76e16d650fa69ea5610f0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -223,11 +223,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': 'b75031a26eed8838222ddb3a81bc1672a0e463a8',
+  'freetype_revision': '3aaae716b25bd2d3232e279bc05af65cff446dd9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
-  'harfbuzz_revision': 'e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b',
+  'harfbuzz_revision': '7cde68f10cdf2c3ff77c1d9077475c0fc034c75c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Emoji Segmenter
   # and whatever else without interference from each other.
@@ -235,7 +235,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '5758cc96a5f3f0f9f3b6f64b83c4918fd2e523dd',
+  'catapult_revision': 'd9164777415c9e1611a038676c2eef56540b120a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -243,7 +243,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '5cb14a4f300bbee3447fb241b57799429492c694',
+  'devtools_frontend_revision': '7eee1a626bd162ff8eaa017c6a1f94a83613b6c3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -291,7 +291,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': 'dc59b4b075e957e36cbecf4d754adc9b67ad1c9c',
+  'spv_tools_revision': '041f0a02493d2c6fcc0148b0c1d397492dfe0084',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -307,7 +307,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'ae1f25fee85ebf2773b24a0a4f39c160839b1dbb',
+  'dawn_revision': '16787735601c0b5fe9b485fb79f6c647a51281fd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -871,7 +871,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8c6f1f9af3f49004e3ba87220d69e17eabaf1b58',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'fc61fb037d2c47749e2485c383ab86b372b66055',
       'condition': 'checkout_linux',
   },
 
@@ -1311,7 +1311,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f0d1100a7149dce7efa44e42f9c1f0952e6c9ab0',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5e3eacac1ca1dcd6f8a18da9a39aeccf48aa13c5',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1512,7 +1512,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'dd55f3ca8f2ea716ca917a4aaf36f0729fe902b1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7c1fb4156d24a217a497eed6a94ac8cb58e162db',
+    Var('webrtc_git') + '/src.git' + '@' + 'd6b9b0a1f4132474c737b5e673e380c3d8e12e2c',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1579,7 +1579,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c2eeedf4626693915c496f99d25c3fe18529cba9',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0db29887459d7d2d5509f8f72ee0081b1138fb14',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 6845545e..eafaa7c4 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -390,7 +390,8 @@
                   '|base/allocator/partition_allocator/'
     },
     'blink_html': {
-      'filepath': 'third_party/blink/renderer/core/html/'
+      'filepath': 'third_party/blink/renderer/core/html/' \
+                  '|third_party/blink/renderer/core/mathml/'
     },
     'blink_htmlparser': {
       'filepath': 'third_party/blink/renderer/core/html/parser/'
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
index b8cd99f6..ed064b9 100644
--- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
+++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
@@ -37,6 +37,10 @@
   return shared_context_state_ && shared_context_state_->GrContextIsVulkan();
 }
 
+bool SkiaOutputSurfaceDependencyWebView::IsUsingDawn() {
+  return false;
+}
+
 gpu::SharedImageManager*
 SkiaOutputSurfaceDependencyWebView::GetSharedImageManager() {
   return gpu_service_->shared_image_manager();
@@ -67,6 +71,11 @@
   return shared_context_state_->vk_context_provider();
 }
 
+viz::DawnContextProvider*
+SkiaOutputSurfaceDependencyWebView::GetDawnContextProvider() {
+  return nullptr;
+}
+
 const gpu::GpuPreferences&
 SkiaOutputSurfaceDependencyWebView::GetGpuPreferences() {
   return gpu_service_->gpu_preferences();
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
index 393faa0..50027fc8 100644
--- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
+++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
@@ -27,12 +27,14 @@
 
   std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() override;
   bool IsUsingVulkan() override;
+  bool IsUsingDawn() override;
   gpu::SharedImageManager* GetSharedImageManager() override;
   gpu::SyncPointManager* GetSyncPointManager() override;
   const gpu::GpuDriverBugWorkarounds& GetGpuDriverBugWorkarounds() override;
   scoped_refptr<gpu::SharedContextState> GetSharedContextState() override;
   gpu::raster::GrShaderCache* GetGrShaderCache() override;
   viz::VulkanContextProvider* GetVulkanContextProvider() override;
+  viz::DawnContextProvider* GetDawnContextProvider() override;
   const gpu::GpuPreferences& GetGpuPreferences() override;
   const gpu::GpuFeatureInfo& GetGpuFeatureInfo() override;
   gpu::MailboxManager* GetMailboxManager() override;
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc
index 07f51a0..673420f4 100644
--- a/base/debug/stack_trace_unittest.cc
+++ b/base/debug/stack_trace_unittest.cc
@@ -31,25 +31,11 @@
 typedef testing::Test StackTraceTest;
 #endif
 
-// TODO(https://crbug.com/999737): Rewrite this test for better clarity and
-// correctness.
-// Note: On Linux, this test currently only fully works on Debug builds.
-// See comments in the #ifdef soup if you intend to change this.
-#if defined(OS_WIN)
-
-// Always fails on Windows: crbug.com/32070
-#define MAYBE_OutputToStream DISABLED_OutputToStream
-
-#elif defined(OS_FUCHSIA) && defined(OFFICIAL_BUILD)
-
-// Backtraces aren't supported by Fuchsia release-optimized builds.
-#define MAYBE_OutputToStream DISABLED_OutputToStream
-
-#else
-#define MAYBE_OutputToStream OutputToStream
-#endif
 #if !defined(__UCLIBC__) && !defined(_AIX)
-TEST_F(StackTraceTest, MAYBE_OutputToStream) {
+// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX.
+// See https://crbug.com/706728
+
+TEST_F(StackTraceTest, OutputToStream) {
   StackTrace trace;
 
   // Dump the trace into a string.
@@ -60,76 +46,54 @@
   // ToString() should produce the same output.
   EXPECT_EQ(backtrace_message, trace.ToString());
 
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
-  // Stack traces require an extra data table that bloats our binaries,
-  // so they're turned off for release builds.  We stop the test here,
-  // at least letting us verify that the calls don't crash.
-  return;
-#endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
-
   size_t frames_found = 0;
-  trace.Addresses(&frames_found);
-  ASSERT_GE(frames_found, 5u) <<
-      "No stack frames found.  Skipping rest of test.";
+  const void* const* addresses = trace.Addresses(&frames_found);
+  ASSERT_TRUE(addresses);
+  ASSERT_GT(frames_found, 0u) << "No stack frames found.";
+
+#if defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX)
+  // Stack traces require an extra data table that bloats our binaries,
+  // so they're turned off for official builds. Stop the test here, so
+  // it at least verifies that StackTrace calls don't crash.
+  return;
+#endif  // defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX)
+
+  ASSERT_GT(frames_found, 5u) << "Too few frames found.";
+
+#if defined(OS_FUCHSIA) || defined(OS_ANDROID)
+  // Under Fuchsia and Android, StackTrace emits executable build-Ids and
+  // address offsets which are symbolized on the test host system, rather than
+  // being symbolized in-process.
+  return;
+#endif  // defined(OS_FUCHSIA) || defined(OS_ANDROID)
+
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+  // Configurations such as ASAN and TSan emit unsymbolized stacks.
+  return;
+#endif  // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
 
   // Check if the output has symbol initialization warning.  If it does, fail.
   ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
-            std::string::npos) <<
-      "Unable to resolve symbols.  Skipping rest of test.";
+            std::string::npos)
+      << "Unable to resolve symbols.";
 
-#if defined(OS_MACOSX)
-#if 0
-  // Disabled due to -fvisibility=hidden in build config.
-
-  // Symbol resolution via the backtrace_symbol function does not work well
-  // in OS X.
-  // See this thread:
-  //
-  //    http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html
-  //
-  // Just check instead that we find our way back to the "start" symbol
-  // which should be the first symbol in the trace.
-  //
-  // TODO(port): Find a more reliable way to resolve symbols.
-
-  // Expect to at least find main.
-  EXPECT_TRUE(backtrace_message.find("start") != std::string::npos)
-      << "Expected to find start in backtrace:\n"
-      << backtrace_message;
-
-#endif
-#elif defined(USE_SYMBOLIZE)
-  // This branch is for gcc-compiled code, but not Mac due to the
-  // above #if.
   // Expect a demangled symbol.
-  EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") !=
-              std::string::npos)
+  // Note that Windows Release builds omit the function parameters from the
+  // demangled stack output, otherwise this could be "testing::Test::Run()".
+  EXPECT_TRUE(backtrace_message.find("testing::Test::Run") != std::string::npos)
       << "Expected a demangled symbol in backtrace:\n"
       << backtrace_message;
 
-#elif 0
-  // This is the fall-through case; it used to cover Windows.
-  // But it's disabled because of varying buildbot configs;
-  // some lack symbols.
-
   // Expect to at least find main.
   EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
       << "Expected to find main in backtrace:\n"
       << backtrace_message;
 
-#if defined(OS_WIN)
-// MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with
-// MSVC's __FUNCTION__ macro.
-#define __func__ __FUNCTION__
-#endif
-
   // Expect to find this function as well.
   // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
   EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
       << "Expected to find " << __func__ << " in backtrace:\n"
       << backtrace_message;
-
-#endif  // define(OS_MACOSX)
 }
 
 #if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
@@ -146,7 +110,7 @@
   truncated.Addresses(&count);
   EXPECT_EQ(2u, count);
 }
-#endif  // !defined(OFFICIAL_BUILD)
+#endif  // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
 
 // The test is used for manual testing, e.g., to see the raw output.
 TEST_F(StackTraceTest, DebugOutputToStream) {
@@ -194,7 +158,7 @@
   trace.ToStringWithPrefix(nullptr);
 }
 
-#endif  // !defined(__UCLIBC__)
+#endif  // !defined(__UCLIBC__) && !defined(_AIX)
 
 #if defined(OS_POSIX) && !defined(OS_ANDROID)
 #if !defined(OS_IOS)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 1096166..8cc1458 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8897393320560678400
\ No newline at end of file
+8897362889837801216
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index d9f85a3..640e107 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8897398712024874704
\ No newline at end of file
+8897363254003807056
\ No newline at end of file
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index 32918efd..31a736d 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -18,6 +18,10 @@
 class MetafileSkia;
 }  // namespace printing
 
+namespace paint_preview {
+class PaintPreviewTracker;
+}  // namespace paint_preview
+
 namespace cc {
 class SkottieWrapper;
 class PaintFlags;
@@ -191,12 +195,19 @@
   void SetPrintingMetafile(printing::MetafileSkia* metafile) {
     metafile_ = metafile;
   }
+  paint_preview::PaintPreviewTracker* GetPaintPreviewTracker() const {
+    return tracker_;
+  }
+  void SetPaintPreviewTracker(paint_preview::PaintPreviewTracker* tracker) {
+    tracker_ = tracker;
+  }
 
   // Subclasses can override to handle custom data.
   virtual void recordCustomData(uint32_t id) {}
 
  private:
   printing::MetafileSkia* metafile_ = nullptr;
+  paint_preview::PaintPreviewTracker* tracker_ = nullptr;
 };
 
 class CC_PAINT_EXPORT PaintCanvasAutoRestore {
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn
index 46b44df..93f9df3c 100644
--- a/chrome/android/features/autofill_assistant/BUILD.gn
+++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -133,6 +133,7 @@
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java",
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java",
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java",
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java",
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java",
     "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantDateChoiceOptions.java",
@@ -214,6 +215,7 @@
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java",
+    "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java",
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml
index f3ac4d60..56478b1 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml
@@ -4,14 +4,19 @@
      found in the LICENSE file. -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/login_full"
+    android:id="@+id/login_summary"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
     android:gravity="center_vertical">
   <TextView
-      android:id="@+id/username"
+      android:id="@+id/label"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:textAppearance="@style/TextAppearance.BlackBody"/>
+  <TextView
+      android:id="@+id/sublabel"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:textAppearance="@style/TextAppearance.BlackBody" />
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java
index 67f7cc6..74f7324 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.GridLayout;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -19,7 +20,7 @@
 import android.widget.Space;
 import android.widget.TextView;
 
-import androidx.annotation.Nullable;
+import androidx.annotation.DrawableRes;
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
@@ -167,6 +168,13 @@
         addItem(view, hasEditButton, null, null);
     }
 
+    public void addItem(View view, boolean hasEditButton,
+            @Nullable Callback<Boolean> itemSelectedListener,
+            @Nullable Runnable itemEditedListener) {
+        addItem(view, hasEditButton, itemSelectedListener, itemEditedListener,
+                R.drawable.ic_edit_24dp, "");
+    }
+
     /**
      * Adds an item to the list. Additional widgets to select and edit the item are created as
      * necessary.
@@ -176,10 +184,12 @@
      * @param itemSelectedListener Optional listener which is notified when the item is selected or
      * deselected.
      * @param itemEditedListener Optional listener which is notified when the item is edited.
+     * @param editButtonDrawable The drawable to use for the optional edit button.
+     * @param editButtonContentDescription The content description for the optional edit button.
      */
     public void addItem(View view, boolean hasEditButton,
-            @Nullable Callback<Boolean> itemSelectedListener,
-            @Nullable Runnable itemEditedListener) {
+            @Nullable Callback<Boolean> itemSelectedListener, @Nullable Runnable itemEditedListener,
+            @DrawableRes int editButtonDrawable, String editButtonContentDescription) {
         CompoundButton radioButton =
                 mAllowMultipleChoices ? new CheckBox(getContext()) : new RadioButton(getContext());
         radioButton.setPadding(0, 0, mColumnSpacing, 0);
@@ -195,7 +205,7 @@
         View editButton = null;
         LinearLayout spacer = null;
         if (hasEditButton) {
-            editButton = createEditButton();
+            editButton = createEditButton(editButtonDrawable, editButtonContentDescription);
             editButton.setOnClickListener(unusedView -> {
                 if (itemEditedListener != null) {
                     itemEditedListener.run();
@@ -388,17 +398,19 @@
         return lp;
     }
 
-    private View createEditButton() {
+    private View createEditButton(
+            @DrawableRes int editButtonDrawable, String editButtonContentDescription) {
         int editButtonSize = getContext().getResources().getDimensionPixelSize(
                 R.dimen.autofill_assistant_choicelist_edit_button_size);
         ChromeImageView editButton = new ChromeImageView(getContext());
-        editButton.setImageResource(R.drawable.ic_edit_24dp);
+        editButton.setImageResource(editButtonDrawable);
         editButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
         editButton.setLayoutParams(new ViewGroup.LayoutParams(editButtonSize, editButtonSize));
 
         LinearLayout editButtonLayout = createMinimumTouchSizeContainer();
         editButtonLayout.setGravity(Gravity.CENTER);
         editButtonLayout.addView(editButton);
+        editButtonLayout.setContentDescription(editButtonContentDescription);
         return editButtonLayout;
     }
 
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
index 3c47bec..c357998 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.autofill_assistant.user_data;
 
+import android.support.annotation.Nullable;
+
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.chrome.browser.autofill.PersonalDataManager;
@@ -248,6 +250,12 @@
         set(DELEGATE, delegate);
     }
 
+    /** Creates a simple info popup with a title and some text. */
+    @CalledByNative
+    private static AssistantInfoPopup createInfoPopup(String title, String text) {
+        return new AssistantInfoPopup(title, text);
+    }
+
     /** Creates an empty list of login options. */
     @CalledByNative
     private static List<AssistantLoginChoice> createLoginChoiceList() {
@@ -256,9 +264,11 @@
 
     /** Appends a login choice to {@code loginChoices}. */
     @CalledByNative
-    private void addLoginChoice(List<AssistantLoginChoice> loginChoices, String identifier,
-            String label, int priority) {
-        loginChoices.add(new AssistantLoginChoice(identifier, label, priority));
+    private static void addLoginChoice(List<AssistantLoginChoice> loginChoices, String identifier,
+            String label, String sublabel, String sublabelAccessibilityHint, int priority,
+            @Nullable AssistantInfoPopup infoPopup) {
+        loginChoices.add(new AssistantLoginChoice(
+                identifier, label, sublabel, sublabelAccessibilityHint, priority, infoPopup));
     }
 
     /** Sets the list of available login choices. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
index 8c5a6b8..2a816a86 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
@@ -12,6 +12,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
 import org.chromium.base.ApiCompatibilityUtils;
@@ -39,7 +40,6 @@
     private final int mFullViewResId;
     private final int mTitleToContentPadding;
     private final List<Item> mItems;
-    private final boolean mCanEditItems;
 
     protected final Context mContext;
     protected T mSelectedOption;
@@ -69,16 +69,14 @@
      *         button should be created.
      * @param listAddButton The string to display in the add button at the bottom of the list. Can
      *         be null if no add button should be created.
-     * @param canEditItems Whether items can be edited (i.e., show an edit button) or not.
      */
     public AssistantCollectUserDataSection(Context context, ViewGroup parent, int summaryViewResId,
             int fullViewResId, int titleToContentPadding, @Nullable String titleAddButton,
-            @Nullable String listAddButton, boolean canEditItems) {
+            @Nullable String listAddButton) {
         mContext = context;
         mFullViewResId = fullViewResId;
         mItems = new ArrayList<>();
         mTitleToContentPadding = titleToContentPadding;
-        mCanEditItems = canEditItems;
 
         LayoutInflater inflater = LayoutInflater.from(context);
         mSectionExpander = new AssistantVerticalExpander(context, null);
@@ -291,7 +289,7 @@
     }
 
     /**
-     * Creates a new |Item| from |option|.
+     * Creates a new item from {@code option}.
      */
     private Item createItem(T option) {
         View fullView = LayoutInflater.from(mContext).inflate(mFullViewResId, null);
@@ -301,48 +299,69 @@
     }
 
     /**
-     * Adds |item| to the UI.
+     * Adds {@code item} to the UI.
      */
     private void addItem(Item item) {
         mItems.add(item);
-        mItemsView.addItem(item.mFullView, /*hasEditButton=*/mCanEditItems, selected -> {
-            if (mIgnoreItemSelectedNotifications || !selected) {
-                return;
-            }
-            mIgnoreItemSelectedNotifications = true;
-            selectItem(item.mFullView, item.mOption);
-            mIgnoreItemSelectedNotifications = false;
-            if (item.mOption.isComplete()) {
-                // Workaround for Android bug: a layout transition may cause the newly checked
-                // radiobutton to not render properly.
-                mSectionExpander.post(() -> mSectionExpander.setExpanded(false));
-            } else {
-                createOrEditItem(item.mOption);
-            }
-        }, () -> createOrEditItem(item.mOption));
+        boolean canEditOption = canEditOption(item.mOption);
+        @DrawableRes
+        int editButtonDrawable = R.drawable.ic_edit_24dp;
+        String editButtonContentDescription = "";
+        if (canEditOption) {
+            editButtonDrawable = getEditButtonDrawable(item.mOption);
+            editButtonContentDescription = getEditButtonContentDescription(item.mOption);
+        }
+        mItemsView.addItem(item.mFullView, /*hasEditButton=*/canEditOption,
+                selected
+                -> {
+                    if (mIgnoreItemSelectedNotifications || !selected) {
+                        return;
+                    }
+                    mIgnoreItemSelectedNotifications = true;
+                    selectItem(item.mFullView, item.mOption);
+                    mIgnoreItemSelectedNotifications = false;
+                    if (item.mOption.isComplete()) {
+                        // Workaround for Android bug: a layout transition may cause the newly
+                        // checked radiobutton to not render properly.
+                        mSectionExpander.post(() -> mSectionExpander.setExpanded(false));
+                    } else {
+                        createOrEditItem(item.mOption);
+                    }
+                },
+                ()
+                        -> createOrEditItem(item.mOption),
+                /*editButtonDrawable=*/editButtonDrawable,
+                /*editButtonContentDescription=*/editButtonContentDescription);
         updateVisibility();
     }
 
     /**
-     * Asks the subclass to edit an item or create a new one (if |oldItem| is null). Subclasses
-     * should call |addOrUpdateItem| when they are done.
+     * Asks the subclass to edit an item or create a new one (if {@code oldItem} is null).
+     * Subclasses should call {@code addOrUpdateItem} when they are done.
      * @param oldItem The item to be edited (null if a new item should be created).
      */
     protected abstract void createOrEditItem(@Nullable T oldItem);
 
     /**
-     * Asks the subclass to update the contents of |fullView|, which was previously created by
-     * |createFullView|.
+     * Asks the subclass to update the contents of {@code fullView}, which was previously created by
+     * {@code createFullView}.
      */
     protected abstract void updateFullView(View fullView, T option);
 
-    /**
-     * Asks the subclass to update the contents of the summary view.
-     */
+    /** Asks the subclass to update the contents of the summary view. */
     protected abstract void updateSummaryView(View summaryView, T option);
 
+    /** Asks the subclass whether {@code option} should be editable or not. */
+    protected abstract boolean canEditOption(T option);
+
+    /** Asks the subclass which drawable to use for {@code option}. */
+    protected abstract @DrawableRes int getEditButtonDrawable(T option);
+
+    /** Asks the subclass for the content description of {@code option}. */
+    protected abstract String getEditButtonContentDescription(T option);
+
     /**
-     * For convenience. Hides |view| if it is empty.
+     * For convenience. Hides {@code view} if it is empty.
      */
     void hideIfEmpty(TextView view) {
         view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
index c0d37591..c924d43 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
@@ -10,6 +10,7 @@
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.autofill_assistant.R;
@@ -35,7 +36,7 @@
                 context.getResources().getDimensionPixelSize(
                         R.dimen.autofill_assistant_payment_request_title_padding),
                 context.getString(R.string.payments_add_contact),
-                context.getString(R.string.payments_add_contact), /*canEditItems=*/true);
+                context.getString(R.string.payments_add_contact));
         setTitle(context.getString(R.string.payments_contact_details_label));
     }
 
@@ -104,6 +105,21 @@
         contactIncompleteView.setVisibility(contact.isComplete() ? View.GONE : View.VISIBLE);
     }
 
+    @Override
+    protected boolean canEditOption(AutofillContact contact) {
+        return true;
+    }
+
+    @Override
+    protected @DrawableRes int getEditButtonDrawable(AutofillContact contact) {
+        return R.drawable.ic_edit_24dp;
+    }
+
+    @Override
+    protected String getEditButtonContentDescription(AutofillContact contact) {
+        return mContext.getString(R.string.payments_edit_contact_details_label);
+    }
+
     /**
      * The Chrome profiles have changed externally. This will rebuild the UI with the new/changed
      * set of profiles, while keeping the selected item if possible.
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java
new file mode 100644
index 0000000..961fe6f
--- /dev/null
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java
@@ -0,0 +1,26 @@
+// Copyright 2019 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.
+
+package org.chromium.chrome.browser.autofill_assistant.user_data;
+
+/**
+ * Represents a simple info popup.
+ */
+public class AssistantInfoPopup {
+    private final String mTitle;
+    private final String mText;
+
+    public AssistantInfoPopup(String title, String text) {
+        mTitle = title;
+        mText = text;
+    }
+
+    public String getTitle() {
+        return mTitle;
+    }
+
+    public String getText() {
+        return mText;
+    }
+}
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java
index b6ea521..ebc3af0 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.autofill_assistant.user_data;
 
+import android.support.annotation.Nullable;
+
 import org.chromium.chrome.browser.widget.prefeditor.EditableOption;
 
 /**
@@ -13,18 +15,36 @@
  */
 public class AssistantLoginChoice extends EditableOption {
     private final int mPriority;
+    private final String mSublabelAccessibilityHint;
+    private final @Nullable AssistantInfoPopup mInfoPopup;
+
     /**
      * @param identifier The unique identifier of this login choice.
      * @param label The label to display to the user.
+     * @param sublabel Optional sublabel to display below the label.
+     * @param sublabelAccessibilityHint The a11y hint for {@code sublabel}.
      * @param priority The priority of this login choice (lower value == higher priority). Can be -1
      * to indicate default/auto.
+     * @param infoPopup Optional popup that provides further information for this login choice.
      */
-    public AssistantLoginChoice(String identifier, String label, int priority) {
-        super(identifier, label, null, null);
+    public AssistantLoginChoice(String identifier, String label, String sublabel,
+            String sublabelAccessibilityHint, int priority,
+            @Nullable AssistantInfoPopup infoPopup) {
+        super(identifier, label, sublabel, null);
         mPriority = priority;
+        mSublabelAccessibilityHint = sublabelAccessibilityHint;
+        mInfoPopup = infoPopup;
     }
 
     public int getPriority() {
         return mPriority;
     }
+
+    public @Nullable AssistantInfoPopup getInfoPopup() {
+        return mInfoPopup;
+    }
+
+    public String getSublabelAccessibilityHint() {
+        return mSublabelAccessibilityHint;
+    }
 }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java
index efb5d61..c1ff99e 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java
@@ -4,13 +4,20 @@
 
 package org.chromium.chrome.browser.autofill_assistant.user_data;
 
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
+
 import android.content.Context;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
-import androidx.annotation.Nullable;
+import androidx.annotation.DrawableRes;
+
+import org.chromium.chrome.autofill_assistant.R;
+import org.chromium.ui.UiUtils;
 
 import java.util.List;
 
@@ -19,18 +26,23 @@
  */
 public class AssistantLoginSection extends AssistantCollectUserDataSection<AssistantLoginChoice> {
     AssistantLoginSection(Context context, ViewGroup parent) {
-        super(context, parent,
-                org.chromium.chrome.autofill_assistant.R.layout.autofill_assistant_login,
-                org.chromium.chrome.autofill_assistant.R.layout.autofill_assistant_login,
+        super(context, parent, R.layout.autofill_assistant_login, R.layout.autofill_assistant_login,
                 context.getResources().getDimensionPixelSize(
                         org.chromium.chrome.autofill_assistant.R.dimen
                                 .autofill_assistant_payment_request_title_padding),
-                /*titleAddButton=*/null, /*listAddButton=*/null, /*canEditItems=*/false);
+                /*titleAddButton=*/null, /*listAddButton=*/null);
     }
 
     @Override
     protected void createOrEditItem(@Nullable AssistantLoginChoice oldItem) {
-        // Nothing to do, this section currently does not support adding or creating items.
+        assert oldItem != null;
+        assert oldItem.getInfoPopup() != null;
+
+        new UiUtils.CompatibleAlertDialogBuilder(mContext, R.style.Theme_Chromium_AlertDialog)
+                .setTitle(oldItem.getInfoPopup().getTitle())
+                .setMessage(oldItem.getInfoPopup().getText())
+                .setPositiveButton(R.string.close, (dialog, which) -> {})
+                .show();
     }
 
     @Override
@@ -40,9 +52,35 @@
 
     @Override
     protected void updateSummaryView(View summaryView, AssistantLoginChoice option) {
-        TextView usernameView =
-                summaryView.findViewById(org.chromium.chrome.autofill_assistant.R.id.username);
-        usernameView.setText(option.getLabel());
+        TextView labelView = summaryView.findViewById(R.id.label);
+        labelView.setText(option.getLabel());
+        TextView sublabelView = summaryView.findViewById(R.id.sublabel);
+        if (TextUtils.isEmpty(option.getSublabel())) {
+            sublabelView.setVisibility(View.GONE);
+        } else {
+            sublabelView.setText(option.getSublabel());
+            sublabelView.setContentDescription(option.getSublabelAccessibilityHint());
+            sublabelView.setImportantForAccessibility(
+                    TextUtils.isEmpty(option.getSublabelAccessibilityHint())
+                            ? IMPORTANT_FOR_ACCESSIBILITY_NO
+                            : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        }
+    }
+
+    @Override
+    protected boolean canEditOption(AssistantLoginChoice choice) {
+        return choice.getInfoPopup() != null;
+    }
+
+    @Override
+    protected @DrawableRes int getEditButtonDrawable(AssistantLoginChoice choice) {
+        return R.drawable.btn_info;
+    }
+
+    @Override
+    protected String getEditButtonContentDescription(AssistantLoginChoice choice) {
+        // TODO(b/143862732): Send this a11y string from the backend.
+        return mContext.getString(R.string.learn_more);
     }
 
     /**
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java
index caeac64..dc880a5c 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java
@@ -12,6 +12,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.autofill_assistant.R;
@@ -38,7 +39,7 @@
                 context.getResources().getDimensionPixelSize(
                         R.dimen.autofill_assistant_payment_request_payment_method_title_padding),
                 context.getString(R.string.payments_add_card),
-                context.getString(R.string.payments_add_card), /*canEditItems=*/true);
+                context.getString(R.string.payments_add_card));
         setTitle(context.getString(R.string.payments_method_of_payment_label));
     }
 
@@ -120,6 +121,21 @@
         hideIfEmpty(methodIncompleteView);
     }
 
+    @Override
+    protected boolean canEditOption(AutofillPaymentInstrument method) {
+        return true;
+    }
+
+    @Override
+    protected @DrawableRes int getEditButtonDrawable(AutofillPaymentInstrument method) {
+        return R.drawable.ic_edit_24dp;
+    }
+
+    @Override
+    protected String getEditButtonContentDescription(AutofillPaymentInstrument method) {
+        return mContext.getString(R.string.autofill_edit_credit_card);
+    }
+
     void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) {
         // TODO(crbug.com/806868): replace suggested billing addresses (remove if necessary).
         for (PersonalDataManager.AutofillProfile profile : profiles) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java
index 500fff8..196cb5a 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java
@@ -10,6 +10,7 @@
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.autofill_assistant.R;
@@ -34,7 +35,7 @@
                 context.getResources().getDimensionPixelSize(
                         R.dimen.autofill_assistant_payment_request_title_padding),
                 context.getString(R.string.payments_add_address),
-                context.getString(R.string.payments_add_address), /*canEditItems=*/true);
+                context.getString(R.string.payments_add_address));
         setTitle(context.getString(R.string.payments_shipping_address_label));
     }
 
@@ -93,6 +94,21 @@
         methodIncompleteView.setVisibility(address.isComplete() ? View.GONE : View.VISIBLE);
     }
 
+    @Override
+    protected boolean canEditOption(AutofillAddress address) {
+        return true;
+    }
+
+    @Override
+    protected @DrawableRes int getEditButtonDrawable(AutofillAddress address) {
+        return R.drawable.ic_edit_24dp;
+    }
+
+    @Override
+    protected String getEditButtonContentDescription(AutofillAddress address) {
+        return mContext.getString(R.string.payments_edit_address);
+    }
+
     void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) {
         if (mIgnoreProfileChangeNotifications) {
             return;
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java
index 826e78d..4637459e 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java
@@ -243,7 +243,7 @@
 
         PersonalDataManager.CreditCard creditCard = new PersonalDataManager.CreditCard("",
                 "https://example.com", true, true, profileName, "4111111111111111", "1111", "12",
-                "2050", "amex", org.chromium.chrome.autofill_assistant.R.drawable.amex_card,
+                "2050", "visa", org.chromium.chrome.autofill_assistant.R.drawable.visa_card,
                 CardType.UNKNOWN, billingAddressId, "" /* serverId */);
         return setCreditCard(creditCard);
     }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
index 13814c9..f1b973bf 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
@@ -54,6 +54,7 @@
 import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel;
 import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantDateChoiceOptions;
 import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantDateTime;
+import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantInfoPopup;
 import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantLoginChoice;
 import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantTermsAndConditionsState;
 import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionFactory;
@@ -503,7 +504,8 @@
             model.set(AssistantCollectUserDataModel.VISIBLE, true);
             model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true);
             model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS,
-                    Collections.singletonList(new AssistantLoginChoice("id", "Guest", 0)));
+                    Collections.singletonList(new AssistantLoginChoice(
+                            "id", "Guest", "Description of guest checkout", "", 0, null)));
         });
 
         /* Non-empty sections should not display the 'add' button in their title. */
@@ -554,8 +556,8 @@
                 "Acme Inc., 123 Main, 90210 Los Angeles, California, Uzbekistan",
                 viewHolder.mShippingSection.getCollapsedView(),
                 viewHolder.mShippingAddressList.getItem(0));
-        testLoginDetails("Guest", viewHolder.mLoginsSection.getCollapsedView(),
-                viewHolder.mLoginList.getItem(0));
+        testLoginDetails("Guest", "Description of guest checkout",
+                viewHolder.mLoginsSection.getCollapsedView(), viewHolder.mLoginList.getItem(0));
 
         /* Check delegate status. */
         assertThat(delegate.mPaymentMethod.getCard().getNumber(), is("4111111111111111"));
@@ -1101,6 +1103,34 @@
         assertThat(delegate.mAdditionalValues.get("loyalty"), is("L-394834"));
     }
 
+    @Test
+    @MediumTest
+    public void testLoginSectionInfoPopup() throws Exception {
+        AssistantCollectUserDataModel model = new AssistantCollectUserDataModel();
+        createCollectUserDataCoordinator(model);
+        AutofillAssistantCollectUserDataTestHelper.MockDelegate delegate =
+                new AutofillAssistantCollectUserDataTestHelper.MockDelegate();
+
+        AssistantInfoPopup infoPopup =
+                new AssistantInfoPopup("Guest checkout", "Text explanation.");
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            model.set(AssistantCollectUserDataModel.DELEGATE, delegate);
+            model.set(AssistantCollectUserDataModel.VISIBLE, true);
+            model.set(AssistantCollectUserDataModel.LOGIN_SECTION_TITLE, "Login options");
+            model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true);
+            model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS,
+                    Collections.singletonList(new AssistantLoginChoice(
+                            "id", "Guest checkout", "", "", 0, infoPopup)));
+        });
+
+        onView(withText("Login options")).perform(click());
+        onView(withContentDescription(mTestRule.getActivity().getString(R.string.learn_more)))
+                .perform(click());
+        onView(withText("Guest checkout")).check(matches(isDisplayed()));
+        onView(withText("Text explanation.")).check(matches(isDisplayed()));
+        onView(withText(mTestRule.getActivity().getString(R.string.close))).perform(click());
+    }
+
     private View getPaymentSummaryErrorView(ViewHolder viewHolder) {
         return viewHolder.mPaymentSection.findViewById(R.id.payment_method_summary)
                 .findViewById(R.id.incomplete_error);
@@ -1157,10 +1187,13 @@
                 .check(matches(not(isDisplayed())));
     }
 
-    private void testLoginDetails(String expectedLabel, View summaryView, View fullView) {
-        onView(allOf(withId(R.id.username), isDescendantOfA(is(summaryView))))
+    private void testLoginDetails(
+            String expectedLabel, String expectedSublabel, View summaryView, View fullView) {
+        onView(allOf(withId(R.id.label), isDescendantOfA(is(summaryView))))
                 .check(matches(withText(expectedLabel)));
-        onView(allOf(withId(R.id.username), isDescendantOfA(is(fullView))))
+        onView(allOf(withId(R.id.label), isDescendantOfA(is(fullView))))
                 .check(matches(withText(expectedLabel)));
+        onView(allOf(withId(R.id.sublabel), isDescendantOfA(is(fullView))))
+                .check(matches(withText(expectedSublabel)));
     }
 }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java
new file mode 100644
index 0000000..31640c2
--- /dev/null
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java
@@ -0,0 +1,125 @@
+// Copyright 2019 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.
+
+package org.chromium.chrome.browser.autofill_assistant;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.typeText;
+import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementValue;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.autofill_assistant.R;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.CollectUserDataProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.ElementReferenceProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.UseCreditCardProto;
+import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
+import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.content_public.browser.WebContents;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Tests autofill assistant payment.
+ */
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@RunWith(ChromeJUnit4ClassRunner.class)
+public class AutofillAssistantPaymentTest {
+    @Rule
+    public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule();
+
+    private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/"
+            + "form_target_website.html";
+
+    private AutofillAssistantCollectUserDataTestHelper mHelper;
+
+    private WebContents getWebContents() {
+        return mTestRule.getWebContents();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        AutofillAssistantPreferencesUtil.setInitialPreferences(true);
+        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
+                InstrumentationRegistry.getTargetContext(),
+                mTestRule.getTestServer().getURL(TEST_PAGE)));
+        mHelper = new AutofillAssistantCollectUserDataTestHelper();
+    }
+
+    /**
+     * Fill a form with a saved credit card's details and type the CVC when prompted.
+     */
+    @Test
+    @MediumTest
+    public void testEnterPayment() throws Exception {
+        String profileId = mHelper.addDummyProfile("John Doe", "johndoe@gmail.com");
+        mHelper.addDummyCreditCard(profileId);
+
+        ArrayList<ActionProto> list = new ArrayList<>();
+        list.add((ActionProto) ActionProto.newBuilder()
+                         .setCollectUserData(
+                                 CollectUserDataProto.newBuilder()
+                                         .setRequestPaymentMethod(true)
+                                         .addSupportedBasicCardNetworks("visa")
+                                         .setThirdpartyPrivacyNoticeText("3rd party privacy text")
+                                         .setRequestTermsAndConditions(false))
+                         .build());
+        list.add((ActionProto) ActionProto.newBuilder()
+                         .setUseCard(UseCreditCardProto.newBuilder().setFormFieldElement(
+                                 ElementReferenceProto.newBuilder().addSelectors("#card_number")))
+                         .build());
+        list.add((ActionProto) ActionProto.newBuilder()
+                         .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices(
+                                 PromptProto.Choice.newBuilder()))
+                         .build());
+        AutofillAssistantTestScript script = new AutofillAssistantTestScript(
+                (SupportedScriptProto) SupportedScriptProto.newBuilder()
+                        .setPath("form_target_website.html")
+                        .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
+                                ChipProto.newBuilder().setText("Payment")))
+                        .build(),
+                list);
+
+        AutofillAssistantTestService testService =
+                new AutofillAssistantTestService(Collections.singletonList(script));
+        startAutofillAssistant(mTestRule.getActivity(), testService);
+
+        waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
+        onView(withText("Continue")).perform(click());
+        waitUntilViewMatchesCondition(withId(R.id.card_unmask_input), isCompletelyDisplayed());
+        onView(withId(R.id.card_unmask_input)).perform(typeText("123"));
+        onView(withId(R.id.positive_button)).perform(click());
+        waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
+        assertThat(getElementValue("name", getWebContents()), is("John Doe"));
+        assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111"));
+        assertThat(getElementValue("cv2_number", getWebContents()), is("123"));
+        assertThat(getElementValue("exp_month", getWebContents()), is("12"));
+        assertThat(getElementValue("exp_year", getWebContents()), is("2050"));
+    }
+}
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
index f3eb13b..4a22608 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -339,4 +339,23 @@
         JSONArray values = new JSONArray(javascriptHelper.getJsonResultAndClear());
         return new Rect(values.getInt(0), values.getInt(1), values.getInt(2), values.getInt(3));
     }
+
+    /**
+     * Retrieves the value of the specified element.
+     */
+    public static String getElementValue(String elementId, WebContents webContents)
+            throws Exception {
+        if (!checkElementExists(elementId, webContents)) {
+            throw new IllegalArgumentException(elementId + " does not exist");
+        }
+        TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
+                new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
+        javascriptHelper.evaluateJavaScriptForTests(webContents,
+                "(function() {"
+                        + " return [document.getElementById('" + elementId + "').value]"
+                        + "})()");
+        javascriptHelper.waitUntilHasValue();
+        JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
+        return result.getString(0);
+    }
 }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java
index 575f4eb..ad958a0 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java
@@ -62,9 +62,6 @@
      */
     public static void recordSheetTrigger(
             @AccessoryTabType int tabType, @AccessorySheetTrigger int bucket) {
-        // TODO(crbug.com/926372): Add metrics capabilities for credit cards.
-        if (tabType == AccessoryTabType.CREDIT_CARDS) return;
-
         RecordHistogram.recordEnumeratedHistogram(
                 getHistogramForType(UMA_KEYBOARD_ACCESSORY_SHEET_TRIGGERED, tabType), bucket,
                 AccessorySheetTrigger.COUNT);
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java
index 9a379a0..84d6396 100644
--- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java
+++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java
@@ -55,7 +55,7 @@
 import org.chromium.chrome.browser.help.HelpAndFeedback;
 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
@@ -713,7 +713,7 @@
             sRegisteredVrAssetsComponent = true;
         }
         SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceManager.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP,
+                ChromePreferenceKeys.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP,
                 isDaydreamCurrentViewer);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 712c92e9e..426c617 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -110,7 +110,7 @@
 import org.chromium.chrome.browser.omnibox.LocationBar;
 import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -817,7 +817,7 @@
             boolean isLegacyMultiWindow = MultiWindowUtils.getInstance().isLegacyMultiWindow(this);
             if (!isShowingPromo && !mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete()
                     && preferenceManager.readBoolean(
-                            ChromePreferenceManager.PROMOS_SKIPPED_ON_FIRST_START, false)
+                            ChromePreferenceKeys.PROMOS_SKIPPED_ON_FIRST_START, false)
                     && !VrModuleProvider.getDelegate().isInVr()
                     // VrModuleProvider.getDelegate().isInVr may not return true at this point
                     // even though Chrome is about to enter VR, so we need to also check whether
@@ -827,7 +827,7 @@
                 isShowingPromo = maybeShowPromo();
             } else {
                 preferenceManager.writeBoolean(
-                        ChromePreferenceManager.PROMOS_SKIPPED_ON_FIRST_START, true);
+                        ChromePreferenceKeys.PROMOS_SKIPPED_ON_FIRST_START, true);
             }
 
             ToolbarButtonInProductHelpController.create(this, isShowingPromo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
index b64a0c0..b4cdd05b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -22,7 +22,7 @@
 import org.chromium.base.task.AsyncTask;
 import org.chromium.base.task.BackgroundOnlyAsyncTask;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.content_public.browser.BrowserStartupController;
 
@@ -105,7 +105,7 @@
                                 && TextUtils.equals(
                                            context.getPackageName(), info.activityInfo.packageName);
                         SharedPreferencesManager.getInstance().writeBoolean(
-                                ChromePreferenceManager.CHROME_DEFAULT_BROWSER, isDefault);
+                                ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, isDefault);
 
                         // Check if there is a default handler for the Intent.  If so, store its
                         // label.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
index eea641d9..e90a53d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
@@ -4,8 +4,8 @@
 
 package org.chromium.chrome.browser.browserservices;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA;
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL;
 
 import org.chromium.base.StrictModeContext;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java
index a261aa70..3f433ce 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java
@@ -6,7 +6,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
 /** Java-side implementation of the VrAssetsComponentInstaller. */
@@ -15,6 +15,6 @@
     @CalledByNative
     private static boolean shouldRegisterOnStartup() {
         return SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, false);
+                ChromePreferenceKeys.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, false);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index e7a0718..1a993fe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.locale.LocaleManager;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.share.LensUtils;
@@ -430,7 +430,7 @@
                 } catch (URISyntaxException ignore) {
                 }
                 if (SharedPreferencesManager.getInstance().readBoolean(
-                            ChromePreferenceManager.CHROME_DEFAULT_BROWSER, false)
+                            ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, false)
                         && addNewEntries) {
                     if (mDelegate.isIncognitoSupported()) {
                         tab.add(0, new ChromeContextMenuItem(Item.OPEN_IN_CHROME_INCOGNITO_TAB));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java b/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java
index 38e38da..6d212f08 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java
@@ -7,7 +7,7 @@
 import org.chromium.base.CommandLine;
 import org.chromium.base.SysUtils;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.util.AccessibilityUtil;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -97,7 +97,7 @@
         if (getInstance().mEnableAccessibilityLayout) return true;
         if (!AccessibilityUtil.isAccessibilityEnabled()) return false;
         return SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true);
+                ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true);
     }
 
     /**
@@ -114,7 +114,7 @@
         if (!getInstance().mEnableAnimations) return false;
         if (!AccessibilityUtil.isAccessibilityEnabled()) return true;
         return !SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true);
+                ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java
index f8d6af2..556572f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java
@@ -26,7 +26,7 @@
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.device.DeviceClassManager;
 import org.chromium.chrome.browser.firstrun.FirstRunUtils;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -698,7 +698,7 @@
         }
 
         SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY,
+                ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY,
                 FieldTrialList.findFullName(ChromeFeatureList.REACHED_CODE_PROFILER));
     }
 
@@ -709,7 +709,7 @@
     public static String getReachedCodeProfilerTrialGroup() {
         if (sReachedCodeProfilerTrialGroup == null) {
             sReachedCodeProfilerTrialGroup = SharedPreferencesManager.getInstance().readString(
-                    ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY, "");
+                    ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY, "");
         }
 
         return sReachedCodeProfilerTrialGroup;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java
index 55c03df..438316d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java
@@ -21,7 +21,7 @@
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.util.IntentUtils;
@@ -332,7 +332,7 @@
     /** @return Whether Chrome is the default browser on the device. */
     private boolean isChromeDefaultHandler(Context context) {
         return SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.CHROME_DEFAULT_BROWSER, false);
+                ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, false);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
index 7e976ef1..8347a78 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
@@ -18,7 +18,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.AsyncTask;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.util.ConversionUtils;
 import org.chromium.chrome.browser.webapps.WebApkDistributor;
@@ -128,8 +128,8 @@
     /** Makes recordings that were deferred in order to not load native. */
     public static void recordDeferredUma() {
         SharedPreferencesManager preferencesManager = SharedPreferencesManager.getInstance();
-        Set<String> uninstalledPackages = preferencesManager.readStringSet(
-                ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES);
+        Set<String> uninstalledPackages =
+                preferencesManager.readStringSet(ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES);
         if (uninstalledPackages.isEmpty()) return;
 
         long fallbackUninstallTimestamp = System.currentTimeMillis();
@@ -152,7 +152,7 @@
             }
         }
         preferencesManager.writeStringSet(
-                ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES, new HashSet<String>());
+                ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES, new HashSet<String>());
 
         // TODO(http://crbug.com/1000312): Clear WebappDataStorage for uninstalled WebAPK.
     }
@@ -160,7 +160,7 @@
     /** Sets WebAPK uninstall to be recorded next time that native is loaded. */
     public static void deferRecordWebApkUninstalled(String packageName) {
         SharedPreferencesManager.getInstance().addToStringSet(
-                ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES, packageName);
+                ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES, packageName);
         String webApkId = WebappRegistry.webApkIdForPackage(packageName);
         WebappRegistry.warmUpSharedPrefsForId(webApkId);
         WebappDataStorage webappDataStorage =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
index 0a234ba3..d95a22ee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.night_mode;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import android.support.v7.app.AppCompatDelegate;
 import android.text.TextUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java
index efb7a631..6c31e8d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.night_mode;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
index 694a7d9..856edab 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.night_mode;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.DARKEN_WEBSITES_ENABLED_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.DARKEN_WEBSITES_ENABLED_KEY;
 
 import android.text.TextUtils;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index b5f10c81..ceea573 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -13,6 +13,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
@@ -109,7 +110,7 @@
     public static boolean shouldCreatePromo() {
         return !sDisablePromoForTests
                 && !SharedPreferencesManager.getInstance().readBoolean(
-                        ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false)
+                        ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false)
                 && !getSuppressionStatus();
     }
 
@@ -165,7 +166,7 @@
         updateVisibility();
 
         SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, true);
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, true);
 
         final @StringRes int promoHeader = mSigninPromoController.getDescriptionStringId();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
index a7f739c..715152c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
@@ -40,7 +40,7 @@
 import org.chromium.chrome.browser.omaha.inline.InlineUpdateControllerFactory;
 import org.chromium.chrome.browser.omaha.metrics.UpdateSuccessMetrics;
 import org.chromium.chrome.browser.omaha.metrics.UpdateSuccessMetrics.UpdateType;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.util.ConversionUtils;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
@@ -205,7 +205,7 @@
         }
 
         SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, currentlyUsedVersion);
+                ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, currentlyUsedVersion);
         mStatus.latestUnsupportedVersion = currentlyUsedVersion;
         pingObservers();
     }
@@ -409,7 +409,7 @@
                 case UpdateState.UNSUPPORTED_OS_VERSION:
                     status.latestUnsupportedVersion =
                             SharedPreferencesManager.getInstance().readString(
-                                    ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, null);
+                                    ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null);
                     break;
             }
 
@@ -430,11 +430,11 @@
                         allowedToUpdate ? UpdateState.UPDATE_AVAILABLE : UpdateState.NONE;
 
                 SharedPreferencesManager.getInstance().removeKey(
-                        ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION);
+                        ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION);
             } else if (!VersionNumberGetter.isCurrentOsVersionSupported()) {
                 status.updateState = UpdateState.UNSUPPORTED_OS_VERSION;
                 status.latestUnsupportedVersion = SharedPreferencesManager.getInstance().readString(
-                        ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, null);
+                        ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null);
             } else {
                 status.updateState = UpdateState.NONE;
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java
index ef467b0c..91faeafd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java
@@ -69,11 +69,11 @@
 
         ChromeBaseCheckBoxPreference mAccessibilityTabSwitcherPref =
                 (ChromeBaseCheckBoxPreference) findPreference(
-                        ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER);
+                        ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER);
         if (AccessibilityUtil.isAccessibilityEnabled()) {
             mAccessibilityTabSwitcherPref.setChecked(
                     SharedPreferencesManager.getInstance().readBoolean(
-                            ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true));
+                            ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true));
         } else {
             getPreferenceScreen().removePreference(mAccessibilityTabSwitcherPref);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
index ca5cd42..b47348f49 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
@@ -11,9 +11,10 @@
 import java.util.Set;
 
 /**
- * ChromePreferenceManager stores and retrieves various values in Android shared preferences.
+ * ChromePreferenceManager stores and retrieves values in Android shared preferences for specific
+ * features.
  *
- * TODO(crbug.com/1022107): Finish moving constants to ChromePreferenceKeys.
+ * TODO(crbug.com/1022102): Finish moving feature-specific methods out of this class and delete it.
  */
 public class ChromePreferenceManager {
     // For new int values with a default of 0, just document the key and its usage, and call
@@ -21,208 +22,6 @@
     // For new boolean values, document the key and its usage, call #readBoolean and #writeBoolean
     // directly. While calling #readBoolean, default value is required.
 
-    /**
-     * Whether the promotion for data reduction has been skipped on first invocation.
-     * Default value is false.
-     */
-    public static final String PROMOS_SKIPPED_ON_FIRST_START = "promos_skipped_on_first_start";
-    private static final String SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION =
-            "signin_promo_last_shown_chrome_version";
-    private static final String SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES =
-            "signin_promo_last_shown_account_names";
-
-    /**
-     * This value was used prior to KitKat to keep existing low-end devices on the normal UI rather
-     * than the simplified UI.
-     *
-     * This value may still exist in shared preferences file. Do not reuse.
-     */
-    @Deprecated
-    public static final String ALLOW_LOW_END_DEVICE_UI = "allow_low_end_device_ui";
-
-    @Deprecated
-    private static final String PREF_WEBSITE_SETTINGS_FILTER = "website_settings_filter";
-
-    /**
-     * Whether Chrome is set as the default browser.
-     * Default value is false.
-     */
-    public static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser";
-
-    /**
-     * Deprecated in M70. This value may still exist in the shared preferences file. Do not reuse.
-     * TODO(twellington): Remove preference from the file in a future pref cleanup effort.
-     */
-    @Deprecated
-    private static final String CHROME_MODERN_DESIGN_ENABLED_KEY = "chrome_modern_design_enabled";
-
-    /**
-     * Whether or not the home page button is force enabled.
-     * Default value is false.
-     */
-    @Deprecated
-    public static final String HOME_PAGE_BUTTON_FORCE_ENABLED_KEY =
-            "home_page_button_force_enabled";
-
-    /**
-     * Whether or not the homepage tile will be shown.
-     * Default value is false.
-     */
-    @Deprecated
-    public static final String HOMEPAGE_TILE_ENABLED_KEY = "homepage_tile_enabled";
-
-    /**
-     * Whether or not the new tab page button is enabled.
-     * Default value is false.
-     */
-    @Deprecated
-    public static final String NTP_BUTTON_ENABLED_KEY = "ntp_button_enabled";
-
-    /**
-     * Deprecated in M71. This value may still exist in the shared preferences file. Do not reuse.
-     * TODO(twellington): Remove preference from the file in a future pref cleanup effort.
-     */
-    @Deprecated
-    private static final String NTP_BUTTON_VARIANT_KEY = "ntp_button_variant";
-
-    /**
-     * Deprecated in M77. This value may still exist in shared preferences file. Do not reuse.
-     */
-    @Deprecated
-    public static final String TAB_PERSISTENT_STORE_TASK_RUNNER_ENABLED_KEY =
-            "tab_persistent_store_task_runner_enabled";
-
-    /**
-     * Deprecated in M75. This value may still exist in shared preferences file. Do not reuse.
-     */
-    @Deprecated
-    private static final String INFLATE_TOOLBAR_ON_BACKGROUND_THREAD_KEY =
-            "inflate_toolbar_on_background_thread";
-
-    /**
-     * The current theme setting in the user settings.
-     * Default value is -1. Use NightModeUtils#getThemeSetting() to retrieve current setting or
-     * default theme.
-     */
-    public static final String UI_THEME_SETTING_KEY = "ui_theme_setting";
-
-    /**
-     * Whether or not darken websites is enabled.
-     * Default value is false.
-     */
-    public static final String DARKEN_WEBSITES_ENABLED_KEY = "darken_websites_enabled";
-
-    /**
-     * Marks that the content suggestions surface has been shown.
-     * Default value is false.
-     */
-    public static final String CONTENT_SUGGESTIONS_SHOWN_KEY = "content_suggestions_shown";
-
-    /**
-     * Whether the user dismissed the personalized sign in promo from the Settings.
-     * Default value is false.
-     */
-    public static final String SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED =
-            "settings_personalized_signin_promo_dismissed";
-    /**
-     * Whether the user dismissed the personalized sign in promo from the new tab page.
-     * Default value is false.
-     */
-    public static final String NTP_SIGNIN_PROMO_DISMISSED =
-            "ntp.personalized_signin_promo_dismissed";
-
-    private static final String NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START =
-            "ntp.signin_promo_suppression_period_start";
-
-    private static final String SUCCESS_UPLOAD_SUFFIX = "_crash_success_upload";
-    private static final String FAILURE_UPLOAD_SUFFIX = "_crash_failure_upload";
-
-    /**
-     * Deprecated in M76. This value may still exist in the shared preferences file. Do not reuse.
-     */
-    @Deprecated
-    public static final String SOLE_INTEGRATION_ENABLED_KEY = "sole_integration_enabled";
-
-    private static final String VERIFIED_DIGITAL_ASSET_LINKS =
-            "verified_digital_asset_links";
-    private static final String TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES =
-            "trusted_web_activity_disclosure_accepted_packages";
-
-    /**
-     * Whether VR assets component should be registered on startup.
-     * Default value is false.
-     */
-    public static final String SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP =
-            "should_register_vr_assets_component_on_startup";
-
-    /*
-     * Whether the simplified tab switcher is enabled when accessibility mode is enabled. Keep in
-     * sync with accessibility_preferences.xml.
-     * Default value is true.
-     */
-    public static final String ACCESSIBILITY_TAB_SWITCHER = "accessibility_tab_switcher";
-
-    /**
-     * When the user is shown a badge that the current Android OS version is unsupported, and they
-     * tap it to display the menu (which has additional information), we store the current version
-     * of Chrome to this preference to ensure we only show the badge once. The value is cleared
-     * if the Chrome version later changes.
-     */
-    public static final String LATEST_UNSUPPORTED_VERSION = "android_os_unsupported_chrome_version";
-
-    /**
-     * Keys for deferred recording of the outcomes of showing the clear data dialog after
-     * Trusted Web Activity client apps are uninstalled or have their data cleared.
-     */
-    public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL =
-            "twa_dialog_number_of_dismissals_on_uninstall";
-    public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA =
-            "twa_dialog_number_of_dismissals_on_clear_data";
-
-    /** Key for deferred recording of WebAPK uninstalls. */
-    @Deprecated
-    public static final String WEBAPK_NUMBER_OF_UNINSTALLS = "webapk_number_of_uninstalls";
-
-    /** Key for deferred recording of list of uninstalled WebAPK packages. */
-    public static final String WEBAPK_UNINSTALLED_PACKAGES = "webapk_uninstalled_packages";
-
-    /**
-     * Key for whether it allows to start in service manager only mode.
-     * Default value is false.
-     */
-    public static final String ALLOW_STARTING_SERVICE_MANAGER_ONLY_KEY =
-            "allow_starting_service_manager_only";
-
-    /**
-     * Deprecated keys for Chrome Home.
-     */
-    @Deprecated
-    private static final String CHROME_HOME_USER_ENABLED_KEY = "chrome_home_user_enabled";
-    @Deprecated
-    private static final String CHROME_HOME_OPT_OUT_SNACKBAR_SHOWN =
-            "chrome_home_opt_out_snackbar_shown";
-    @Deprecated
-    public static final String CHROME_HOME_INFO_PROMO_SHOWN_KEY = "chrome_home_info_promo_shown";
-    @Deprecated
-    public static final String CHROME_HOME_SHARED_PREFERENCES_KEY = "chrome_home_enabled_date";
-
-    /**
-     * Contains a trial group that was used to determine whether the reached code profiler should be
-     * enabled.
-     */
-    public static final String REACHED_CODE_PROFILER_GROUP_KEY = "reached_code_profiler_group";
-
-    /**
-     * Key to cache whether offline indicator v2 (persistent offline indicator) is enabled.
-     */
-    public static final String OFFLINE_INDICATOR_V2_ENABLED_KEY = "offline_indicator_v2_enabled";
-
-    /**
-     * Previously used to migrate {@link PrefServiceBridge} preferences to current version.
-     */
-    @Deprecated
-    private static final String MIGRATION_PREF_KEY = "PrefMigrationVersion";
-
     private static class LazyHolder {
         static final ChromePreferenceManager INSTANCE = new ChromePreferenceManager();
     }
@@ -259,7 +58,7 @@
     }
 
     private String successUploadKey(@ProcessType String process) {
-        return process.toLowerCase(Locale.US) + SUCCESS_UPLOAD_SUFFIX;
+        return process.toLowerCase(Locale.US) + ChromePreferenceKeys.SUCCESS_UPLOAD_SUFFIX;
     }
 
     /**
@@ -278,7 +77,7 @@
     }
 
     private String failureUploadKey(@ProcessType String process) {
-        return process.toLowerCase(Locale.US) + FAILURE_UPLOAD_SUFFIX;
+        return process.toLowerCase(Locale.US) + ChromePreferenceKeys.FAILURE_UPLOAD_SUFFIX;
     }
 
     /**
@@ -286,14 +85,14 @@
      * isn't known.
      */
     public int getSigninPromoLastShownVersion() {
-        return mManager.readInt(SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION);
+        return mManager.readInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION);
     }
 
     /**
      * Sets Chrome major version number when signin promo was last shown.
      */
     public void setSigninPromoLastShownVersion(int majorVersion) {
-        mManager.writeInt(SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION, majorVersion);
+        mManager.writeInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION, majorVersion);
     }
 
     /**
@@ -301,14 +100,16 @@
      * or null if promo hasn't been shown yet.
      */
     public Set<String> getSigninPromoLastAccountNames() {
-        return mManager.readStringSet(SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, null);
+        return mManager.readStringSet(
+                ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, null);
     }
 
     /**
      * Stores a set of account names on the device when signin promo is shown.
      */
     public void setSigninPromoLastAccountNames(Set<String> accountNames) {
-        mManager.writeStringSet(SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, accountNames);
+        mManager.writeStringSet(
+                ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, accountNames);
     }
 
     /**
@@ -317,7 +118,7 @@
      * @return the epoch time in milliseconds (see {@link System#currentTimeMillis()}).
      */
     public long getNewTabPageSigninPromoSuppressionPeriodStart() {
-        return mManager.readLong(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START);
+        return mManager.readLong(ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START);
     }
 
     /**
@@ -326,7 +127,8 @@
      * @param timeMillis the epoch time in milliseconds (see {@link System#currentTimeMillis()}).
      */
     public void setNewTabPageSigninPromoSuppressionPeriodStart(long timeMillis) {
-        mManager.writeLong(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START, timeMillis);
+        mManager.writeLong(
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START, timeMillis);
     }
 
     /**
@@ -334,7 +136,7 @@
      * Tab Page are no longer suppressed.
      */
     public void clearNewTabPageSigninPromoSuppressionPeriodStart() {
-        mManager.removeKey(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START);
+        mManager.removeKey(ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START);
     }
 
     /**
@@ -344,7 +146,8 @@
     public Set<String> getVerifiedDigitalAssetLinks() {
         // From the official docs, modifying the result of a SharedPreferences.getStringSet can
         // cause bad things to happen including exceptions or ruining the data.
-        return new HashSet<>(mManager.readStringSet(VERIFIED_DIGITAL_ASSET_LINKS));
+        return new HashSet<>(
+                mManager.readStringSet(ChromePreferenceKeys.VERIFIED_DIGITAL_ASSET_LINKS));
     }
 
     /**
@@ -352,12 +155,13 @@
      * Can be retrieved by {@link #getVerifiedDigitalAssetLinks()}.
      */
     public void setVerifiedDigitalAssetLinks(Set<String> links) {
-        mManager.writeStringSet(VERIFIED_DIGITAL_ASSET_LINKS, links);
+        mManager.writeStringSet(ChromePreferenceKeys.VERIFIED_DIGITAL_ASSET_LINKS, links);
     }
 
     /** Do not modify the set returned by this method. */
     private Set<String> getTrustedWebActivityDisclosureAcceptedPackages() {
-        return mManager.readStringSet(TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES);
+        return mManager.readStringSet(
+                ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES);
     }
 
     /**
@@ -365,7 +169,9 @@
      * TWAs launched by the given package.
      */
     public void setUserAcceptedTwaDisclosureForPackage(String packageName) {
-        mManager.addToStringSet(TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, packageName);
+        mManager.addToStringSet(
+                ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES,
+                packageName);
     }
 
     /**
@@ -374,7 +180,8 @@
      */
     public void removeTwaDisclosureAcceptanceForPackage(String packageName) {
         mManager.removeFromStringSet(
-                TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, packageName);
+                ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES,
+                packageName);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
index e237af0..d38b57f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
@@ -16,7 +16,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.signin.DisplayableProfileData;
@@ -168,7 +168,7 @@
         }
 
         boolean personalizedPromoDismissed = SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, false);
+                ChromePreferenceKeys.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, false);
         if (!mPersonalizedPromoEnabled || personalizedPromoDismissed) {
             setupGenericPromo();
             return;
@@ -280,7 +280,7 @@
         SigninPromoUtil.setupPromoViewFromCache(
                 mSigninPromoController, mProfileDataCache, signinPromoView, () -> {
                     SharedPreferencesManager.getInstance().writeBoolean(
-                            ChromePreferenceManager.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED,
+                            ChromePreferenceKeys.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED,
                             true);
                     update();
                 });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
index 21c1c60f..abad6cd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
@@ -4,8 +4,8 @@
 
 package org.chromium.chrome.browser.preferences.themes;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.DARKEN_WEBSITES_ENABLED_KEY;
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.DARKEN_WEBSITES_ENABLED_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import android.os.Build;
 import android.os.Bundle;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java
index f4e1fbf..5dfbe3cf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java
@@ -13,7 +13,7 @@
 import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
 import org.chromium.chrome.browser.ntp.snippets.FaviconFetchResult;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
@@ -30,10 +30,10 @@
 
     public static void recordSurfaceVisible() {
         if (!SharedPreferencesManager.getInstance().readBoolean(
-                    ChromePreferenceManager.CONTENT_SUGGESTIONS_SHOWN_KEY, false)) {
+                    ChromePreferenceKeys.CONTENT_SUGGESTIONS_SHOWN_KEY, false)) {
             RecordUserAction.record("Suggestions.FirstTimeSurfaceVisible");
             SharedPreferencesManager.getInstance().writeBoolean(
-                    ChromePreferenceManager.CONTENT_SUGGESTIONS_SHOWN_KEY, true);
+                    ChromePreferenceKeys.CONTENT_SUGGESTIONS_SHOWN_KEY, true);
         }
 
         RecordUserAction.record("Suggestions.SurfaceVisible");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
index d837a44..d3e59bd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -33,7 +33,7 @@
 import org.chromium.chrome.browser.omnibox.LocationBar;
 import org.chromium.chrome.browser.omnibox.LocationBarTablet;
 import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.toolbar.HomeButton;
@@ -715,6 +715,6 @@
 
     private boolean isAccessibilityTabSwitcherPreferenceEnabled() {
         return SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true);
+                ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
index ec760b52..a992618 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionStore;
 import org.chromium.chrome.browser.browsing_data.UrlFilter;
 import org.chromium.chrome.browser.browsing_data.UrlFilterBridge;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.webapk.lib.common.WebApkConstants;
@@ -300,7 +300,7 @@
         // Do not delete WebappDataStorage if we still need it for UKM logging.
         Set<String> webApkPackagesWithPendingUkm =
                 SharedPreferencesManager.getInstance().readStringSet(
-                        ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES);
+                        ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES);
         if (webApkPackagesWithPendingUkm.contains(webApkPackageName)) return false;
 
         return !PackageUtils.isPackageInstalled(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
index 1c799db..bd960f1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
@@ -14,7 +14,7 @@
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.test.ReachedCodeProfiler;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -105,7 +105,7 @@
         mActivityTestRule.startMainActivityFromLauncher();
         Assert.assertEquals(FAKE_GROUP_NAME,
                 SharedPreferencesManager.getInstance().readString(
-                        ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY, null));
+                        ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY, null));
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java
index 346c448..094cb976 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java
@@ -28,7 +28,6 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
@@ -93,7 +92,7 @@
         // Note that this should be done before the startMainActivityOnBlankPage(), because Chrome
         // will otherwise run this check on startup and disable BackgroundSync code.
         if (!ExternalAuthUtils.canUseGooglePlayServices()) {
-            mNativeLibraryTestRule.loadNativeLibraryAndInitBrowserProcess();
+            mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
             disableGooglePlayServicesVersionCheck();
         }
 
@@ -114,7 +113,6 @@
     @Test
     @MediumTest
     @Feature({"BackgroundSync"})
-    @DisabledTest(message = "crbug.com/1015055")
     public void onSyncCalledWithNetworkConnectivity() throws Exception {
         forceConnectionType(ConnectionType.CONNECTION_NONE);
 
@@ -148,7 +146,6 @@
     @Test
     @MediumTest
     @Feature({"BackgroundSync"})
-    @DisabledTest(message = "crbug.com/1015055")
     public void browserWakeUpScheduledWhenSyncEventFails() throws Exception {
         forceConnectionType(ConnectionType.CONNECTION_NONE);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java
index e2cfe5c..609847a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java
@@ -5,11 +5,8 @@
 package org.chromium.chrome.browser.compositor.layouts;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
+import android.content.ContextWrapper;
 import android.content.res.Resources;
-import android.os.Looper;
-import android.test.mock.MockContext;
 import android.test.mock.MockResources;
 
 /**
@@ -17,13 +14,12 @@
  * It points to a {@link MockResources} for anything that is based on xml configurations. For
  * everything else the standard provided Context should be sufficient.
  */
-public class MockContextForLayout extends MockContext {
-    private final Context mValidContext;
+public class MockContextForLayout extends ContextWrapper {
     private final MockResourcesForLayout mResources;
     private final Resources.Theme mTheme;
 
     public MockContextForLayout(Context validContext) {
-        mValidContext = validContext;
+        super(validContext);
         mResources = new MockResourcesForLayout(validContext.getResources());
         mTheme = mResources.newTheme();
     }
@@ -34,37 +30,12 @@
     }
 
     @Override
-    public ApplicationInfo getApplicationInfo() {
-        return mValidContext.getApplicationInfo();
-    }
-
-    @Override
-    public Object getSystemService(String name) {
-        return mValidContext.getSystemService(name);
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        return mValidContext.getPackageManager();
-    }
-
-    @Override
     public Context getApplicationContext() {
         return this;
     }
 
     @Override
-    public int checkCallingOrSelfPermission(String permission) {
-        return mValidContext.checkCallingOrSelfPermission(permission);
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return mValidContext.getMainLooper();
-    }
-
-    @Override
     public Resources.Theme getTheme() {
         return mTheme;
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
index 98e8d2cb1..9f24203 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
@@ -45,7 +45,7 @@
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ntp.cards.SignInPromo;
 import org.chromium.chrome.browser.ntp.snippets.SectionHeader;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
@@ -178,10 +178,10 @@
     @Feature({"FeedNewTabPage"})
     public void testSignInPromo_DismissBySwipe() {
         boolean dismissed = SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false);
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false);
         if (dismissed) {
             SharedPreferencesManager.getInstance().writeBoolean(
-                    ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false);
+                    ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false);
         }
 
         // Verify that sign-in promo is displayed initially.
@@ -205,7 +205,7 @@
 
         // Reset state.
         SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, dismissed);
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, dismissed);
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
index 50e441ab..4b72fa05 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
@@ -9,7 +9,7 @@
 import org.chromium.base.test.params.ParameterProvider;
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.chrome.browser.flags.FeatureUtilities;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.preferences.themes.ThemePreferences;
 import org.chromium.chrome.test.ui.DummyUiActivity;
@@ -65,8 +65,7 @@
      * @param nightModeEnabled Whether night mode should be enabled.
      */
     public static void setUpNightModeForChromeActivity(boolean nightModeEnabled) {
-        SharedPreferencesManager.getInstance().writeInt(
-                ChromePreferenceManager.UI_THEME_SETTING_KEY,
+        SharedPreferencesManager.getInstance().writeInt(ChromePreferenceKeys.UI_THEME_SETTING_KEY,
                 nightModeEnabled ? ThemePreferences.ThemeSetting.DARK
                                  : ThemePreferences.ThemeSetting.LIGHT);
     }
@@ -79,7 +78,6 @@
         FeatureUtilities.setNightModeAvailableForTesting(null);
         NightModeUtils.setNightModeSupportedForTesting(null);
         GlobalNightModeStateProviderHolder.resetInstanceForTesting();
-        SharedPreferencesManager.getInstance().removeKey(
-                ChromePreferenceManager.UI_THEME_SETTING_KEY);
+        SharedPreferencesManager.getInstance().removeKey(ChromePreferenceKeys.UI_THEME_SETTING_KEY);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java
index e12851a..ac99e361b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java
@@ -5,7 +5,7 @@
 package org.chromium.chrome.browser.preferences.themes;
 
 import static org.chromium.chrome.browser.ChromeFeatureList.ANDROID_NIGHT_MODE;
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java
index 3719d30..e118921 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java
@@ -15,7 +15,7 @@
 
 import static org.chromium.base.ApplicationState.HAS_RUNNING_ACTIVITIES;
 import static org.chromium.base.ApplicationState.HAS_STOPPED_ACTIVITIES;
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import android.os.Build;
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java
index ef67633..20e3137 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java
@@ -7,7 +7,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY;
+import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY;
 
 import org.junit.After;
 import org.junit.Test;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
index 82b3336..5f04c20 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -68,6 +68,7 @@
 import org.chromium.chrome.browser.ntp.snippets.KnownCategories;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
@@ -339,7 +340,7 @@
     public void tearDown() {
         CardsVariationParameters.setTestVariationParams(null);
         SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false);
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false);
         ChromePreferenceManager.getInstance().clearNewTabPageSigninPromoSuppressionPeriodStart();
         PrefServiceBridge.setInstanceForTesting(null);
         ShadowPostTask.reset();
@@ -1042,7 +1043,7 @@
         when(mMockSigninManager.isSignInAllowed()).thenReturn(true);
         when(mMockIdentityManager.hasPrimaryAccount()).thenReturn(false);
         SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false);
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false);
         useArticleCategory();
 
         final int signInPromoPosition = mAdapter.getFirstPositionForType(ItemViewType.PROMO);
@@ -1054,7 +1055,7 @@
         verify(itemDismissedCallback).onResult(anyString());
         assertFalse(isSignInPromoVisible());
         assertTrue(SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false));
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false));
         reloadNtp();
         assertFalse(isSignInPromoVisible());
     }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index d11ed97..dc2162b 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -421,7 +421,6 @@
     "//components/autofill/content/common/mojom",
     "//components/contextual_search/content/common/mojom",
     "//components/data_reduction_proxy/core/common:interfaces",
-    "//components/dom_distiller/content/common/mojom",
     "//components/metrics/public/mojom:call_stack_mojo_bindings",
     "//components/page_load_metrics/common:page_load_metrics_mojom",
     "//components/rappor/public/mojom",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index 7dccaf51..c119c34 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -56,7 +56,6 @@
     "+components/chromeos_camera/common",
     "+components/contextual_search/content/common",
     "+components/data_reduction_proxy/core/common",
-    "+components/dom_distiller/content/common",
     "+components/metrics/public",
     "+components/rappor/public",
     "+components/translate/content/common",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index b19b1c70..20e3d67 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -26,7 +26,6 @@
 #include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
 #include "components/contextual_search/content/common/mojom/contextual_search_js_api_service.mojom.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy.mojom.h"
-#include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h"
 #include "components/metrics/public/mojom/call_stack_profile_collector.mojom.h"
 #include "components/page_load_metrics/common/page_load_metrics.mojom.h"
 #include "components/rappor/public/mojom/rappor_recorder.mojom.h"
@@ -157,7 +156,6 @@
                 cros::mojom::CameraAppDeviceProvider,
 #endif
                 contextual_search::mojom::ContextualSearchJsApiService,
-                dom_distiller::mojom::DistillerJavaScriptService,
 #if BUILDFLAG(ENABLE_EXTENSIONS)
                 extensions::KeepAlive,
                 extensions::mime_handler::BeforeUnloadControl,
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 8143e61..7273eaf5 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1981,6 +1981,7 @@
     "//components/data_use_measurement/core:ascriber",
     "//components/device_event_log",
     "//components/dom_distiller/content/browser",
+    "//components/dom_distiller/content/common/mojom",
     "//components/domain_reliability",
     "//components/download/content/factory",
     "//components/download/database",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 487508e..2e4f95eddc 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1709,6 +1709,10 @@
      kOsCrOS,
      FEATURE_VALUE_TYPE(
          chromeos::features::kBluetoothAggressiveAppearanceFilter)},
+    {"cryptauth-v1-devicesync-deprecate",
+     flag_descriptions::kCryptAuthV1DeviceSyncDeprecateName,
+     flag_descriptions::kCryptAuthV1DeviceSyncDeprecateDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kCryptAuthV1DeviceSyncDeprecate)},
     {"cryptauth-v2-device-activity-status",
      flag_descriptions::kCryptAuthV2DeviceActivityStatusName,
      flag_descriptions::kCryptAuthV2DeviceActivityStatusDescription, kOsCrOS,
@@ -3012,10 +3016,9 @@
      flag_descriptions::kEnableOutOfBlinkCorsDescription, kOsAll,
      FEATURE_VALUE_TYPE(network::features::kOutOfBlinkCors)},
 
-    {"cross-origin-embedder-policy",
-     flag_descriptions::kCrossOriginEmbedderPolicyName,
-     flag_descriptions::kCrossOriginEmbedderPolicyDescription, kOsAll,
-     FEATURE_VALUE_TYPE(network::features::kCrossOriginEmbedderPolicy)},
+    {"cross-origin-isolation", flag_descriptions::kCrossOriginIsolationName,
+     flag_descriptions::kCrossOriginIsolationDescription, kOsAll,
+     FEATURE_VALUE_TYPE(network::features::kCrossOriginIsolation)},
 
     {"disable-keepalive-fetch", flag_descriptions::kDisableKeepaliveFetchName,
      flag_descriptions::kDisableKeepaliveFetchDescription, kOsAll,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
index dd3b50f..3f519bd 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -116,6 +116,33 @@
       env, base::android::ConvertUTF8ToJavaString(env, color_string));
 }
 
+// Creates the Java equivalent to |login_choices|.
+base::android::ScopedJavaLocalRef<jobject> CreateJavaLoginChoiceList(
+    JNIEnv* env,
+    const std::vector<LoginChoice>& login_choices) {
+  auto jlist = Java_AssistantCollectUserDataModel_createLoginChoiceList(env);
+  for (const auto& login_choice : login_choices) {
+    base::android::ScopedJavaLocalRef<jobject> jinfo_popup = nullptr;
+    if (login_choice.info_popup.has_value()) {
+      jinfo_popup = Java_AssistantCollectUserDataModel_createInfoPopup(
+          env,
+          base::android::ConvertUTF8ToJavaString(
+              env, login_choice.info_popup->title()),
+          base::android::ConvertUTF8ToJavaString(
+              env, login_choice.info_popup->text()));
+    }
+    Java_AssistantCollectUserDataModel_addLoginChoice(
+        env, jlist,
+        base::android::ConvertUTF8ToJavaString(env, login_choice.identifier),
+        base::android::ConvertUTF8ToJavaString(env, login_choice.label),
+        base::android::ConvertUTF8ToJavaString(env, login_choice.sublabel),
+        base::android::ConvertUTF8ToJavaString(
+            env, login_choice.sublabel_accessibility_hint),
+        login_choice.preselect_priority, jinfo_popup);
+  }
+  return jlist;
+}
+
 // Creates the java equivalent to the text inputs specified in |section|.
 base::android::ScopedJavaLocalRef<jobject> CreateJavaTextInputsForSection(
     JNIEnv* env,
@@ -888,14 +915,8 @@
       base::android::ToJavaArrayOfStrings(
           env, collect_user_data_options->supported_basic_card_networks));
   if (collect_user_data_options->request_login_choice) {
-    auto jlist = Java_AssistantCollectUserDataModel_createLoginChoiceList(env);
-    for (const auto& login_choice : collect_user_data_options->login_choices) {
-      Java_AssistantCollectUserDataModel_addLoginChoice(
-          env, jmodel, jlist,
-          base::android::ConvertUTF8ToJavaString(env, login_choice.identifier),
-          base::android::ConvertUTF8ToJavaString(env, login_choice.label),
-          login_choice.preselect_priority);
-    }
+    auto jlist = CreateJavaLoginChoiceList(
+        env, collect_user_data_options->login_choices);
     Java_AssistantCollectUserDataModel_setLoginChoices(env, jmodel, jlist);
   }
   Java_AssistantCollectUserDataModel_setRequestDateRange(
diff --git a/chrome/browser/android/background_sync_launcher_android.cc b/chrome/browser/android/background_sync_launcher_android.cc
index 1a6626b..8189768 100644
--- a/chrome/browser/android/background_sync_launcher_android.cc
+++ b/chrome/browser/android/background_sync_launcher_android.cc
@@ -82,7 +82,6 @@
 // static
 void BackgroundSyncLauncherAndroid::SetPlayServicesVersionCheckDisabledForTests(
     bool disabled) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   disable_play_services_version_check_for_tests = disabled;
 }
 
diff --git a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc
index fa3154e..a78d025 100644
--- a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc
+++ b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc
@@ -8,6 +8,7 @@
 #include "chrome/android/chrome_jni_headers/DomDistillerUIUtils_jni.h"
 #include "chrome/browser/ui/android/view_android_helper.h"
 #include "components/dom_distiller/core/url_utils.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/android/window_android.h"
 #include "url/gurl.h"
@@ -18,10 +19,12 @@
 
 namespace android {
 
-// static
-void DistillerUIHandleAndroid::OpenSettings(
-    content::WebContents* web_contents) {
+void DistillerUIHandleAndroid::OpenSettings() {
   JNIEnv* env = base::android::AttachCurrentThread();
+
+  DCHECK(render_frame_host_);
+  content::WebContents* web_contents =
+      content::WebContents::FromRenderFrameHost(render_frame_host_);
   Java_DomDistillerUIUtils_openSettings(env,
                                         web_contents->GetJavaWebContents());
 }
diff --git a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h
index 0045e744..f79b3ea 100644
--- a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h
+++ b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h
@@ -6,8 +6,11 @@
 #define CHROME_BROWSER_ANDROID_DOM_DISTILLER_DISTILLER_UI_HANDLE_ANDROID_H_
 
 #include "base/macros.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
-#include "content/public/browser/web_contents.h"
+#include "components/dom_distiller/core/distiller_ui_handle.h"
+
+namespace content {
+class RenderFrameHost;
+}
 
 namespace dom_distiller {
 
@@ -18,9 +21,13 @@
   DistillerUIHandleAndroid() {}
   ~DistillerUIHandleAndroid() override {}
 
-  void OpenSettings(content::WebContents* web_contents) override;
+  void set_render_frame_host(content::RenderFrameHost* host) {
+    render_frame_host_ = host;
+  }
+  void OpenSettings() override;
 
  private:
+  content::RenderFrameHost* render_frame_host_ = nullptr;
   DISALLOW_COPY_AND_ASSIGN(DistillerUIHandleAndroid);
 };
 
diff --git a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
index 16af4395..2dc59d7 100644
--- a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
+++ b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
@@ -63,10 +64,12 @@
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
+    base::FilePath sub_dir =
+        temp_dir_.GetPath().AppendASCII("BackgroundSyncTest");
+    ASSERT_TRUE(base::CreateDirectory(sub_dir));
+
     HistoryServiceFactory::GetInstance()->SetTestingFactory(
-        &profile_, base::BindRepeating(
-                       &BuildTestHistoryService,
-                       temp_dir_.GetPath().AppendASCII("BackgroundSyncTest")));
+        &profile_, base::BindRepeating(&BuildTestHistoryService, sub_dir));
     controller_ = std::make_unique<BackgroundSyncControllerImpl>(&profile_);
   }
 
@@ -94,10 +97,10 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
+  base::ScopedTempDir temp_dir_;
   TestingProfile profile_;
   std::unique_ptr<BackgroundSyncControllerImpl> controller_;
   std::unique_ptr<base::FieldTrialList> field_trial_list_;
-  base::ScopedTempDir temp_dir_;
 
   DISALLOW_COPY_AND_ASSIGN(BackgroundSyncControllerImplTest);
 };
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 6b1cc8d..f1b14d8 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -11,13 +11,17 @@
 #include "chrome/browser/accessibility/accessibility_labels_service.h"
 #include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
 #include "chrome/browser/content_settings/content_settings_manager_impl.h"
+#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
 #include "chrome/browser/navigation_predictor/navigation_predictor.h"
 #include "chrome/browser/prerender/prerender_contents.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ssl/insecure_sensitive_input_driver_factory.h"
 #include "chrome/common/prerender.mojom.h"
 #include "components/dom_distiller/content/browser/distillability_driver.h"
+#include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h"
 #include "components/dom_distiller/content/common/mojom/distillability_service.mojom.h"
+#include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h"
+#include "components/dom_distiller/core/dom_distiller_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -37,6 +41,7 @@
 #endif  // BUILDFLAG(ENABLE_UNHANDLED_TAP)
 
 #if defined(OS_ANDROID)
+#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h"
 #include "content/public/browser/web_contents.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h"
@@ -97,6 +102,23 @@
   driver->CreateDistillabilityService(std::move(receiver));
 }
 
+void BindDistillerJavaScriptService(
+    content::RenderFrameHost* const frame_host,
+    mojo::PendingReceiver<dom_distiller::mojom::DistillerJavaScriptService>
+        receiver) {
+  dom_distiller::DomDistillerService* dom_distiller_service =
+      dom_distiller::DomDistillerServiceFactory::GetForBrowserContext(
+          content::WebContents::FromRenderFrameHost(frame_host)
+              ->GetBrowserContext());
+  auto* distiller_ui_handle = dom_distiller_service->GetDistillerUIHandle();
+#if defined(OS_ANDROID)
+  static_cast<dom_distiller::android::DistillerUIHandleAndroid*>(
+      distiller_ui_handle)
+      ->set_render_frame_host(frame_host);
+#endif
+  CreateDistillerJavaScriptService(distiller_ui_handle, std::move(receiver));
+}
+
 void BindPrerenderCanceler(
     content::RenderFrameHost* frame_host,
     mojo::PendingReceiver<mojom::PrerenderCanceler> receiver) {
@@ -157,6 +179,9 @@
   map->Add<dom_distiller::mojom::DistillabilityService>(
       base::BindRepeating(&BindDistillabilityService));
 
+  map->Add<dom_distiller::mojom::DistillerJavaScriptService>(
+      base::BindRepeating(&BindDistillerJavaScriptService));
+
   map->Add<mojom::PrerenderCanceler>(
       base::BindRepeating(&BindPrerenderCanceler));
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 8e200cf..43cb024 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -2013,6 +2013,8 @@
     "printing/printer_metrics_provider.h",
     "printing/printers_map.cc",
     "printing/printers_map.h",
+    "printing/printers_model_type_controller.cc",
+    "printing/printers_model_type_controller.h",
     "printing/printers_sync_bridge.cc",
     "printing/printers_sync_bridge.h",
     "printing/server_printers_fetcher.cc",
@@ -2122,6 +2124,8 @@
     "smb_client/temp_file_manager.h",
     "startup_settings_cache.cc",
     "startup_settings_cache.h",
+    "sync/os_preferences_model_type_controller.cc",
+    "sync/os_preferences_model_type_controller.h",
     "system/automatic_reboot_manager.cc",
     "system/automatic_reboot_manager.h",
     "system/automatic_reboot_manager_observer.h",
@@ -2935,21 +2939,8 @@
     "../ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc",
     "../ui/webui/settings/chromeos/internet_handler_unittest.cc",
     "../ui/webui/settings/chromeos/multidevice_handler_unittest.cc",
-    "//components/drive/change_list_processor_unittest.cc",
-    "//components/drive/chromeos/file_cache_unittest.cc",
-    "//components/drive/drive_file_util_unittest.cc",
     "//components/drive/drive_notification_manager_unittest.cc",
-    "//components/drive/drive_operation_queue_unittest.cc",
-    "//components/drive/file_change_unittest.cc",
-    "//components/drive/file_system_core_util_unittest.cc",
-    "//components/drive/file_write_watcher_unittest.cc",
-    "//components/drive/job_queue_unittest.cc",
-    "//components/drive/job_scheduler_unittest.cc",
-    "//components/drive/local_file_reader_unittest.cc",
-    "//components/drive/remove_stale_cache_files_unittest.cc",
-    "//components/drive/resource_entry_conversion_unittest.cc",
     "//components/drive/resource_metadata_storage_unittest.cc",
-    "//components/drive/resource_metadata_unittest.cc",
     "//components/drive/search_metadata_unittest.cc",
   ]
 
@@ -3020,9 +3011,7 @@
     "//components/crx_file",
     "//components/download/public/background_service/test:test_support",
     "//components/drive",
-    "//components/drive:drive_chromeos",
     "//components/drive:test_support",
-    "//components/drive:test_support_chromeos",
     "//components/exo",
     "//components/invalidation/impl:test_support",
     "//components/invalidation/public",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index 3e8b8ce0..d3eed6e3 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -66,9 +66,7 @@
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/arc/test/connection_holder_util.h"
 #include "components/arc/test/fake_file_system_instance.h"
-#include "components/drive/chromeos/file_system_interface.h"
 #include "components/drive/drive_pref_names.h"
-#include "components/drive/service/fake_drive_service.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc
index 575c255..4c04b37b 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.cc
+++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -288,15 +288,18 @@
   OnLaunchFailed(KioskAppLaunchError::USER_CANCEL);
 }
 
-void AppLaunchController::OnNetworkConfigRequested(bool requested) {
-  network_config_requested_ = requested;
-  if (requested) {
-    MaybeShowNetworkConfigureUI();
-  } else {
-    app_launch_splash_screen_view_->UpdateAppLaunchState(
-        AppLaunchSplashScreenView::APP_LAUNCH_STATE_PREPARING_NETWORK);
-    startup_app_launcher_->RestartLauncher();
-  }
+void AppLaunchController::OnNetworkConfigRequested() {
+  DCHECK(!network_config_requested_);
+  network_config_requested_ = true;
+  MaybeShowNetworkConfigureUI();
+}
+
+void AppLaunchController::OnNetworkConfigFinished() {
+  DCHECK(network_config_requested_);
+  network_config_requested_ = false;
+  app_launch_splash_screen_view_->UpdateAppLaunchState(
+      AppLaunchSplashScreenView::APP_LAUNCH_STATE_PREPARING_NETWORK);
+  startup_app_launcher_->RestartLauncher();
 }
 
 void AppLaunchController::OnNetworkStateChanged(bool online) {
diff --git a/chrome/browser/chromeos/login/app_launch_controller.h b/chrome/browser/chromeos/login/app_launch_controller.h
index 6ae3fe1..b09f5e4 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.h
+++ b/chrome/browser/chromeos/login/app_launch_controller.h
@@ -58,7 +58,8 @@
   // AppLaunchSplashScreenView::Delegate:
   void OnConfigureNetwork() override;
   void OnCancelAppLaunch() override;
-  void OnNetworkConfigRequested(bool requested) override;
+  void OnNetworkConfigRequested() override;
+  void OnNetworkConfigFinished() override;
   void OnNetworkStateChanged(bool online) override;
   void OnDeletingSplashScreenView() override;
   KioskAppManagerBase::App GetAppData() override;
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog.cc b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
index 7cc30bb..e81e41a 100644
--- a/chrome/browser/chromeos/login/ui/login_web_dialog.cc
+++ b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
@@ -56,8 +56,7 @@
       delegate_(delegate),
       title_(title),
       url_(url) {
-  if (!parent_window_) {
-    DCHECK(chromeos::LoginDisplayHost::default_host());
+  if (!parent_window_ && chromeos::LoginDisplayHost::default_host()) {
     parent_window_ =
         chromeos::LoginDisplayHost::default_host()->GetNativeWindow();
   }
@@ -93,6 +92,11 @@
     std::vector<WebUIMessageHandler*>* handlers) const {}
 
 void LoginWebDialog::GetDialogSize(gfx::Size* size) const {
+  // TODO(https://crbug.com/1022774): Fix for the lock screen.
+  if (!parent_window_) {
+    *size = kMaxSize;
+    return;
+  }
   gfx::Rect bounds = parent_window_->bounds();
   bounds.Inset(kMinMargins);
   *size = bounds.size();
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc b/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc
index 2e1f650..0874047 100644
--- a/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc
+++ b/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc
@@ -45,4 +45,13 @@
   EXPECT_TRUE(closing_observer.widget_closed());
 }
 
+// Tests that LoginWebDialog does not crash with missing parent window.
+IN_PROC_BROWSER_TEST_F(LoginWebDialogTest, NoParentWindow) {
+  LoginWebDialog* dialog = new LoginWebDialog(
+      browser()->profile(), nullptr, nullptr, base::string16(), GURL());
+  dialog->Show();
+  aura::Window* window = dialog->get_dialog_window_for_test();
+  ASSERT_TRUE(window);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.cc b/chrome/browser/chromeos/login/web_kiosk_controller.cc
index ff4c940b..0e863699e 100644
--- a/chrome/browser/chromeos/login/web_kiosk_controller.cc
+++ b/chrome/browser/chromeos/login/web_kiosk_controller.cc
@@ -67,17 +67,17 @@
   }
 }
 
-void WebKioskController::OnConfigureNetwork() {
-  // TODO(crbug.com/1006230): Implement when app launch logic is done.
-}
-
 void WebKioskController::OnCancelAppLaunch() {
   KioskAppLaunchError::Save(KioskAppLaunchError::USER_CANCEL);
   CleanUp();
   chrome::AttemptUserExit();
 }
 
-void WebKioskController::OnNetworkConfigRequested(bool requested) {
+void WebKioskController::OnNetworkConfigRequested() {
+  // TODO(crbug.com/1006230): Implement when app launch logic is done.
+}
+
+void WebKioskController::OnNetworkConfigFinished() {
   // TODO(crbug.com/1006230): Implement when app launch logic is done.
 }
 
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.h b/chrome/browser/chromeos/login/web_kiosk_controller.h
index 4cfea7f..22de152f 100644
--- a/chrome/browser/chromeos/login/web_kiosk_controller.h
+++ b/chrome/browser/chromeos/login/web_kiosk_controller.h
@@ -52,9 +52,9 @@
   void OnProfilePrepared(Profile* profile, bool browser_launched) override;
 
   // AppLaunchSplashScreenView::Delegate:
-  void OnConfigureNetwork() override;
   void OnCancelAppLaunch() override;
-  void OnNetworkConfigRequested(bool requested) override;
+  void OnNetworkConfigRequested() override;
+  void OnNetworkConfigFinished() override;
   void OnNetworkStateChanged(bool online) override;
   void OnDeletingSplashScreenView() override;
   KioskAppManagerBase::App GetAppData() override;
diff --git a/chrome/browser/chromeos/printing/printers_model_type_controller.cc b/chrome/browser/chromeos/printing/printers_model_type_controller.cc
new file mode 100644
index 0000000..b2a9a4d
--- /dev/null
+++ b/chrome/browser/chromeos/printing/printers_model_type_controller.cc
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/printing/printers_model_type_controller.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "components/prefs/pref_service.h"
+#include "components/sync/base/model_type.h"
+#include "components/sync/base/pref_names.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/model/model_type_controller_delegate.h"
+
+PrintersModelTypeController::PrintersModelTypeController(
+    std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate,
+    PrefService* pref_service,
+    syncer::SyncService* sync_service)
+    : syncer::ModelTypeController(syncer::PRINTERS, std::move(delegate)),
+      pref_service_(pref_service),
+      sync_service_(sync_service) {
+  DCHECK(chromeos::features::IsSplitSettingsSyncEnabled());
+  DCHECK(pref_service_);
+  DCHECK(sync_service_);
+  pref_registrar_.Init(pref_service_);
+  pref_registrar_.Add(
+      syncer::prefs::kOsSyncFeatureEnabled,
+      base::BindRepeating(&PrintersModelTypeController::OnUserPrefChanged,
+                          base::Unretained(this)));
+}
+
+PrintersModelTypeController::~PrintersModelTypeController() = default;
+
+syncer::DataTypeController::PreconditionState
+PrintersModelTypeController::GetPreconditionState() const {
+  DCHECK(CalledOnValidThread());
+  return pref_service_->GetBoolean(syncer::prefs::kOsSyncFeatureEnabled)
+             ? PreconditionState::kPreconditionsMet
+             : PreconditionState::kMustStopAndClearData;
+}
+
+void PrintersModelTypeController::OnUserPrefChanged() {
+  DCHECK(CalledOnValidThread());
+  sync_service_->DataTypePreconditionChanged(type());
+}
diff --git a/chrome/browser/chromeos/printing/printers_model_type_controller.h b/chrome/browser/chromeos/printing/printers_model_type_controller.h
new file mode 100644
index 0000000..2269876
--- /dev/null
+++ b/chrome/browser/chromeos/printing/printers_model_type_controller.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_
+#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_
+
+#include "components/prefs/pref_change_registrar.h"
+#include "components/sync/driver/model_type_controller.h"
+
+class PrefService;
+
+namespace syncer {
+class ModelTypeControllerDelegate;
+class SyncService;
+}  // namespace syncer
+
+// Controls syncing of ModelType PRINTERS.
+class PrintersModelTypeController : public syncer::ModelTypeController {
+ public:
+  PrintersModelTypeController(
+      std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate,
+      PrefService* pref_service,
+      syncer::SyncService* sync_service);
+  ~PrintersModelTypeController() override;
+
+  PrintersModelTypeController(const PrintersModelTypeController&) = delete;
+  PrintersModelTypeController& operator=(const PrintersModelTypeController&) =
+      delete;
+
+  // DataTypeController:
+  PreconditionState GetPreconditionState() const override;
+
+ private:
+  // Callback for changes to the OS sync feature enabled pref.
+  void OnUserPrefChanged();
+
+  PrefService* const pref_service_;
+  syncer::SyncService* const sync_service_;
+
+  PrefChangeRegistrar pref_registrar_;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc
new file mode 100644
index 0000000..4490e722
--- /dev/null
+++ b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc
@@ -0,0 +1,55 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/sync/os_preferences_model_type_controller.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "components/prefs/pref_service.h"
+#include "components/sync/base/model_type.h"
+#include "components/sync/base/pref_names.h"
+#include "components/sync/driver/sync_service.h"
+
+OsPreferencesModelTypeController::OsPreferencesModelTypeController(
+    syncer::ModelType type,
+    syncer::OnceModelTypeStoreFactory store_factory,
+    base::WeakPtr<syncer::SyncableService> syncable_service,
+    const base::RepeatingClosure& dump_stack,
+    PrefService* pref_service,
+    syncer::SyncService* sync_service)
+    : syncer::SyncableServiceBasedModelTypeController(type,
+                                                      std::move(store_factory),
+                                                      syncable_service,
+                                                      dump_stack),
+      pref_service_(pref_service),
+      sync_service_(sync_service) {
+  DCHECK(chromeos::features::IsSplitSettingsSyncEnabled());
+  DCHECK(type == syncer::OS_PREFERENCES ||
+         type == syncer::OS_PRIORITY_PREFERENCES);
+  DCHECK(pref_service_);
+  DCHECK(sync_service_);
+  pref_registrar_.Init(pref_service_);
+  pref_registrar_.Add(
+      syncer::prefs::kOsSyncFeatureEnabled,
+      base::BindRepeating(&OsPreferencesModelTypeController::OnUserPrefChanged,
+                          base::Unretained(this)));
+}
+
+OsPreferencesModelTypeController::~OsPreferencesModelTypeController() = default;
+
+syncer::DataTypeController::PreconditionState
+OsPreferencesModelTypeController::GetPreconditionState() const {
+  DCHECK(CalledOnValidThread());
+  return pref_service_->GetBoolean(syncer::prefs::kOsSyncFeatureEnabled)
+             ? PreconditionState::kPreconditionsMet
+             : PreconditionState::kMustStopAndClearData;
+}
+
+void OsPreferencesModelTypeController::OnUserPrefChanged() {
+  DCHECK(CalledOnValidThread());
+  sync_service_->DataTypePreconditionChanged(type());
+}
diff --git a/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h
new file mode 100644
index 0000000..4267219
--- /dev/null
+++ b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_
+#define CHROME_BROWSER_CHROMEOS_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_
+
+#include "base/callback_forward.h"
+#include "base/memory/weak_ptr.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "components/sync/driver/syncable_service_based_model_type_controller.h"
+#include "components/sync/model/model_type_store.h"
+
+class PrefService;
+
+namespace syncer {
+class SyncService;
+}
+
+// Controls syncing of ModelTypes OS_PREFERENCES and OS_PRIORITY_PREFERENCES.
+class OsPreferencesModelTypeController
+    : public syncer::SyncableServiceBasedModelTypeController {
+ public:
+  OsPreferencesModelTypeController(
+      syncer::ModelType type,
+      syncer::OnceModelTypeStoreFactory store_factory,
+      base::WeakPtr<syncer::SyncableService> syncable_service,
+      const base::RepeatingClosure& dump_stack,
+      PrefService* pref_service,
+      syncer::SyncService* sync_service);
+  ~OsPreferencesModelTypeController() override;
+
+  OsPreferencesModelTypeController(const OsPreferencesModelTypeController&) =
+      delete;
+  OsPreferencesModelTypeController& operator=(
+      const OsPreferencesModelTypeController&) = delete;
+
+  // DataTypeController:
+  PreconditionState GetPreconditionState() const override;
+
+ private:
+  // Callback for changes to the OS sync feature enabled pref.
+  void OnUserPrefChanged();
+
+  PrefService* const pref_service_;
+  syncer::SyncService* const sync_service_;
+
+  PrefChangeRegistrar pref_registrar_;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
index 733d2e7..f57033e 100644
--- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc
+++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -38,9 +38,9 @@
      "1913a5e0a6cad30b6f03e176177e0d7ed62c5d6700a9c66da556d7c3f5d6a47e"},
     {"cros-termina", "800.1",
      "e9d960f84f628e1f42d05de4046bb5b3154b6f1f65c08412c6af57a29aecaffb"},
-    {"rtanalytics-light", "14.0",
+    {"rtanalytics-light", "15.0",
      "69f09d33c439c2ab55bbbe24b47ab55cb3f6c0bd1f1ef46eefea3216ec925038"},
-    {"rtanalytics-full", "14.0",
+    {"rtanalytics-full", "15.0",
      "c93c3e1013c52100a20038b405ac854d69fa889f6dc4fa6f188267051e05e444"},
     {"star-cups-driver", "1.1",
      "6d24de30f671da5aee6d463d9e446cafe9ddac672800a9defe86877dcde6c466"},
diff --git a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
index b6ceed8..9a0006e 100644
--- a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
+++ b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
@@ -249,4 +249,14 @@
       Optional(AllOf(Not(IsDistillable()), IsLast(), Not(IsMobileFriendly()))));
 }
 
+IN_PROC_BROWSER_TEST_F(DistillablePageUtilsBrowserTestAllArticles,
+                       ObserverNotCalledAfterRemoval) {
+  RemoveObserver(web_contents_, &holder_);
+  EXPECT_CALL(holder_, OnResult(_)).Times(0);
+  NavigateAndWait(kSimpleArticlePath, kWaitNoExpectedCall);
+  EXPECT_THAT(
+      GetLatestResult(web_contents_),
+      Optional(AllOf(IsDistillable(), IsLast(), Not(IsMobileFriendly()))));
+}
+
 }  // namespace dom_distiller
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
index 0ac7729..d56aa95 100644
--- a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
+++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -8,6 +8,7 @@
 
 #include "base/sequenced_task_runner.h"
 #include "base/task/post_task.h"
+#include "build/build_config.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/dom_distiller/content/browser/distiller_page_web_contents.h"
@@ -18,15 +19,21 @@
 #include "content/public/browser/storage_partition.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h"
+#endif  // defined(OS_ANDROID)
+
 namespace dom_distiller {
 
 DomDistillerContextKeyedService::DomDistillerContextKeyedService(
     std::unique_ptr<DistillerFactory> distiller_factory,
     std::unique_ptr<DistillerPageFactory> distiller_page_factory,
-    std::unique_ptr<DistilledPagePrefs> distilled_page_prefs)
+    std::unique_ptr<DistilledPagePrefs> distilled_page_prefs,
+    std::unique_ptr<DistillerUIHandle> distiller_ui_handle)
     : DomDistillerService(std::move(distiller_factory),
                           std::move(distiller_page_factory),
-                          std::move(distilled_page_prefs)) {}
+                          std::move(distilled_page_prefs),
+                          std::move(distiller_ui_handle)) {}
 
 // static
 DomDistillerServiceFactory* DomDistillerServiceFactory::GetInstance() {
@@ -80,11 +87,17 @@
       std::move(distiller_url_fetcher_factory), options));
   std::unique_ptr<DistilledPagePrefs> distilled_page_prefs(
       new DistilledPagePrefs(profile->GetPrefs()));
+  std::unique_ptr<DistillerUIHandle> distiller_ui_handle;
+
+#if defined(OS_ANDROID)
+  distiller_ui_handle =
+      std::make_unique<dom_distiller::android::DistillerUIHandleAndroid>();
+#endif  // defined(OS_ANDROID)
 
   DomDistillerContextKeyedService* service =
-      new DomDistillerContextKeyedService(std::move(distiller_factory),
-                                          std::move(distiller_page_factory),
-                                          std::move(distilled_page_prefs));
+      new DomDistillerContextKeyedService(
+          std::move(distiller_factory), std::move(distiller_page_factory),
+          std::move(distilled_page_prefs), std::move(distiller_ui_handle));
 
   return service;
 }
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.h b/chrome/browser/dom_distiller/dom_distiller_service_factory.h
index e28ad13f..e51ccd87 100644
--- a/chrome/browser/dom_distiller/dom_distiller_service_factory.h
+++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/memory/singleton.h"
 #include "components/dom_distiller/core/distilled_page_prefs.h"
+#include "components/dom_distiller/core/distiller_ui_handle.h"
 #include "components/dom_distiller/core/dom_distiller_service.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -26,7 +27,8 @@
   DomDistillerContextKeyedService(
       std::unique_ptr<DistillerFactory> distiller_factory,
       std::unique_ptr<DistillerPageFactory> distiller_page_factory,
-      std::unique_ptr<DistilledPagePrefs> distilled_page_prefs);
+      std::unique_ptr<DistilledPagePrefs> distilled_page_prefs,
+      std::unique_ptr<DistillerUIHandle> distiller_ui_handle);
   ~DomDistillerContextKeyedService() override {}
 
  private:
diff --git a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
index 006d5aa..217c44f2 100644
--- a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
+++ b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
@@ -118,7 +118,8 @@
     auto service = std::make_unique<DomDistillerContextKeyedService>(
         std::move(distiller_factory), std::move(distiller_page_factory),
         std::make_unique<DistilledPagePrefs>(
-            Profile::FromBrowserContext(context)->GetPrefs()));
+            Profile::FromBrowserContext(context)->GetPrefs()),
+        /* distiller_ui_handle */ nullptr);
     if (expect_distillation_) {
       // There will only be destillation of an article if the database contains
       // the article.
diff --git a/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc b/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc
index 28acfac..98cf30b 100644
--- a/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc
+++ b/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc
@@ -55,6 +55,10 @@
   return GetImpl()->GetDistilledPagePrefs();
 }
 
+DistillerUIHandle* LazyDomDistillerService::GetDistillerUIHandle() {
+  return GetImpl()->GetDistillerUIHandle();
+}
+
 LazyDomDistillerService::LazyDomDistillerService(Profile* profile)
     : profile_(profile) {}
 
diff --git a/chrome/browser/dom_distiller/lazy_dom_distiller_service.h b/chrome/browser/dom_distiller/lazy_dom_distiller_service.h
index 23895af..d605f9b5 100644
--- a/chrome/browser/dom_distiller/lazy_dom_distiller_service.h
+++ b/chrome/browser/dom_distiller/lazy_dom_distiller_service.h
@@ -37,6 +37,7 @@
   std::unique_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle(
       std::unique_ptr<SourcePageHandle> handle) override;
   DistilledPagePrefs* GetDistilledPagePrefs() override;
+  DistillerUIHandle* GetDistillerUIHandle() override;
 
  private:
   explicit LazyDomDistillerService(Profile* profile);
diff --git a/chrome/browser/dom_distiller/profile_utils.cc b/chrome/browser/dom_distiller/profile_utils.cc
index 59230bb..09c07fd 100644
--- a/chrome/browser/dom_distiller/profile_utils.cc
+++ b/chrome/browser/dom_distiller/profile_utils.cc
@@ -13,15 +13,10 @@
 #include "chrome/common/chrome_isolated_world_ids.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/dom_distiller/content/browser/distiller_javascript_utils.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
 #include "components/dom_distiller/content/browser/dom_distiller_viewer_source.h"
 #include "components/dom_distiller/core/dom_distiller_features.h"
 #include "components/dom_distiller/core/url_constants.h"
 
-#if defined(OS_ANDROID)
-#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h"
-#endif  // defined(OS_ANDROID)
-
 namespace dom_distiller {
 
 void RegisterViewerSource(Profile* profile) {
@@ -30,20 +25,14 @@
 
   LazyDomDistillerService* lazy_service =
       LazyDomDistillerService::Create(profile);
-  std::unique_ptr<DistillerUIHandle> ui_handle;
-
-#if defined(OS_ANDROID)
-  ui_handle =
-      std::make_unique<dom_distiller::android::DistillerUIHandleAndroid>();
-#endif  // defined(OS_ANDROID)
 
   // Set the JavaScript world ID.
   if (!DistillerJavaScriptWorldIdIsSet())
     SetDistillerJavaScriptWorldId(ISOLATED_WORLD_ID_CHROME_INTERNAL);
 
   content::URLDataSource::Add(
-      profile, std::make_unique<DomDistillerViewerSource>(
-                   lazy_service, kDomDistillerScheme, std::move(ui_handle)));
+      profile, std::make_unique<DomDistillerViewerSource>(lazy_service,
+                                                          kDomDistillerScheme));
 }
 
 }  // namespace dom_distiller
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
index 538751dcb..8ebab3b 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h"
 
 #include <memory>
+#include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/json/json_writer.h"
@@ -51,7 +53,9 @@
 
 EnterpriseReportingPrivateUploadChromeDesktopReportFunction::
     EnterpriseReportingPrivateUploadChromeDesktopReportFunction(
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+    : dm_token_(
+          policy::BrowserDMTokenStorage::BrowserDMToken::CreateEmptyToken()) {
   policy::DeviceManagementService* device_management_service =
       g_browser_process->browser_policy_connector()
           ->device_management_service();
@@ -66,7 +70,7 @@
       std::string() /* manufacture_date */, device_management_service,
       std::move(url_loader_factory), nullptr,
       policy::CloudPolicyClient::DeviceDMTokenCallback());
-  dm_token_ = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken();
+  dm_token_ = policy::BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken();
   client_id_ = policy::BrowserDMTokenStorage::Get()->RetrieveClientId();
 }
 
@@ -85,7 +89,7 @@
 EnterpriseReportingPrivateUploadChromeDesktopReportFunction::Run() {
   VLOG(1) << "Uploading enterprise report";
 
-  if (dm_token_.empty() || client_id_.empty()) {
+  if (!dm_token_.is_valid() || client_id_.empty()) {
     LogReportError("Device is not enrolled.");
     return RespondNow(Error(enterprise_reporting::kDeviceNotEnrolled));
   }
@@ -104,7 +108,7 @@
   }
 
   if (!cloud_policy_client_->is_registered())
-    cloud_policy_client_->SetupRegistration(dm_token_, client_id_,
+    cloud_policy_client_->SetupRegistration(dm_token_.value(), client_id_,
                                             std::vector<std::string>());
 
   cloud_policy_client_->UploadChromeDesktopReport(
@@ -123,8 +127,9 @@
 }
 
 void EnterpriseReportingPrivateUploadChromeDesktopReportFunction::
-    SetRegistrationInfoForTesting(const std::string& dm_token,
-                                  const std::string& client_id) {
+    SetRegistrationInfoForTesting(
+        const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token,
+        const std::string& client_id) {
   dm_token_ = dm_token;
   client_id_ = client_id;
 }
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
index ec772107..d125f544 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
@@ -5,7 +5,11 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_ENTERPRISE_REPORTING_PRIVATE_API_H_
 #define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_ENTERPRISE_REPORTING_PRIVATE_API_H_
 
+#include <memory>
+#include <string>
+
 #include "base/memory/ref_counted.h"
+#include "chrome/browser/policy/browser_dm_token_storage.h"
 #include "extensions/browser/extension_function.h"
 
 namespace policy {
@@ -39,8 +43,9 @@
 
   void SetCloudPolicyClientForTesting(
       std::unique_ptr<policy::CloudPolicyClient> client);
-  void SetRegistrationInfoForTesting(const std::string& dm_token,
-                                     const std::string& client_id);
+  void SetRegistrationInfoForTesting(
+      const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token,
+      const std::string& client_id);
 
   // Used by tests that want to overrode the URLLoaderFactory used to simulate
   // network requests.
@@ -58,7 +63,7 @@
   void OnReportUploaded(bool status);
 
   std::unique_ptr<policy::CloudPolicyClient> cloud_policy_client_;
-  std::string dm_token_;
+  policy::BrowserDMTokenStorage::BrowserDMToken dm_token_;
   std::string client_id_;
 
   DISALLOW_COPY_AND_ASSIGN(
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
index 344b323..06829af 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -43,7 +43,16 @@
         test_url_loader_factory_.GetSafeWeakWrapper());
     client_ = client.get();
     function->SetCloudPolicyClientForTesting(std::move(client));
-    function->SetRegistrationInfoForTesting(dm_token, kFakeClientId);
+    if (dm_token.empty()) {
+      function->SetRegistrationInfoForTesting(
+          policy::BrowserDMTokenStorage::BrowserDMToken::CreateEmptyToken(),
+          kFakeClientId);
+    } else {
+      function->SetRegistrationInfoForTesting(
+          policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken(
+              dm_token),
+          kFakeClientId);
+    }
     return function;
   }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 8fbe1df..fcff95f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -555,7 +555,7 @@
     "expiry_milestone": 80
   },
   {
-    "name": "cross-origin-embedder-policy",
+    "name": "cross-origin-isolation",
     "owners": [ "yhirano" ],
     "expiry_milestone": 83
   },
@@ -590,6 +590,11 @@
     "expiry_milestone": 82
   },
   {
+    "name": "cryptauth-v1-devicesync-deprecate",
+    "owners": [ "khorimoto", "nohle" ],
+    "expiry_milestone": 87
+  },
+  {
     "name": "cryptauth-v2-device-activity-status",
     "owners": [ "khorimoto", "nohle", "themaxli" ],
     "expiry_milestone": 85
@@ -1669,7 +1674,7 @@
   {
     "name": "enable-reader-mode",
     "owners": [ "gilmanmh@google.com" ],
-    "expiry_milestone": 78
+    "expiry_milestone": 82
   },
   {
     "name": "enable-reader-mode-in-cct",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index b36de73..2c8ff0f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -815,9 +815,9 @@
 const char kEnableOutOfBlinkCorsDescription[] =
     "CORS handling logic is moved out of blink.";
 
-const char kCrossOriginEmbedderPolicyName[] = "Cross Origin Embedder Policy";
-const char kCrossOriginEmbedderPolicyDescription[] =
-    "Enable Cross Origin Embedder Policy (https://mikewest.github.io/corpp/).";
+const char kCrossOriginIsolationName[] = "Cross Origin Isolation";
+const char kCrossOriginIsolationDescription[] =
+    "Enable Cross Origin Opener Policy and Cross Origin Embedder Policy.";
 
 const char kDisableKeepaliveFetchName[] = "Disable fetch with keepalive set";
 const char kDisableKeepaliveFetchDescription[] =
@@ -3336,6 +3336,12 @@
 const char kCrostiniWebUIInstallerDescription[] =
     "Enable the new WebUI Crostini Installer.";
 
+const char kCryptAuthV1DeviceSyncDeprecateName[] =
+    "Deprecate CryptAuth v1 DeviceSync";
+const char kCryptAuthV1DeviceSyncDeprecateDescription[] =
+    "Deprecate the CryptAuth v1 DeviceSync protocol. The v2 DeviceSync flag "
+    "should be enabled before this flag is flipped.";
+
 const char kCryptAuthV2DeviceActivityStatusName[] =
     "CryptAuth Device Activity Status";
 const char kCryptAuthV2DeviceActivityStatusDescription[] =
@@ -3343,7 +3349,8 @@
 
 const char kCryptAuthV2DeviceSyncName[] = "CryptAuth v2 DeviceSync";
 const char kCryptAuthV2DeviceSyncDescription[] =
-    "Use the CryptAuth v2 DeviceSync protocol.";
+    "Use the CryptAuth v2 DeviceSync protocol. Note: v1 DeviceSync will "
+    "continue to run until the deprecation flag is flipped.";
 
 const char kCryptAuthV2EnrollmentName[] = "CryptAuth v2 Enrollment";
 const char kCryptAuthV2EnrollmentDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 411e4a1..fd171b9 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -477,8 +477,8 @@
 extern const char kEnableOutOfBlinkCorsName[];
 extern const char kEnableOutOfBlinkCorsDescription[];
 
-extern const char kCrossOriginEmbedderPolicyName[];
-extern const char kCrossOriginEmbedderPolicyDescription[];
+extern const char kCrossOriginIsolationName[];
+extern const char kCrossOriginIsolationDescription[];
 
 extern const char kDisableKeepaliveFetchName[];
 extern const char kDisableKeepaliveFetchDescription[];
@@ -1975,6 +1975,9 @@
 extern const char kCrostiniWebUIInstallerName[];
 extern const char kCrostiniWebUIInstallerDescription[];
 
+extern const char kCryptAuthV1DeviceSyncDeprecateName[];
+extern const char kCryptAuthV1DeviceSyncDeprecateDescription[];
+
 extern const char kCryptAuthV2DeviceActivityStatusName[];
 extern const char kCryptAuthV2DeviceActivityStatusDescription[];
 
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 71d06fc..90a9eb0 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -3315,8 +3315,7 @@
 #define MAYBE_FillWhenFormWithHiddenUsername \
   DISABLED_FillWhenFormWithHiddenUsername
 #else
-#define MAYBE_FillWhenFormWithHiddenUsername \
-  FillWhenFormWithHiddenUsername
+#define MAYBE_FillWhenFormWithHiddenUsername FillWhenFormWithHiddenUsername
 #endif
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
                        MAYBE_FillWhenFormWithHiddenUsername) {
@@ -3788,6 +3787,8 @@
   // Check that the password for origin A was not updated automatically and the
   // update bubble is shown instead.
   WaitForPasswordStore();  // Let the navigation take its effect on storing.
+  ASSERT_THAT(password_store->stored_passwords(),
+              ElementsAre(testing::Key(url_A.GetOrigin())));
   CheckThatCredentialsStored("user", "oldpassword");
   std::unique_ptr<BubbleObserver> prompt_observer(
       new BubbleObserver(WebContents()));
@@ -3799,10 +3800,9 @@
   prompt_observer->AcceptUpdatePrompt(stored_form);
 
   WaitForPasswordStore();
-  // There are two credentials saved with the new password.
+  // The stored credential has been updated with the new password.
   const auto& passwords_map = password_store->stored_passwords();
-  ASSERT_THAT(passwords_map, ElementsAre(testing::Key(url_A.GetOrigin()),
-                                         testing::Key(url_B.GetOrigin())));
+  ASSERT_THAT(passwords_map, ElementsAre(testing::Key(url_A.GetOrigin())));
   for (const auto& credentials : passwords_map) {
     ASSERT_THAT(credentials.second, testing::SizeIs(1));
     EXPECT_EQ(base::ASCIIToUTF16("user"), credentials.second[0].username_value);
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 56079c34..f974c9b 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -69,8 +69,6 @@
 #include "content/public/common/context_menu_params.h"
 #include "content/public/common/mime_handler_view_mode.h"
 #include "content/public/common/url_constants.h"
-#include "content/public/test/accessibility_notification_waiter.h"
-#include "content/public/test/browser_accessibility.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/dump_accessibility_test_helper.h"
 #include "content/public/test/hit_test_region_observer.h"
@@ -83,7 +81,6 @@
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "pdf/pdf_features.h"
 #include "services/network/public/cpp/features.h"
-#include "ui/accessibility/ax_action_data.h"
 #include "ui/accessibility/ax_enum_util.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node.h"
@@ -2518,13 +2515,12 @@
     // Find the embedded PDF and dump the accessibility tree.
     content::FindAccessibilityNodeCriteria find_criteria;
     find_criteria.role = ax::mojom::Role::kEmbeddedObject;
-    content::TestBrowserAccessibility* pdf_root =
+    content::BrowserAccessibility* pdf_root =
         content::FindAccessibilityNode(guest_contents, find_criteria);
     CHECK(pdf_root);
 
     base::string16 actual_contents_utf16;
-    content::TestBrowserAccessibility::FormatAccessibilityTree(
-        formatter.get(), pdf_root, &actual_contents_utf16);
+    formatter->FormatAccessibilityTree(pdf_root, &actual_contents_utf16);
     std::string actual_contents = base::UTF16ToUTF8(actual_contents_utf16);
 
     std::vector<std::string> actual_lines =
@@ -2630,38 +2626,3 @@
 IN_PROC_BROWSER_TEST_P(PDFExtensionAccessibilityTreeDumpTest, TextStyle) {
   RunPDFTest(FILE_PATH_LITERAL("text-style.pdf"));
 }
-
-// This test suite validates the navigation done using the accessibility client.
-using PDFExtensionAccessibilityNavigationTest = PDFExtensionTest;
-
-IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityNavigationTest,
-                       LinkNavigation) {
-  // Enable accessibility and load the test file.
-  content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
-  GURL url(embedded_test_server()->GetURL("/pdf/accessibility/weblinks.pdf"));
-  WebContents* guest_contents = LoadPdfGetGuestContents(url);
-  ASSERT_TRUE(guest_contents);
-  WaitForAccessibilityTreeToContainNodeWithName(guest_contents, "Page 1");
-
-  // Find the specific link node.
-  content::FindAccessibilityNodeCriteria find_criteria;
-  find_criteria.role = ax::mojom::Role::kLink;
-  find_criteria.name = "http://bing.com";
-  content::TestBrowserAccessibility* link_node =
-      content::FindAccessibilityNode(guest_contents, find_criteria);
-  ASSERT_TRUE(link_node);
-
-  // Invoke action on a link and wait for navigation to complete.
-  content::AccessibilityNotificationWaiter event_waiter(
-      GetActiveWebContents(), ui::kAXModeComplete,
-      ax::mojom::Event::kLoadComplete);
-  ui::AXActionData action_data;
-  action_data.action = ax::mojom::Action::kDoDefault;
-  action_data.target_node_id = link_node->GetData().id;
-  link_node->AccessibilityPerformAction(action_data);
-  event_waiter.WaitForNotification();
-
-  // Test that navigation occurred correctly.
-  const GURL& expected_url = GetActiveWebContents()->GetURL();
-  EXPECT_EQ("https://bing.com/", expected_url.spec());
-}
diff --git a/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc b/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc
index f60dc29..49ca7fa 100644
--- a/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc
+++ b/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc
@@ -471,9 +471,13 @@
   }
 
   void VerifyEnrollmentResult() {
-    EXPECT_EQ(is_enrollment_token_valid() ? "fake_device_management_token"
-                                          : std::string(),
-              BrowserDMTokenStorage::Get()->RetrieveDMToken());
+    auto dm_token = BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken();
+    if (is_enrollment_token_valid()) {
+      EXPECT_TRUE(dm_token.is_valid());
+      EXPECT_EQ("fake_device_management_token", dm_token.value());
+    } else {
+      EXPECT_TRUE(dm_token.is_empty());
+    }
 
     // Verify the enrollment result.
     ChromeBrowserCloudManagementEnrollmentResult expected_result;
diff --git a/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc b/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc
index 192ce1d..b989810 100644
--- a/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc
+++ b/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.h"
 
 #include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -163,10 +164,10 @@
 }
 
 void MachineLevelUserCloudPolicyFetcher::TryToFetchPolicy() {
-  std::string dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken();
+  auto dm_token = BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken();
   std::string client_id = BrowserDMTokenStorage::Get()->RetrieveClientId();
-  if (!dm_token.empty() && !client_id.empty())
-    SetupRegistrationAndFetchPolicy(dm_token, client_id);
+  if (dm_token.is_valid() && !client_id.empty())
+    SetupRegistrationAndFetchPolicy(dm_token.value(), client_id);
 }
 
 }  // namespace policy
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index 8e7580b..e6a92498 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -12,7 +12,6 @@
  * Do not remove constants from here. Keys that were used in past versions but are not used anymore
  * cannot be reused. Mark them as @Deprecated.
  *
- * TODO(crbug.com/1022107): Finish moving constants from ChromePreferenceManager.
  * TODO(crbug.com/1013781): Implement key deprecation. For now, just mark them as @Deprecated.
  */
 public final class ChromePreferenceKeys {
@@ -98,5 +97,204 @@
     public static final String CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER =
             "contextual_search_current_week_number";
 
+    /**
+     * Whether the promotion for data reduction has been skipped on first invocation.
+     * Default value is false.
+     */
+    public static final String PROMOS_SKIPPED_ON_FIRST_START = "promos_skipped_on_first_start";
+    public static final String SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION =
+            "signin_promo_last_shown_chrome_version";
+    public static final String SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES =
+            "signin_promo_last_shown_account_names";
+
+    /**
+     * This value was used prior to KitKat to keep existing low-end devices on the normal UI rather
+     * than the simplified UI.
+     *
+     * This value may still exist in shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String ALLOW_LOW_END_DEVICE_UI = "allow_low_end_device_ui";
+
+    @Deprecated
+    private static final String PREF_WEBSITE_SETTINGS_FILTER = "website_settings_filter";
+
+    /**
+     * Whether Chrome is set as the default browser.
+     * Default value is false.
+     */
+    public static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser";
+
+    /**
+     * Deprecated in M70. This value may still exist in the shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String CHROME_MODERN_DESIGN_ENABLED_KEY = "chrome_modern_design_enabled";
+
+    /**
+     * Whether or not the home page button is force enabled.
+     * Default value is false.
+     */
+    @Deprecated
+    private static final String HOME_PAGE_BUTTON_FORCE_ENABLED_KEY =
+            "home_page_button_force_enabled";
+
+    /**
+     * Whether or not the homepage tile will be shown.
+     * Default value is false.
+     */
+    @Deprecated
+    private static final String HOMEPAGE_TILE_ENABLED_KEY = "homepage_tile_enabled";
+
+    /**
+     * Whether or not the new tab page button is enabled.
+     * Default value is false.
+     */
+    @Deprecated
+    private static final String NTP_BUTTON_ENABLED_KEY = "ntp_button_enabled";
+
+    /**
+     * Deprecated in M71. This value may still exist in the shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String NTP_BUTTON_VARIANT_KEY = "ntp_button_variant";
+
+    /**
+     * Deprecated in M77. This value may still exist in shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String TAB_PERSISTENT_STORE_TASK_RUNNER_ENABLED_KEY =
+            "tab_persistent_store_task_runner_enabled";
+
+    /**
+     * Deprecated in M75. This value may still exist in shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String INFLATE_TOOLBAR_ON_BACKGROUND_THREAD_KEY =
+            "inflate_toolbar_on_background_thread";
+
+    /**
+     * The current theme setting in the user settings.
+     * Default value is -1. Use NightModeUtils#getThemeSetting() to retrieve current setting or
+     * default theme.
+     */
+    public static final String UI_THEME_SETTING_KEY = "ui_theme_setting";
+
+    /**
+     * Whether or not darken websites is enabled.
+     * Default value is false.
+     */
+    public static final String DARKEN_WEBSITES_ENABLED_KEY = "darken_websites_enabled";
+
+    /**
+     * Marks that the content suggestions surface has been shown.
+     * Default value is false.
+     */
+    public static final String CONTENT_SUGGESTIONS_SHOWN_KEY = "content_suggestions_shown";
+
+    /**
+     * Whether the user dismissed the personalized sign in promo from the Settings.
+     * Default value is false.
+     */
+    public static final String SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED =
+            "settings_personalized_signin_promo_dismissed";
+    /**
+     * Whether the user dismissed the personalized sign in promo from the new tab page.
+     * Default value is false.
+     */
+    public static final String NTP_SIGNIN_PROMO_DISMISSED =
+            "ntp.personalized_signin_promo_dismissed";
+
+    public static final String NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START =
+            "ntp.signin_promo_suppression_period_start";
+
+    public static final String SUCCESS_UPLOAD_SUFFIX = "_crash_success_upload";
+    public static final String FAILURE_UPLOAD_SUFFIX = "_crash_failure_upload";
+
+    /**
+     * Deprecated in M76. This value may still exist in the shared preferences file. Do not reuse.
+     */
+    @Deprecated
+    private static final String SOLE_INTEGRATION_ENABLED_KEY = "sole_integration_enabled";
+
+    public static final String VERIFIED_DIGITAL_ASSET_LINKS = "verified_digital_asset_links";
+    public static final String TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES =
+            "trusted_web_activity_disclosure_accepted_packages";
+
+    /**
+     * Whether VR assets component should be registered on startup.
+     * Default value is false.
+     */
+    public static final String SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP =
+            "should_register_vr_assets_component_on_startup";
+
+    /*
+     * Whether the simplified tab switcher is enabled when accessibility mode is enabled. Keep in
+     * sync with accessibility_preferences.xml.
+     * Default value is true.
+     */
+    public static final String ACCESSIBILITY_TAB_SWITCHER = "accessibility_tab_switcher";
+
+    /**
+     * When the user is shown a badge that the current Android OS version is unsupported, and they
+     * tap it to display the menu (which has additional information), we store the current version
+     * of Chrome to this preference to ensure we only show the badge once. The value is cleared
+     * if the Chrome version later changes.
+     */
+    public static final String LATEST_UNSUPPORTED_VERSION = "android_os_unsupported_chrome_version";
+
+    /**
+     * Keys for deferred recording of the outcomes of showing the clear data dialog after
+     * Trusted Web Activity client apps are uninstalled or have their data cleared.
+     */
+    public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL =
+            "twa_dialog_number_of_dismissals_on_uninstall";
+    public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA =
+            "twa_dialog_number_of_dismissals_on_clear_data";
+
+    /** Key for deferred recording of WebAPK uninstalls. */
+    @Deprecated
+    private static final String WEBAPK_NUMBER_OF_UNINSTALLS = "webapk_number_of_uninstalls";
+
+    /** Key for deferred recording of list of uninstalled WebAPK packages. */
+    public static final String WEBAPK_UNINSTALLED_PACKAGES = "webapk_uninstalled_packages";
+
+    /**
+     * Key for whether it allows to start in service manager only mode.
+     * Default value is false.
+     */
+    public static final String ALLOW_STARTING_SERVICE_MANAGER_ONLY_KEY =
+            "allow_starting_service_manager_only";
+
+    /**
+     * Deprecated keys for Chrome Home.
+     */
+    @Deprecated
+    private static final String CHROME_HOME_USER_ENABLED_KEY = "chrome_home_user_enabled";
+    @Deprecated
+    private static final String CHROME_HOME_OPT_OUT_SNACKBAR_SHOWN =
+            "chrome_home_opt_out_snackbar_shown";
+    @Deprecated
+    private static final String CHROME_HOME_INFO_PROMO_SHOWN_KEY = "chrome_home_info_promo_shown";
+    @Deprecated
+    private static final String CHROME_HOME_SHARED_PREFERENCES_KEY = "chrome_home_enabled_date";
+
+    /**
+     * Contains a trial group that was used to determine whether the reached code profiler should be
+     * enabled.
+     */
+    public static final String REACHED_CODE_PROFILER_GROUP_KEY = "reached_code_profiler_group";
+
+    /**
+     * Key to cache whether offline indicator v2 (persistent offline indicator) is enabled.
+     */
+    public static final String OFFLINE_INDICATOR_V2_ENABLED_KEY = "offline_indicator_v2_enabled";
+
+    /**
+     * Previously used to migrate {@link PrefServiceBridge} preferences to current version.
+     */
+    @Deprecated
+    private static final String MIGRATION_PREF_KEY = "PrefMigrationVersion";
+
     private ChromePreferenceKeys() {}
 }
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index 2cefced..a842791 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -381,34 +381,27 @@
   ]
 }
 
-# TODO(https://crbug.com/930109): Figure out why this test fails on MAC ASAN.
-if (!is_asan || !is_mac) {
-  js2gtest("resources_unitjs_tests") {
-    test_type = "webui"
-    sources = [
-      "gaia_auth_host/password_change_authenticator_test.unitjs",
-    ]
+js2gtest("resources_unitjs_tests") {
+  test_type = "webui"
+  sources = [
+    "gaia_auth_host/password_change_authenticator_test.unitjs",
+  ]
 
-    # This has to be a gen_include, so it doesn't collide with other js2gtests
-    gen_include_files = [ "//ui/webui/resources/js/cr.js" ]
+  # This has to be a gen_include, so it doesn't collide with other js2gtests
+  gen_include_files = [ "//ui/webui/resources/js/cr.js" ]
 
-    # But these have to be extra_js_files, since it uses a native object
-    # EventTarget, which doesn't work at compile time.
-    extra_js_files = [
-      "//ui/webui/resources/js/cr/event_target.js",
-      "gaia_auth_host/password_change_authenticator.js",
-    ]
-    defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-  }
+  # But these have to be extra_js_files, since it uses a native object
+  # EventTarget, which doesn't work at compile time.
+  extra_js_files = [
+    "//ui/webui/resources/js/cr/event_target.js",
+    "gaia_auth_host/password_change_authenticator.js",
+  ]
+  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+}
 
-  source_set("browser_tests") {
-    testonly = true
-    deps = [
-      ":resources_unitjs_tests",
-    ]
-  }
-} else {
-  source_set("browser_tests") {
-    testonly = true
-  }
+source_set("browser_tests") {
+  testonly = true
+  deps = [
+    ":resources_unitjs_tests",
+  ]
 }
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html
index 1428af5a..62ec58f 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html
@@ -24,6 +24,16 @@
       }
     </style>
     <div class="settings-box first">
+      <div id="featureEnabledLabel" class="start">
+        PLACEHOLDER Enable OS sync
+      </div>
+      <cr-toggle checked="{{osSyncPrefs.featureEnabled}}"
+                 on-change="onFeatureEnabledChanged_"
+                 aria-labelledby="featureEnabledLabel">
+      </cr-toggle>
+    </div>
+    <!-- TODO(jamescook): Hide or disable everything when feature is off. -->
+    <div class="settings-box">
       <div id="syncEverythingCheckboxLabel" class="start">
         $i18n{syncEverythingCheckboxLabel}
       </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js
index 65ecd86..b1fd6e57 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js
@@ -87,6 +87,16 @@
   },
 
   /**
+   * Handler for when the feature enabled checkbox is changed.
+   * @param {!Event} event
+   * @private
+   */
+  onFeatureEnabledChanged_: function(event) {
+    this.set('osSyncPrefs.featureEnabled', !!event.target.checked);
+    this.sendOsSyncDatatypes_();
+  },
+
+  /**
    * Handler for when the sync all data types checkbox is changed.
    * @param {!Event} event
    * @private
@@ -110,14 +120,14 @@
       }
     }
 
-    this.onSingleSyncDataTypeChanged_();
+    this.sendOsSyncDatatypes_();
   },
 
   /**
-   * Handler for when any sync data type checkbox is changed.
+   * Sends the osSyncPrefs dictionary back to the C++ handler.
    * @private
    */
-  onSingleSyncDataTypeChanged_: function() {
+  sendOsSyncDatatypes_: function() {
     assert(this.osSyncPrefs);
     this.browserProxy_.setOsSyncDatatypes(this.osSyncPrefs);
   },
diff --git a/chrome/browser/signin/signin_util_win.cc b/chrome/browser/signin/signin_util_win.cc
index dcf3887a..1e310eb 100644
--- a/chrome/browser/signin/signin_util_win.cc
+++ b/chrome/browser/signin/signin_util_win.cc
@@ -65,7 +65,7 @@
 // Finish the process of import credentials.  This is either called directly
 // from ImportCredentialsFromProvider() if a browser window for the profile is
 // already available or is delayed until a browser can first be opened.
-void FinishImportCredentialsFromProvider(const std::string& account_id,
+void FinishImportCredentialsFromProvider(const CoreAccountId& account_id,
                                          Browser* browser,
                                          Profile* profile,
                                          Profile::CreateStatus status) {
@@ -111,7 +111,7 @@
       AboutSigninInternalsFactory::GetInstance()->GetForProfile(profile);
   signin_internals->OnAuthenticationResultReceived("Credential Provider");
 
-  std::string account_id =
+  CoreAccountId account_id =
       IdentityManagerFactory::GetForProfile(profile)
           ->GetAccountsMutator()
           ->AddOrUpdateAccount(base::UTF16ToUTF8(gaia_id),
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index adbf54e..5376da21 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -77,6 +77,7 @@
 #include "components/sync/engine/passive_model_worker.h"
 #include "components/sync/engine/sequenced_model_worker.h"
 #include "components/sync/engine/ui_model_worker.h"
+#include "components/sync/model/model_type_store.h"
 #include "components/sync/model/model_type_store_service.h"
 #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
 #include "components/sync_bookmarks/bookmark_sync_service.h"
@@ -120,13 +121,16 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/printing/printers_model_type_controller.h"
 #include "chrome/browser/chromeos/printing/printers_sync_bridge.h"
 #include "chrome/browser/chromeos/printing/synced_printers_manager.h"
 #include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h"
+#include "chrome/browser/chromeos/sync/os_preferences_model_type_controller.h"
 #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h"
 #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h"
 #include "chromeos/components/sync_wifi/wifi_configuration_sync_service.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "components/arc/arc_util.h"
 #endif  // defined(OS_CHROMEOS)
 
@@ -301,6 +305,9 @@
   const base::RepeatingClosure dump_stack = base::BindRepeating(
       &syncer::ReportUnrecoverableError, chrome::GetChannel());
 
+  syncer::RepeatingModelTypeStoreFactory model_type_store_factory =
+      GetModelTypeStoreService()->GetStoreFactory();
+
   if (!disabled_types.Has(syncer::SECURITY_EVENTS)) {
     syncer::ModelTypeControllerDelegate* delegate =
         SecurityEventRecorderFactory::GetForProfile(profile_)
@@ -330,7 +337,7 @@
   // disabled.
   if (!disabled_types.Has(syncer::APPS)) {
     controllers.push_back(std::make_unique<ExtensionModelTypeController>(
-        syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(),
+        syncer::APPS, model_type_store_factory,
         GetSyncableServiceForType(syncer::APPS), dump_stack, profile_));
   }
 
@@ -338,7 +345,7 @@
   // disabled.
   if (!disabled_types.Has(syncer::EXTENSIONS)) {
     controllers.push_back(std::make_unique<ExtensionModelTypeController>(
-        syncer::EXTENSIONS, GetModelTypeStoreService()->GetStoreFactory(),
+        syncer::EXTENSIONS, model_type_store_factory,
         GetSyncableServiceForType(syncer::EXTENSIONS), dump_stack, profile_));
   }
 
@@ -346,8 +353,7 @@
   // disabled.
   if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
     controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>(
-        syncer::EXTENSION_SETTINGS,
-        GetModelTypeStoreService()->GetStoreFactory(),
+        syncer::EXTENSION_SETTINGS, model_type_store_factory,
         extensions::settings_sync_util::GetSyncableServiceProvider(
             profile_, syncer::EXTENSION_SETTINGS),
         dump_stack, profile_));
@@ -357,7 +363,7 @@
   // disabled.
   if (!disabled_types.Has(syncer::APP_SETTINGS)) {
     controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>(
-        syncer::APP_SETTINGS, GetModelTypeStoreService()->GetStoreFactory(),
+        syncer::APP_SETTINGS, model_type_store_factory,
         extensions::settings_sync_util::GetSyncableServiceProvider(
             profile_, syncer::APP_SETTINGS),
         dump_stack, profile_));
@@ -380,7 +386,7 @@
   // Theme sync is enabled by default.  Register unless explicitly disabled.
   if (!disabled_types.Has(syncer::THEMES)) {
     controllers.push_back(std::make_unique<ExtensionModelTypeController>(
-        syncer::THEMES, GetModelTypeStoreService()->GetStoreFactory(),
+        syncer::THEMES, model_type_store_factory,
         GetSyncableServiceForType(syncer::THEMES), dump_stack, profile_));
   }
 
@@ -389,8 +395,7 @@
   if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
     controllers.push_back(
         std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
-            syncer::SEARCH_ENGINES,
-            GetModelTypeStoreService()->GetStoreFactory(),
+            syncer::SEARCH_ENGINES, model_type_store_factory,
             GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack));
   }
 #endif  // !defined(OS_ANDROID)
@@ -401,7 +406,7 @@
   if (!chromeos::switches::IsTabletFormFactor()) {
     controllers.push_back(
         std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
-            syncer::APP_LIST, GetModelTypeStoreService()->GetStoreFactory(),
+            syncer::APP_LIST, model_type_store_factory,
             GetSyncableServiceForType(syncer::APP_LIST), dump_stack));
   }
 #endif  // BUILDFLAG(ENABLE_APP_LIST)
@@ -411,7 +416,7 @@
   if (!disabled_types.Has(syncer::DICTIONARY)) {
     controllers.push_back(
         std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
-            syncer::DICTIONARY, GetModelTypeStoreService()->GetStoreFactory(),
+            syncer::DICTIONARY, model_type_store_factory,
             GetSyncableServiceForType(syncer::DICTIONARY), dump_stack));
   }
 #endif  // defined(OS_LINUX) || defined(OS_WIN)
@@ -420,10 +425,30 @@
   if (arc::IsArcAllowedForProfile(profile_) &&
       !arc::IsArcAppSyncFlowDisabled()) {
     controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>(
-        GetModelTypeStoreService()->GetStoreFactory(),
+        model_type_store_factory,
         GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack,
         sync_service, profile_));
   }
+  if (chromeos::features::IsSplitSettingsSyncEnabled()) {
+    if (!disabled_types.Has(syncer::OS_PREFERENCES)) {
+      controllers.push_back(std::make_unique<OsPreferencesModelTypeController>(
+          syncer::OS_PREFERENCES, model_type_store_factory,
+          GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack,
+          profile_->GetPrefs(), sync_service));
+    }
+    if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) {
+      controllers.push_back(std::make_unique<OsPreferencesModelTypeController>(
+          syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory,
+          GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES),
+          dump_stack, profile_->GetPrefs(), sync_service));
+    }
+    if (!disabled_types.Has(syncer::PRINTERS)) {
+      controllers.push_back(std::make_unique<PrintersModelTypeController>(
+          std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
+              GetControllerDelegateForModelType(syncer::PRINTERS).get()),
+          profile_->GetPrefs(), sync_service));
+    }
+  }
 #endif  // defined(OS_CHROMEOS)
 
   return controllers;
diff --git a/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc
index 2f65a51..38727a6a 100644
--- a/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/prefs/pref_service.h"
+#include "components/sync/base/pref_names.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using preferences_helper::ChangeStringPref;
@@ -35,6 +36,15 @@
   // Needed for AwaitQuiescence().
   bool TestUsesSelfNotifications() override { return true; }
 
+  bool SetupClients() override {
+    bool result = SyncTest::SetupClients();
+    for (Profile* profile : GetAllProfiles()) {
+      profile->GetPrefs()->SetBoolean(syncer::prefs::kOsSyncFeatureEnabled,
+                                      true);
+    }
+    return result;
+  }
+
  private:
   // The names |scoped_feature_list_| and |feature_list_| are both used in
   // superclasses.
diff --git a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc
index 80a800e..f4644123 100644
--- a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc
+++ b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc
@@ -122,8 +122,7 @@
   DISALLOW_COPY_AND_ASSIGN(OverviewWindowDragTest);
 };
 
-// Flakily crashes (likely use-after-free). crbug.com/1021936
-IN_PROC_BROWSER_TEST_P(OverviewWindowDragTest, DISABLED_NormalDrag) {
+IN_PROC_BROWSER_TEST_P(OverviewWindowDragTest, NormalDrag) {
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
   aura::Window* browser_window = browser_view->GetWidget()->GetNativeWindow();
   ui_controls::SendKeyPress(browser_window, ui::VKEY_MEDIA_LAUNCH_APP1,
diff --git a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
index 3a0a9c2..e971527 100644
--- a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
+++ b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
@@ -154,8 +154,7 @@
   waiter.Wait();
 }
 
-// Flakily crashes. - crbug.com/1021936
-IN_PROC_BROWSER_TEST_P(ScreenRotationTest, DISABLED_RotateInTabletOverview) {
+IN_PROC_BROWSER_TEST_P(ScreenRotationTest, RotateInTabletOverview) {
   // Browser window is used just to identify display.
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
   gfx::NativeWindow browser_window =
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
index c5712d8..57a8d68 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
@@ -266,7 +266,7 @@
     return;
 
   network_config_requested_ = true;
-  delegate_->OnNetworkConfigRequested(true);
+  delegate_->OnNetworkConfigRequested();
 }
 
 void AppLaunchSplashScreenHandler::HandleContinueAppLaunch() {
@@ -274,7 +274,7 @@
   if (delegate_ && online_state_) {
     network_config_requested_ = false;
     network_config_done_ = true;
-    delegate_->OnNetworkConfigRequested(false);
+    delegate_->OnNetworkConfigFinished();
     Show();
   }
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
index 345b8edf..09690d5 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
@@ -28,7 +28,10 @@
     virtual void OnCancelAppLaunch() {}
 
     // Invoked when the network config shortcut key is pressed.
-    virtual void OnNetworkConfigRequested(bool requested) {}
+    virtual void OnNetworkConfigRequested() {}
+
+    // Invoked when the network config did prepare network and is closed.
+    virtual void OnNetworkConfigFinished() {}
 
     // Invoked when network state is changed. |online| is true if the device
     // is connected to the Internet.
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
index 64b37e2..61589b9 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -78,6 +78,16 @@
   const base::DictionaryValue* result;
   CHECK(args->GetDictionary(0, &result));
 
+  // Start configuring the SyncService using the configuration passed to us from
+  // the JS layer.
+  syncer::SyncService* service = GetSyncService();
+
+  // If the sync engine has shutdown for some reason, just stop.
+  if (!service || !service->IsEngineInitialized()) {
+    sync_blocker_.reset();
+    return;
+  }
+
   bool sync_all_os_types;
   CHECK(result->GetBoolean("syncAllOsTypes", &sync_all_os_types));
 
@@ -91,23 +101,17 @@
       selected_types.Put(type);
   }
 
-  // Start configuring the SyncService using the configuration passed to us from
-  // the JS layer.
-  syncer::SyncService* service = GetSyncService();
-
-  // If the sync engine has shutdown for some reason, just stop.
-  if (!service || !service->IsEngineInitialized()) {
-    sync_blocker_.reset();
-    return;
-  }
-
   // Filter out any non-registered types. The WebUI may echo back values from
   // toggles for in-development features hidden by feature flags.
-  selected_types.RetainAll(
-      service->GetUserSettings()->GetRegisteredSelectableOsTypes());
+  SyncUserSettings* settings = service->GetUserSettings();
+  selected_types.RetainAll(settings->GetRegisteredSelectableOsTypes());
+  settings->SetSelectedOsTypes(sync_all_os_types, selected_types);
 
-  service->GetUserSettings()->SetSelectedOsTypes(sync_all_os_types,
-                                                 selected_types);
+  // Update the enabled state last so that the selected types will be set before
+  // pref observers are notified of the change.
+  bool feature_enabled;
+  CHECK(result->GetBoolean("featureEnabled", &feature_enabled));
+  settings->SetOsSyncFeatureEnabled(feature_enabled);
 
   // TODO(jamescook): Add metrics for selected types.
 }
@@ -124,6 +128,7 @@
 
   base::DictionaryValue args;
   SyncUserSettings* user_settings = service->GetUserSettings();
+  args.SetBoolean("featureEnabled", user_settings->GetOsSyncFeatureEnabled());
   // Tell the UI layer which data types are registered/enabled by the user.
   UserSelectableOsTypeSet registered_types =
       user_settings->GetRegisteredSelectableOsTypes();
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
index a40e79a..223f97a 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
@@ -23,10 +23,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using base::DictionaryValue;
 using syncer::UserSelectableOsType;
 using syncer::UserSelectableOsTypeSet;
 using syncer::UserSelectableTypeSet;
-
 using ::testing::_;
 using ::testing::ByMove;
 using ::testing::Mock;
@@ -38,13 +38,16 @@
 
 namespace {
 
+enum FeatureConfig { FEATURE_ENABLED, FEATURE_DISABLED };
 enum SyncAllConfig { SYNC_ALL_OS_TYPES, CHOOSE_WHAT_TO_SYNC };
 
 // Creates a dictionary with the key/value pairs appropriate for a call to
 // HandleSetOsSyncDatatypes().
-base::DictionaryValue CreateSyncPrefs(SyncAllConfig sync_all,
-                                      UserSelectableOsTypeSet types) {
-  base::DictionaryValue result;
+DictionaryValue CreateOsSyncPrefs(FeatureConfig feature,
+                                  SyncAllConfig sync_all,
+                                  UserSelectableOsTypeSet types) {
+  DictionaryValue result;
+  result.SetBoolean("featureEnabled", feature == FEATURE_ENABLED);
   result.SetBoolean("syncAllOsTypes", sync_all == SYNC_ALL_OS_TYPES);
   // Add all of our data types.
   result.SetBoolean("osPreferencesSynced",
@@ -56,7 +59,7 @@
 
 // Checks whether the passed |dictionary| contains a |key| with the given
 // |expected_value|.
-void CheckBool(const base::DictionaryValue* dictionary,
+void CheckBool(const DictionaryValue* dictionary,
                const std::string& key,
                bool expected_value) {
   bool actual_value;
@@ -67,7 +70,7 @@
 
 // Checks to make sure that the values stored in |dictionary| match the values
 // expected by the JS layer.
-void CheckConfigDataTypeArguments(const base::DictionaryValue* dictionary,
+void CheckConfigDataTypeArguments(const DictionaryValue* dictionary,
                                   SyncAllConfig config,
                                   UserSelectableOsTypeSet types) {
   CheckBool(dictionary, "syncAllOsTypes", config == SYNC_ALL_OS_TYPES);
@@ -123,9 +126,10 @@
                     &OsSyncHandlerTest::OnSetupInProgressHandleDestroyed,
                     base::Unretained(this))))));
 
-    // Configure user settings with all types enabled.
+    // Configure user settings with the sync feature on and all types enabled.
     user_settings_ = mock_sync_service_->GetMockUserSettings();
-    ON_CALL(*user_settings_, IsSyncRequested()).WillByDefault(Return(true));
+    ON_CALL(*user_settings_, GetOsSyncFeatureEnabled())
+        .WillByDefault(Return(true));
     ON_CALL(*user_settings_, IsSyncAllOsTypesEnabled())
         .WillByDefault(Return(true));
     ON_CALL(*user_settings_, GetSelectedOsTypes())
@@ -153,9 +157,9 @@
     in_progress_handle_destroyed_count_++;
   }
 
-  // Expects that the WebUI received an "os-sync-prefs-changed" event and
+  // Expects that an "os-sync-prefs-changed" event was sent to the WebUI and
   // returns the data passed to that event.
-  const base::DictionaryValue* ExpectSyncPrefsChanged() {
+  const DictionaryValue* ExpectOsSyncPrefsSent() {
     const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
     EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
 
@@ -163,7 +167,7 @@
     EXPECT_TRUE(call_data.arg1()->GetAsString(&event));
     EXPECT_EQ(event, "os-sync-prefs-changed");
 
-    const base::DictionaryValue* dictionary = nullptr;
+    const DictionaryValue* dictionary = nullptr;
     EXPECT_TRUE(call_data.arg2()->GetAsDictionary(&dictionary));
     return dictionary;
   }
@@ -184,12 +188,18 @@
   int in_progress_handle_destroyed_count_ = 0;
 };
 
-TEST_F(OsSyncHandlerTest, SyncPrefsSentOnNavigateToPage) {
+TEST_F(OsSyncHandlerTest, OsSyncPrefsSentOnNavigateToPage) {
   handler_->HandleDidNavigateToOsSyncPage(nullptr);
+  ASSERT_EQ(1U, web_ui_.call_data().size());
+  ExpectOsSyncPrefsSent();
+}
 
-  EXPECT_EQ(1U, web_ui_.call_data().size());
-  const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged();
-  CheckBool(dictionary, "syncAllOsTypes", true);
+TEST_F(OsSyncHandlerTest, OsSyncPrefsWhenFeatureIsDisabled) {
+  ON_CALL(*user_settings_, GetOsSyncFeatureEnabled())
+      .WillByDefault(Return(false));
+  handler_->HandleDidNavigateToOsSyncPage(nullptr);
+  const DictionaryValue* os_sync_prefs = ExpectOsSyncPrefsSent();
+  CheckBool(os_sync_prefs, "featureEnabled", false);
 }
 
 TEST_F(OsSyncHandlerTest, OpenConfigPageBeforeSyncEngineInitialized) {
@@ -211,8 +221,7 @@
 
   // Update for sync prefs is sent.
   EXPECT_EQ(1U, web_ui_.call_data().size());
-  const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged();
-  CheckBool(dictionary, "syncAllOsTypes", true);
+  ExpectOsSyncPrefsSent();
 }
 
 TEST_F(OsSyncHandlerTest, NavigateAwayDestroysInProgressHandle) {
@@ -230,10 +239,18 @@
   NotifySyncStateChanged();
 }
 
+TEST_F(OsSyncHandlerTest, UserDisablesFeature) {
+  base::ListValue list_args;
+  list_args.Append(CreateOsSyncPrefs(FEATURE_DISABLED, SYNC_ALL_OS_TYPES,
+                                     UserSelectableOsTypeSet::All()));
+  EXPECT_CALL(*user_settings_, SetOsSyncFeatureEnabled(false));
+  handler_->HandleSetOsSyncDatatypes(&list_args);
+}
+
 TEST_F(OsSyncHandlerTest, TestSyncEverything) {
   base::ListValue list_args;
-  list_args.Append(
-      CreateSyncPrefs(SYNC_ALL_OS_TYPES, UserSelectableOsTypeSet::All()));
+  list_args.Append(CreateOsSyncPrefs(FEATURE_ENABLED, SYNC_ALL_OS_TYPES,
+                                     UserSelectableOsTypeSet::All()));
   EXPECT_CALL(*user_settings_,
               SetSelectedOsTypes(/*sync_all_os_types=*/true, _));
   handler_->HandleSetOsSyncDatatypes(&list_args);
@@ -245,7 +262,8 @@
   for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) {
     UserSelectableOsTypeSet types = {type};
     base::ListValue list_args;
-    list_args.Append(CreateSyncPrefs(CHOOSE_WHAT_TO_SYNC, types));
+    list_args.Append(
+        CreateOsSyncPrefs(FEATURE_ENABLED, CHOOSE_WHAT_TO_SYNC, types));
     EXPECT_CALL(*user_settings_, SetSelectedOsTypes(false, types));
 
     handler_->HandleSetOsSyncDatatypes(&list_args);
@@ -255,8 +273,8 @@
 
 TEST_F(OsSyncHandlerTest, TestSyncAllManually) {
   base::ListValue list_args;
-  list_args.Append(
-      CreateSyncPrefs(CHOOSE_WHAT_TO_SYNC, UserSelectableOsTypeSet::All()));
+  list_args.Append(CreateOsSyncPrefs(FEATURE_ENABLED, CHOOSE_WHAT_TO_SYNC,
+                                     UserSelectableOsTypeSet::All()));
   EXPECT_CALL(*user_settings_,
               SetSelectedOsTypes(false, UserSelectableOsTypeSet::All()));
   handler_->HandleSetOsSyncDatatypes(&list_args);
@@ -265,7 +283,7 @@
 TEST_F(OsSyncHandlerTest, ShowSetupSyncEverything) {
   handler_->HandleDidNavigateToOsSyncPage(nullptr);
 
-  const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged();
+  const DictionaryValue* dictionary = ExpectOsSyncPrefsSent();
   CheckBool(dictionary, "syncAllOsTypes", true);
   CheckBool(dictionary, "osPreferencesRegistered", true);
   CheckBool(dictionary, "printersRegistered", true);
@@ -278,7 +296,7 @@
       .WillByDefault(Return(false));
   handler_->HandleDidNavigateToOsSyncPage(nullptr);
 
-  const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged();
+  const DictionaryValue* dictionary = ExpectOsSyncPrefsSent();
   CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC,
                                UserSelectableOsTypeSet::All());
 }
@@ -292,7 +310,7 @@
 
     handler_->HandleDidNavigateToOsSyncPage(nullptr);
 
-    const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged();
+    const DictionaryValue* dictionary = ExpectOsSyncPrefsSent();
     CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, types);
     Mock::VerifyAndClearExpectations(mock_sync_service_);
   }
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc
index 59e85489..b183685 100644
--- a/chrome/browser/web_applications/web_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -1287,7 +1287,7 @@
 
     std::unique_ptr<WebApplicationInfo> result =
         LoadAndRetrieveWebApplicationInfoWithIcons(url);
-    EXPECT_TRUE(!result);
+    EXPECT_FALSE(result);
   }
   {
     CreateDefaultDataToRetrieve(url);
@@ -1296,7 +1296,7 @@
 
     std::unique_ptr<WebApplicationInfo> result =
         LoadAndRetrieveWebApplicationInfoWithIcons(url);
-    EXPECT_TRUE(!result);
+    EXPECT_FALSE(result);
   }
   {
     CreateDefaultDataToRetrieve(start_url);
diff --git a/chrome/chrome_cleaner/engines/controllers/BUILD.gn b/chrome/chrome_cleaner/engines/controllers/BUILD.gn
index 19ac2e1..d2052d0a 100644
--- a/chrome/chrome_cleaner/engines/controllers/BUILD.gn
+++ b/chrome/chrome_cleaner/engines/controllers/BUILD.gn
@@ -208,7 +208,6 @@
     "//chrome/chrome_cleaner/test:test_uws_catalog",
     "//chrome/chrome_cleaner/ui:cleaner_ui",
     "//chrome/chrome_cleaner/zip_archiver:common",
-    "//components/chrome_cleaner/public/interfaces",
     "//components/chrome_cleaner/test:test_name_helper",
     "//sandbox/win:sandbox",
     "//testing/gmock",
diff --git a/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc b/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc
index 0ea9cc1..1cdce75 100644
--- a/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc
+++ b/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc
@@ -50,7 +50,6 @@
 #include "chrome/chrome_cleaner/test/test_settings_util.h"
 #include "chrome/chrome_cleaner/ui/silent_main_dialog.h"
 #include "chrome/chrome_cleaner/zip_archiver/zip_archiver.h"
-#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom-test-utils.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "sandbox/win/src/sandbox_factory.h"
@@ -137,15 +136,12 @@
   ExtensionCleanupTest() : mojo_task_runner_(MojoTaskRunner::Create()) {}
   void SetUp() override {
     EXPECT_CALL(mock_chrome_prompt_ipc_, MockPostPromptUserTask(_, _, _, _))
-        .WillRepeatedly(
-            [](const std::vector<base::FilePath>& files_to_delete,
-               const std::vector<base::string16>& registry_keys,
-               const std::vector<base::string16>& extension_ids,
-               mojom::ChromePromptInterceptorForTesting::PromptUserCallback*
-                   callback) {
-              std::move(*callback).Run(
-                  mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS);
-            });
+        .WillRepeatedly([](const std::vector<base::FilePath>& files_to_delete,
+                           const std::vector<base::string16>& registry_keys,
+                           const std::vector<base::string16>& extension_ids,
+                           ChromePromptIPC::PromptUserCallback* callback) {
+          std::move(*callback).Run(PromptUserResponse::ACCEPTED_WITHOUT_LOGS);
+        });
     EXPECT_CALL(mock_chrome_prompt_ipc_, Initialize(_));
     EXPECT_CALL(mock_chrome_prompt_ipc_, TryDeleteExtensions(_, _))
         .WillRepeatedly([](base::OnceClosure delete_allowed_callback,
diff --git a/chrome/chrome_cleaner/ipc/BUILD.gn b/chrome/chrome_cleaner/ipc/BUILD.gn
index 03fddfd..83c6e79 100644
--- a/chrome/chrome_cleaner/ipc/BUILD.gn
+++ b/chrome/chrome_cleaner/ipc/BUILD.gn
@@ -32,9 +32,12 @@
     ":mojo_task_runner",
     "//base",
     "//components/chrome_cleaner/public/interfaces",
-    "//components/chrome_cleaner/public/proto",
     "//mojo/public/cpp/platform",
     "//mojo/public/cpp/system",
+  ]
+
+  public_deps = [
+    "//components/chrome_cleaner/public/proto",
     "//third_party/protobuf:protobuf_lite",
   ]
 }
@@ -128,7 +131,6 @@
 
   deps = [
     ":chrome_prompt_ipc",
-    "//components/chrome_cleaner/public/interfaces",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h
index 841c1b7..cbc8b7e 100644
--- a/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h
+++ b/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h
@@ -8,13 +8,11 @@
 #include <string>
 #include <vector>
 
-#include "base/callback_forward.h"
+#include "base/callback.h"
+#include "base/files/file_path.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string16.h"
-
-// This is kept in the base class for now to provide access to mojom enums which
-// will be used in all classes.
-#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
+#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h"
 
 namespace chrome_cleaner {
 
@@ -42,6 +40,17 @@
     virtual void OnConnectionClosedAfterDone() = 0;
   };
 
+  // If legacy Mojo IPC is in use this callback will be invoked by
+  // mojom::ChromePrompt::PromptUserCallback. Otherwise it will be invoked when
+  // a PromptUserResponse proto is received.
+  using PromptUserCallback =
+      base::OnceCallback<void(PromptUserResponse::PromptAcceptance)>;
+
+  // If legacy Mojo IPC is in use this callback will be invoked by
+  // mojom::ChromePrompt::PromptUserCallback. Otherwise it is unused since
+  // DisableExtensions is unimplemented.
+  using DisableExtensionsCallback = base::OnceCallback<void(bool)>;
+
   // Sets |error_handler| as the connection error handler and completes whatever
   // initialization that needs to be done separately from construction. This
   // object doesn't own the error handler pointer.
@@ -56,13 +65,13 @@
       const std::vector<base::FilePath>& files_to_delete,
       const std::vector<base::string16>& registry_keys,
       const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::PromptUserCallback callback) = 0;
+      PromptUserCallback callback) = 0;
 
   // Posts a PromptDisableExtensions() task to the IPC controller's thread.
   // Internal state must be State::kDoneInteraction when the posted task runs.
   virtual void PostDisableExtensionsTask(
       const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::DisableExtensionsCallback callback) = 0;
+      DisableExtensionsCallback callback) = 0;
 
   // Calls |delete_allowed_callback| if the IPC version supports deleting
   // extensions, |delete_not_allowed_callback| otherwise.
diff --git a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc
index cd77fa1..6f74874 100644
--- a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc
+++ b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc
@@ -16,14 +16,14 @@
     const std::vector<base::FilePath>& files_to_delete,
     const std::vector<base::string16>& registry_keys,
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::PromptUserCallback callback) {
+    PromptUserCallback callback) {
   MockPostPromptUserTask(files_to_delete, registry_keys, extension_ids,
                          &callback);
 }
 
 void MockChromePromptIPC::PostDisableExtensionsTask(
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::DisableExtensionsCallback callback) {
+    DisableExtensionsCallback callback) {
   MockPostDisableExtensionsTask(extension_ids, &callback);
 }
 
diff --git a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h
index 495e93b7..06a78f3 100644
--- a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h
+++ b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h"
-#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace chrome_cleaner {
@@ -28,23 +27,22 @@
   // Workaround for GMock's limitation, in which MOCK_METHOD* doesn't
   // accept base::OnceCallback parameters. Will forward any calls to
   // MockPost*() and pass along a raw pointer for |callback|.
-  void PostPromptUserTask(
-      const std::vector<base::FilePath>& files_to_delete,
-      const std::vector<base::string16>& registry_keys,
-      const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::PromptUserCallback callback) override;
+  void PostPromptUserTask(const std::vector<base::FilePath>& files_to_delete,
+                          const std::vector<base::string16>& registry_keys,
+                          const std::vector<base::string16>& extension_ids,
+                          PromptUserCallback callback) override;
   void PostDisableExtensionsTask(
       const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::DisableExtensionsCallback callback) override;
+      DisableExtensionsCallback callback) override;
 
   MOCK_METHOD4(MockPostPromptUserTask,
                void(const std::vector<base::FilePath>& files_to_delete,
                     const std::vector<base::string16>& registry_keys,
                     const std::vector<base::string16>& extension_ids,
-                    mojom::ChromePrompt::PromptUserCallback* callback));
+                    PromptUserCallback* callback));
   MOCK_METHOD2(MockPostDisableExtensionsTask,
                void(const std::vector<base::string16>& extension_ids,
-                    mojom::ChromePrompt::DisableExtensionsCallback* callback));
+                    DisableExtensionsCallback* callback));
 };
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc
index c5bd0422..f0eec1b7 100644
--- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc
+++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc
@@ -69,29 +69,23 @@
     const std::vector<base::FilePath>& files_to_delete,
     const std::vector<base::string16>& registry_keys,
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::PromptUserCallback callback) {
+    PromptUserCallback callback) {
   DCHECK(task_runner_);
   task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(
-          &MojoChromePromptIPC::RunPromptUserTask, base::Unretained(this),
-          files_to_delete, registry_keys, extension_ids,
-          base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceived,
-                         base::Unretained(this), std::move(callback))));
+      base::BindOnce(&MojoChromePromptIPC::RunPromptUserTask,
+                     base::Unretained(this), files_to_delete, registry_keys,
+                     extension_ids, std::move(callback)));
 }
 
 void MojoChromePromptIPC::PostDisableExtensionsTask(
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::DisableExtensionsCallback callback) {
+    DisableExtensionsCallback callback) {
   DCHECK(task_runner_);
   task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &MojoChromePromptIPC::RunDisableExtensionsTask,
-          base::Unretained(this), extension_ids,
-          base::BindOnce(
-              &MojoChromePromptIPC::OnChromeResponseReceivedExtensions,
-              base::Unretained(this), std::move(callback))));
+      FROM_HERE, base::BindOnce(&MojoChromePromptIPC::RunDisableExtensionsTask,
+                                base::Unretained(this), extension_ids,
+                                std::move(callback)));
 }
 
 void MojoChromePromptIPC::TryDeleteExtensions(
@@ -106,22 +100,23 @@
 }
 
 void MojoChromePromptIPC::OnChromeResponseReceived(
-    mojom::ChromePrompt::PromptUserCallback callback,
+    PromptUserCallback callback,
     mojom::PromptAcceptance prompt_acceptance) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(State::kWaitingForResponseFromChrome, state_);
 
   state_ = State::kDoneInteraction;
-  std::move(callback).Run(prompt_acceptance);
+  std::move(callback).Run(
+      static_cast<PromptUserResponse::PromptAcceptance>(prompt_acceptance));
 }
 
 void MojoChromePromptIPC::OnChromeResponseReceivedExtensions(
-    mojom::ChromePrompt::DisableExtensionsCallback callback,
-    bool extensions_disabled_callback) {
+    DisableExtensionsCallback callback,
+    bool extensions_disabled) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(State::kDoneInteraction, state_);
 
-  std::move(callback).Run(extensions_disabled_callback);
+  std::move(callback).Run(extensions_disabled);
 }
 
 void MojoChromePromptIPC::OnConnectionError() {
@@ -186,7 +181,7 @@
     const std::vector<base::FilePath>& files_to_delete,
     const std::vector<base::string16>& registry_keys,
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::PromptUserCallback callback) {
+    PromptUserCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(chrome_prompt_service_);
   DCHECK(state_ != State::kUninitialized);
@@ -200,24 +195,38 @@
 
   state_ = State::kWaitingForResponseFromChrome;
 
+  // Mojo will invoke this callback when a response is received. The
+  // |prompt_acceptance| parameter is unbound and will be filled in by Mojo.
+  mojom::ChromePrompt::PromptUserCallback response_callback =
+      base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceived,
+                     base::Unretained(this), std::move(callback));
+
   const auto& version_callback = base::BindRepeating(
       &MojoChromePromptIPC::PromptUserCheckVersion, base::Unretained(this),
       std::move(files_to_delete), std::move(registry_keys),
       // Uses the AdaptCallbackForRepeating because we are bound by the mojo API
       // to use a RepeatingCallback even though this only should be called once.
-      std::move(extension_ids), AdaptCallbackForRepeating(std::move(callback)));
+      std::move(extension_ids),
+      AdaptCallbackForRepeating(std::move(response_callback)));
   (*chrome_prompt_service_).QueryVersion(version_callback);
 }
 
 void MojoChromePromptIPC::RunDisableExtensionsTask(
     const std::vector<base::string16>& extension_ids,
-    mojom::ChromePrompt::DisableExtensionsCallback callback) {
+    DisableExtensionsCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(chrome_prompt_service_);
   DCHECK(state_ == State::kDoneInteraction);
 
+  // Mojo will invoke this callback when a response is received. The
+  // |extensions_disabled| parameter is unbound and will be filled in by Mojo.
+  mojom::ChromePrompt::DisableExtensionsCallback response_callback =
+      base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceivedExtensions,
+                     base::Unretained(this), std::move(callback));
+
   (*chrome_prompt_service_)
-      ->DisableExtensions(std::move(extension_ids), std::move(callback));
+      ->DisableExtensions(std::move(extension_ids),
+                          std::move(response_callback));
 }
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h
index 46ce19af..36d7e90 100644
--- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h
+++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h
@@ -37,7 +37,7 @@
 //       files_to_delete, registry_keys,
 //       base::BindOnce(&ReceivePromptResult));
 //
-//   void ReceivePromptResult(mojom::PromptAcceptance prompt_acceptance) {
+//   void ReceivePromptResult(PromptAcceptance prompt_acceptance) {
 //     ...
 //   }
 class MojoChromePromptIPC : public ChromePromptIPC {
@@ -55,17 +55,16 @@
   // response from Chrome is received, |callback| will run on the IPC
   // controller's thread; clients of this class are responsible for posting
   // response on the right thread.
-  void PostPromptUserTask(
-      const std::vector<base::FilePath>& files_to_delete,
-      const std::vector<base::string16>& registry_keys,
-      const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::PromptUserCallback callback) override;
+  void PostPromptUserTask(const std::vector<base::FilePath>& files_to_delete,
+                          const std::vector<base::string16>& registry_keys,
+                          const std::vector<base::string16>& extension_ids,
+                          PromptUserCallback callback) override;
 
   // Posts a PromptDisableExtensions() task to the IPC controller's thread.
   // Internal state must be State::kDoneInteraction when the posted task runs.
   void PostDisableExtensionsTask(
       const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::DisableExtensionsCallback callback) override;
+      DisableExtensionsCallback callback) override;
 
   // Queries Chrome for its version of the ChromePrompt interface. If version
   // >= 3 calls |delete_allowed_callback|. Calls |delete_not_allowed_callback|
@@ -89,24 +88,22 @@
   void RunPromptUserTask(const std::vector<base::FilePath>& files_to_delete,
                          const std::vector<base::string16>& registry_keys,
                          const std::vector<base::string16>& extension_ids,
-                         mojom::ChromePrompt::PromptUserCallback callback);
+                         PromptUserCallback callback);
 
   void RunDisableExtensionsTask(
       const std::vector<base::string16>& extension_ids,
-      mojom::ChromePrompt::DisableExtensionsCallback callback);
+      DisableExtensionsCallback callback);
 
-  // Callback for ChromePrompt::PromptUser, internal state must be
+  // Callback for mojom::ChromePrompt::PromptUser, internal state must be
   // State::kWaitingForResponseFromChrome. Invokes callback(prompt_acceptance)
   // and transitions to state State::kDoneInteraction.
-  void OnChromeResponseReceived(
-      mojom::ChromePrompt::PromptUserCallback callback,
-      mojom::PromptAcceptance prompt_acceptance);
+  void OnChromeResponseReceived(PromptUserCallback callback,
+                                mojom::PromptAcceptance prompt_acceptance);
 
-  // Callback for ChromePrompt::DisableExtensions, internal state must be
-  // State::kDoneInteraction. Invokes callback(extensions_deleted_callback).
-  void OnChromeResponseReceivedExtensions(
-      mojom::ChromePrompt::DisableExtensionsCallback callback,
-      bool extensions_deleted_callback);
+  // Callback for mojom::ChromePrompt::DisableExtensions, internal state must
+  // be State::kDoneInteraction. Invokes callback(extensions_deleted).
+  void OnChromeResponseReceivedExtensions(DisableExtensionsCallback callback,
+                                          bool extensions_deleted);
 
   // Connection error handler. Invokes either
   // error_handler_->OnConnectionClosed() or
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc
index d6df9ac..0d503b45 100644
--- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc
+++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc
@@ -20,6 +20,7 @@
 #include "chrome/chrome_cleaner/logging/scoped_logging.h"
 #include "chrome/chrome_cleaner/test/test_util.h"
 #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
+#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h"
 #include "components/chrome_cleaner/test/test_name_helper.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/message_pipe.h"
@@ -83,7 +84,7 @@
   bool uws_expected;
   bool uwe_expected;
   bool with_registry_keys;
-  mojom::PromptAcceptance expected_prompt_acceptance;
+  PromptUserResponse::PromptAcceptance expected_prompt_acceptance;
   ParentDisconnected expected_parent_disconnected;
 };
 
@@ -110,7 +111,8 @@
       EXPECT_EQ(kBadRegistryKey, registry_keys->front());
     }
     CloseConnectionIf(ParentDisconnected::kWhileProcessingChildRequest);
-    std::move(callback).Run(test_config_.expected_prompt_acceptance);
+    std::move(callback).Run(static_cast<mojom::PromptAcceptance>(
+        test_config_.expected_prompt_acceptance));
     if (!test_config_.uwe_expected) {
       CloseConnectionIf(ParentDisconnected::kOnDone);
     }
@@ -162,8 +164,7 @@
 
  protected:
   void CreateImpl(mojo::ScopedMessagePipeHandle mojo_pipe) override {
-    chrome_cleaner::mojom::ChromePromptRequest chrome_prompt_request(
-        std::move(mojo_pipe));
+    mojom::ChromePromptRequest chrome_prompt_request(std::move(mojo_pipe));
     mock_chrome_prompt_ = std::make_unique<MockChromePrompt>(
         test_config_, std::move(chrome_prompt_request));
     // At this point, the child process should be connected.
@@ -234,8 +235,9 @@
  private:
   ~ChromePromptIPCChildProcess() override = default;
 
-  void ReceivePromptResult(base::OnceClosure done,
-                           mojom::PromptAcceptance prompt_acceptance) {
+  void ReceivePromptResult(
+      base::OnceClosure done,
+      PromptUserResponse::PromptAcceptance prompt_acceptance) {
     CHECK_EQ(expected_prompt_acceptance(), prompt_acceptance);
     // Unblocks the main thread.
     std::move(done).Run();
@@ -259,11 +261,11 @@
            command_line().HasSwitch(kIncludeRegistryKeysSwitch);
   }
 
-  mojom::PromptAcceptance expected_prompt_acceptance() const {
+  PromptUserResponse::PromptAcceptance expected_prompt_acceptance() const {
     int val = -1;
     CHECK(base::StringToInt(
         command_line().GetSwitchValueASCII(kExpectedPromptResultSwitch), &val));
-    return static_cast<mojom::PromptAcceptance>(val);
+    return static_cast<PromptUserResponse::PromptAcceptance>(val);
   }
 };
 
@@ -326,12 +328,12 @@
                                        : kSuccessExitCode;
 }
 
-class ChromePromptIPCTest
-    : public ::testing::TestWithParam<std::tuple<bool,
-                                                 bool,
-                                                 bool,
-                                                 mojom::PromptAcceptance,
-                                                 ParentDisconnected>> {
+class ChromePromptIPCTest : public ::testing::TestWithParam<
+                                std::tuple<bool,
+                                           bool,
+                                           bool,
+                                           PromptUserResponse::PromptAcceptance,
+                                           ParentDisconnected>> {
  public:
   void SetUp() override { mojo_task_runner_ = MojoTaskRunner::Create(); }
 
@@ -370,7 +372,7 @@
                              /*uws_expected=*/Values(false),
                              /*uwe_expected=*/Values(false),
                              /*with_registry_keys=*/Values(false),
-                             Values(mojom::PromptAcceptance::DENIED),
+                             Values(PromptUserResponse::DENIED),
                              Values(ParentDisconnected::kNone,
                                     ParentDisconnected::kOnStartup)),
                          GetParamNameForTest());
@@ -382,9 +384,9 @@
         /*uws_expected=*/Values(true),
         /*uwe_expected=*/Bool(),
         /*with_registry_keys=*/Bool(),
-        Values(mojom::PromptAcceptance::ACCEPTED_WITH_LOGS,
-               mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS,
-               mojom::PromptAcceptance::DENIED),
+        Values(PromptUserResponse::ACCEPTED_WITH_LOGS,
+               PromptUserResponse::ACCEPTED_WITHOUT_LOGS,
+               PromptUserResponse::DENIED),
         Values(ParentDisconnected::kNone,
                ParentDisconnected::kOnStartup,
                ParentDisconnected::kWhileProcessingChildRequest,
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc
index b885af6..2fd6e79 100644
--- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc
+++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc
@@ -6,6 +6,7 @@
 
 #include <windows.h>
 
+#include "base/bind_helpers.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/win_util.h"
@@ -105,7 +106,7 @@
     std::string file_path_utf8;
     if (!base::UTF16ToUTF8(file_to_delete.value().c_str(),
                            file_to_delete.value().size(), &file_path_utf8)) {
-      std::move(callback).Run(PromptAcceptance::DENIED);
+      std::move(callback).Run(PromptUserResponse::DENIED);
       return;
     } else {
       prompt_user_message.add_files_to_delete(file_path_utf8);
@@ -116,7 +117,7 @@
     std::string registry_key_utf8;
     if (!base::UTF16ToUTF8(registry_key.c_str(), registry_key.size(),
                            &registry_key_utf8)) {
-      std::move(callback).Run(PromptAcceptance::DENIED);
+      std::move(callback).Run(PromptUserResponse::DENIED);
       return;
     } else {
       prompt_user_message.add_registry_keys(registry_key_utf8);
@@ -127,7 +128,7 @@
     std::string extension_id_utf8;
     if (!base::UTF16ToUTF8(extension_id.c_str(), extension_id.size(),
                            &extension_id_utf8)) {
-      std::move(callback).Run(PromptAcceptance::DENIED);
+      std::move(callback).Run(PromptUserResponse::DENIED);
       return;
     } else {
       prompt_user_message.add_extension_ids(extension_id_utf8);
@@ -152,7 +153,8 @@
   }
 
   // Receive the response from Chrome.
-  PromptAcceptance prompt_acceptance = WaitForPromptAcceptance();
+  PromptUserResponse::PromptAcceptance prompt_acceptance =
+      WaitForPromptAcceptance();
 
   if (state_ == State::kDoneInteraction) {
     return;
@@ -208,7 +210,7 @@
   WriteByPointer(request_content.data(), kMessageLength);
 }
 
-ProtoChromePromptIPC::PromptAcceptance
+PromptUserResponse::PromptAcceptance
 ProtoChromePromptIPC::WaitForPromptAcceptance() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(State::kWaitingForResponseFromChrome, state_);
@@ -223,16 +225,16 @@
   if (!::ReadFile(response_read_handle_.Get(), &response_length,
                   sizeof(response_length), &bytes_read, nullptr)) {
     PLOG(ERROR) << "Reading the prompt acceptance message length failed.";
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
   if (bytes_read != sizeof(response_length)) {
     PLOG(ERROR) << "Short read on the prompt acceptance message length.";
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
 
   if (response_length == 0 || response_length > kMaxMessageLength) {
     PLOG(ERROR) << "Invalid message length received: " << response_length;
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
 
   // Read the response.
@@ -241,23 +243,23 @@
                   base::WriteInto(&response_content, response_length + 1),
                   response_length, &bytes_read, nullptr)) {
     PLOG(ERROR) << "Reading the prompt acceptance message failed";
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
   if (bytes_read != response_length) {
     PLOG(ERROR) << "Short read on the prompt acceptance message.";
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
 
   chrome_cleaner::PromptUserResponse response;
   if (!response.ParseFromString(response_content)) {
     LOG(ERROR) << "Parsing of prompt acceptance failed.";
-    return PromptAcceptance::DENIED;
+    return PromptUserResponse::DENIED;
   }
 
   // Successful execution.
   call_connection_closed.ReplaceClosure(base::DoNothing());
 
-  return static_cast<PromptAcceptance>(response.prompt_acceptance());
+  return response.prompt_acceptance();
 }
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h
index 7bab58d..c2a7afd 100644
--- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h
+++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h
@@ -19,14 +19,6 @@
  public:
   static constexpr uint32_t kMaxMessageLength = 1 * 1024 * 1024;  // 1M bytes
 
-  // Currently some mojom types are used to provide as drop-in replacement
-  // for the existing mojo based implementation. Since they are very simple
-  // they will stay essentially identical once the PromptAcceptance enum is
-  // replaced with a hand rolled one.
-  using PromptAcceptance = mojom::PromptAcceptance;
-  using PromptUserCallback = base::OnceCallback<void(PromptAcceptance)>;
-  using DisableExtensionsCallback = base::OnceCallback<void(bool)>;
-
   ProtoChromePromptIPC(base::win::ScopedHandle response_read_handle,
                        base::win::ScopedHandle request_write_handle);
   ~ProtoChromePromptIPC() override;
@@ -62,7 +54,7 @@
 
   void SendBuffer(const std::string& request_content);
 
-  PromptAcceptance WaitForPromptAcceptance();
+  PromptUserResponse::PromptAcceptance WaitForPromptAcceptance();
 
   template <typename T>
   void WriteByValue(T value) {
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
index bc7a361..8bc29ed 100644
--- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
+++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
@@ -33,7 +33,6 @@
 using base::win::ScopedHandle;
 using testing::Bool;
 using testing::Values;
-using PromptAcceptance = ProtoChromePromptIPC::PromptAcceptance;
 
 constexpr char kIncludeUwSSwitch[] = "include-uws";
 constexpr char kIncludeRegistryKeysSwitch[] = "include-registry-keys";
@@ -128,7 +127,8 @@
 
   bool uws_expected = false;
   bool with_registry_keys = false;
-  PromptAcceptance expected_prompt_acceptance = PromptAcceptance::DENIED;
+  PromptUserResponse::PromptAcceptance expected_prompt_acceptance =
+      PromptUserResponse::DENIED;
   ChromeDisconnectPoint expected_disconnection_point =
       ChromeDisconnectPoint::kNone;
 };
@@ -378,31 +378,11 @@
   }
 
   // Send a response to the cleaner with the expected values.
-  bool SendResponse(PromptAcceptance prompt_acceptance) {
+  bool SendResponse(PromptUserResponse::PromptAcceptance prompt_acceptance) {
     DCHECK(response_write_handle_.IsValid());
 
-    chrome_cleaner::PromptUserResponse response;
-
-    switch (prompt_acceptance) {
-      case PromptAcceptance::DENIED:
-        response.set_prompt_acceptance(
-            chrome_cleaner::PromptUserResponse::DENIED);
-        break;
-      case PromptAcceptance::ACCEPTED_WITH_LOGS:
-        response.set_prompt_acceptance(
-            chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS);
-        break;
-      case PromptAcceptance::ACCEPTED_WITHOUT_LOGS:
-        response.set_prompt_acceptance(
-            chrome_cleaner::PromptUserResponse::ACCEPTED_WITHOUT_LOGS);
-        break;
-      case PromptAcceptance::UNSPECIFIED:
-      default:
-        response.set_prompt_acceptance(
-            chrome_cleaner::PromptUserResponse::UNSPECIFIED);
-        break;
-    }
-
+    PromptUserResponse response;
+    response.set_prompt_acceptance(prompt_acceptance);
     return SendMessage(response);
   }
 
@@ -430,7 +410,8 @@
         kExpectedChromeDisconnectPointSwitch);
 
     expected_prompt_acceptance_ =
-        GetEnumFromCommandLine<PromptAcceptance>(kExpectedPromptResultSwitch);
+        GetEnumFromCommandLine<PromptUserResponse::PromptAcceptance>(
+            kExpectedPromptResultSwitch);
   }
 
   base::win::ScopedHandle ExtractHandleFromCommandLine(
@@ -467,7 +448,7 @@
   // Execute all steps of the prompt according to passed in test config.
   bool Run() {
     DCHECK_NE(expected_disconnect_point_, ChromeDisconnectPoint::kUnspecified);
-    DCHECK_NE(expected_prompt_acceptance_, PromptAcceptance::UNSPECIFIED);
+    DCHECK_NE(expected_prompt_acceptance_, PromptUserResponse::UNSPECIFIED);
 
     CloseConnectionIfDisconectionPointReached(
         ChromeDisconnectPoint::kOnStartup);
@@ -575,7 +556,8 @@
   ChromeDisconnectPoint expected_disconnect_point_ =
       ChromeDisconnectPoint::kUnspecified;
 
-  PromptAcceptance expected_prompt_acceptance_ = PromptAcceptance::UNSPECIFIED;
+  PromptUserResponse::PromptAcceptance expected_prompt_acceptance_ =
+      PromptUserResponse::UNSPECIFIED;
   const base::CommandLine* command_line_ =
       base::CommandLine::ForCurrentProcess();
 };
@@ -594,7 +576,10 @@
 
 class ProtoChromePromptIPCTest
     : public ::testing::TestWithParam<
-          std::tuple<bool, bool, PromptAcceptance, ChromeDisconnectPoint>> {
+          std::tuple<bool,
+                     bool,
+                     PromptUserResponse::PromptAcceptance,
+                     ChromeDisconnectPoint>> {
  private:
   base::test::TaskEnvironment task_environment;
 };
@@ -611,7 +596,8 @@
                              &response_read_handle_, &response_write_handle_);
   }
 
-  void ValidateAcceptance(PromptAcceptance prompt_acceptance) {
+  void ValidateAcceptance(
+      PromptUserResponse::PromptAcceptance prompt_acceptance) {
     EXPECT_EQ(prompt_acceptance, test_config_.expected_prompt_acceptance);
     main_runloop_.Quit();
   }
@@ -746,7 +732,7 @@
                          testing::Combine(
                              /*[>uws_expected=<]*/ Values(false),
                              /*[>with_registry_keys=<]*/ Values(false),
-                             Values(PromptAcceptance::DENIED),
+                             Values(PromptUserResponse::DENIED),
                              Values(ChromeDisconnectPoint::kNone,
                                     ChromeDisconnectPoint::kOnStartup)),
                          GetParamNameForTest());
@@ -757,9 +743,9 @@
     testing::Combine(
         /*uws_expected=*/Values(true),
         /*with_registry_keys=*/Bool(),
-        Values(PromptAcceptance::ACCEPTED_WITH_LOGS,
-               PromptAcceptance::ACCEPTED_WITHOUT_LOGS,
-               PromptAcceptance::DENIED),
+        Values(PromptUserResponse::ACCEPTED_WITH_LOGS,
+               PromptUserResponse::ACCEPTED_WITHOUT_LOGS,
+               PromptUserResponse::DENIED),
         Values(ChromeDisconnectPoint::kNone,
                ChromeDisconnectPoint::kOnStartup,
                ChromeDisconnectPoint::kAfterVersion,
@@ -832,8 +818,9 @@
     EXPECT_TRUE(mock_chrome_->ReadRequest(request_length, &request));
   }
 
-  void ValidateAcceptance(PromptAcceptance expected_prompt_acceptance,
-                          PromptAcceptance prompt_acceptance) {
+  void ValidateAcceptance(
+      PromptUserResponse::PromptAcceptance expected_prompt_acceptance,
+      PromptUserResponse::PromptAcceptance prompt_acceptance) {
     EXPECT_EQ(prompt_acceptance, expected_prompt_acceptance);
     main_runloop_.Quit();
   }
@@ -856,8 +843,7 @@
   chrome_prompt_ipc_->PostPromptUserTask(
       {kInvalidFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
-                     base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::DENIED));
+                     base::Unretained(this), PromptUserResponse::DENIED));
 
   // Providing an invalid file path will trigger an immediate denial from the
   // cleaner side. No communication will happen with Chrome so we do not call
@@ -873,8 +859,7 @@
   chrome_prompt_ipc_->PostPromptUserTask(
       {}, {kInvalidRegistryKey}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
-                     base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::DENIED));
+                     base::Unretained(this), PromptUserResponse::DENIED));
 
   // Providing an invalid registry key will trigger an immediate denial from the
   // cleaner side. No communication will happen with Chrome so we do not call
@@ -891,8 +876,7 @@
   chrome_prompt_ipc_->PostPromptUserTask(
       {}, {}, {kInvalidExtensionID},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
-                     base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::DENIED));
+                     base::Unretained(this), PromptUserResponse::DENIED));
 
   // Providing an invalid extension id will trigger an immediate denial from the
   // cleaner side. No communication will happen with Chrome so we do not call
@@ -910,13 +894,14 @@
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
                      base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS));
+                     PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the prompt message.
   ExpectMessage();
 
   // Send back the response.
-  EXPECT_TRUE(mock_chrome_->SendResponse(PromptAcceptance::ACCEPTED_WITH_LOGS));
+  EXPECT_TRUE(
+      mock_chrome_->SendResponse(PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the close connection message.
   ExpectMessage();
@@ -933,7 +918,7 @@
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
                      base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS));
+                     PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the prompt message.
   ExpectMessage();
@@ -958,7 +943,7 @@
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
                      base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS));
+                     PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the prompt message.
   ExpectMessage();
@@ -983,14 +968,13 @@
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
                      base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS));
+                     PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the prompt message.
   ExpectMessage();
 
-  chrome_cleaner::PromptUserResponse response;
-  response.set_prompt_acceptance(
-      chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS);
+  PromptUserResponse response;
+  response.set_prompt_acceptance(PromptUserResponse::ACCEPTED_WITH_LOGS);
 
   std::string response_content;
   response.SerializeToString(&response_content);
@@ -1020,14 +1004,13 @@
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
                      base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS));
+                     PromptUserResponse::ACCEPTED_WITH_LOGS));
 
   // Expect the prompt message.
   ExpectMessage();
 
-  chrome_cleaner::PromptUserResponse response;
-  response.set_prompt_acceptance(
-      chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS);
+  PromptUserResponse response;
+  response.set_prompt_acceptance(PromptUserResponse::ACCEPTED_WITH_LOGS);
 
   std::string response_content;
   response.SerializeToString(&response_content);
@@ -1055,8 +1038,7 @@
   chrome_prompt_ipc_->PostPromptUserTask(
       {kNonASCIIFilePath}, {}, {},
       base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance,
-                     base::Unretained(this),
-                     chrome_cleaner::PromptAcceptance::UNSPECIFIED));
+                     base::Unretained(this), PromptUserResponse::UNSPECIFIED));
 
   // Expect the prompt message.
   ExpectMessage();
diff --git a/chrome/chrome_cleaner/ui/BUILD.gn b/chrome/chrome_cleaner/ui/BUILD.gn
index ea8933b..36eed5a1 100644
--- a/chrome/chrome_cleaner/ui/BUILD.gn
+++ b/chrome/chrome_cleaner/ui/BUILD.gn
@@ -24,7 +24,11 @@
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/settings",
     "//components/chrome_cleaner/public/constants:constants",
-    "//components/chrome_cleaner/public/interfaces",
+  ]
+
+  public_deps = [
+    "//components/chrome_cleaner/public/proto",
+    "//third_party/protobuf:protobuf_lite",
   ]
 }
 
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc
index ffb8bf7..2cad2ff 100644
--- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc
+++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc
@@ -81,24 +81,24 @@
 
 void ChromeProxyMainDialog::PostPromptResultReceivedTask(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
-    mojom::PromptAcceptance prompt_acceptance) {
+    PromptUserResponse::PromptAcceptance prompt_acceptance) {
   task_runner->PostTask(
       FROM_HERE, base::BindOnce(&ChromeProxyMainDialog::PromptResultReceived,
                                 base::Unretained(this), prompt_acceptance));
 }
 
 void ChromeProxyMainDialog::PromptResultReceived(
-    mojom::PromptAcceptance prompt_acceptance) {
+    PromptUserResponse::PromptAcceptance prompt_acceptance) {
   Settings::GetInstance()->set_logs_allowed_in_cleanup_mode(
-      prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITH_LOGS);
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS);
   delegate()->AcceptedCleanup(
-      prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITH_LOGS ||
-      prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS);
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS ||
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITHOUT_LOGS);
 }
 
 void ChromeProxyMainDialog::PostCloseAfterReceivingResponseTask(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
-    mojom::PromptAcceptance prompt_acceptance) {
+    PromptUserResponse::PromptAcceptance prompt_acceptance) {
   task_runner->PostTask(
       FROM_HERE,
       base::BindOnce(&ChromeProxyMainDialog::CloseAfterReceivingResponse,
@@ -106,7 +106,7 @@
 }
 
 void ChromeProxyMainDialog::CloseAfterReceivingResponse(
-    mojom::PromptAcceptance /*prompt_acceptance*/) {
+    PromptUserResponse::PromptAcceptance /*prompt_acceptance*/) {
   delegate()->OnClose();
 }
 
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h
index f734aed8..44537e4 100644
--- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h
+++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h
@@ -14,7 +14,7 @@
 #include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h"
 #include "chrome/chrome_cleaner/ui/main_dialog_api.h"
 #include "components/chrome_cleaner/public/constants/result_codes.h"
-#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
+#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h"
 
 namespace chrome_cleaner {
 
@@ -46,22 +46,24 @@
   // thread.
   void PostPromptResultReceivedTask(
       scoped_refptr<base::SequencedTaskRunner> task_runner,
-      mojom::PromptAcceptance prompt_acceptance);
+      PromptUserResponse::PromptAcceptance prompt_acceptance);
 
   // Handles the prompt acceptance result received from Chrome. This should
   // only be called by PostPromptResultReceivedTask(), that will handle posting
   // it to the right thread.
-  void PromptResultReceived(mojom::PromptAcceptance prompt_acceptance);
+  void PromptResultReceived(
+      PromptUserResponse::PromptAcceptance prompt_acceptance);
 
   // Callback for the Mojo IPC that posts CloseAfterReceivingResponse() on the
   // UI thread.
   void PostCloseAfterReceivingResponseTask(
       scoped_refptr<base::SequencedTaskRunner> task_runner,
-      mojom::PromptAcceptance prompt_acceptance);
+      PromptUserResponse::PromptAcceptance prompt_acceptance);
 
   // Closes the dialog after receiving a response from Chrome when no UwS is
   // found in the system.
-  void CloseAfterReceivingResponse(mojom::PromptAcceptance prompt_acceptance);
+  void CloseAfterReceivingResponse(
+      PromptUserResponse::PromptAcceptance prompt_acceptance);
 
   // Pointer to the wrapper for the Mojo IPC to send scan results to Chrome.
   ChromePromptIPC* chrome_prompt_ipc_;
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc
index 879a71c2..18743d8 100644
--- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc
+++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc
@@ -16,13 +16,13 @@
 #include "chrome/chrome_cleaner/test/test_pup_data.h"
 #include "chrome/chrome_cleaner/test/test_settings_util.h"
 #include "chrome/chrome_cleaner/ui/mock_main_dialog_delegate.h"
+#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chrome_cleaner {
 namespace {
 
-using mojom::PromptAcceptance;
 using ::testing::_;
 using ::testing::Eq;
 using ::testing::Invoke;
@@ -58,8 +58,8 @@
       .WillOnce(Invoke([](const std::vector<base::FilePath>& files_to_delete,
                           const std::vector<base::string16>& registry_keys,
                           const std::vector<base::string16>& extension_ids,
-                          mojom::ChromePrompt::PromptUserCallback* callback) {
-        std::move(*callback).Run(PromptAcceptance::DENIED);
+                          ChromePromptIPC::PromptUserCallback* callback) {
+        std::move(*callback).Run(PromptUserResponse::DENIED);
       }));
 
   dialog_->NoPUPsFound();
@@ -77,7 +77,7 @@
 }
 
 class ConfirmCleanupChromeProxyMainDialogTest
-    : public ::testing::TestWithParam<PromptAcceptance> {
+    : public ::testing::TestWithParam<PromptUserResponse::PromptAcceptance> {
  public:
   void SetUp() override { Settings::SetInstanceForTesting(&mock_settings_); }
 
@@ -88,11 +88,12 @@
 
 TEST_P(ConfirmCleanupChromeProxyMainDialogTest, ConfirmCleanup) {
   constexpr UwSId kFakePupId = 1024;
-  PromptAcceptance prompt_acceptance = GetParam();
+  PromptUserResponse::PromptAcceptance prompt_acceptance = GetParam();
   bool accept_cleanup =
-      prompt_acceptance == PromptAcceptance::ACCEPTED_WITH_LOGS ||
-      prompt_acceptance == PromptAcceptance::ACCEPTED_WITHOUT_LOGS;
-  bool logs_allowed = prompt_acceptance == PromptAcceptance::ACCEPTED_WITH_LOGS;
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS ||
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITHOUT_LOGS;
+  bool logs_allowed =
+      prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS;
 
   base::test::SingleThreadTaskEnvironment task_environment(
       base::test::SingleThreadTaskEnvironment::MainThreadType::UI);
@@ -139,7 +140,7 @@
                            const std::vector<base::FilePath>& files_to_delete,
                            const std::vector<base::string16>& registry_keys,
                            const std::vector<base::string16>& extension_ids,
-                           mojom::ChromePrompt::PromptUserCallback* callback) {
+                           ChromePromptIPC::PromptUserCallback* callback) {
         std::move(*callback).Run(prompt_acceptance);
       }));
 
@@ -156,9 +157,9 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     ConfirmCleanupChromeProxyMainDialogTest,
-    testing::Values(PromptAcceptance::ACCEPTED_WITH_LOGS,
-                    PromptAcceptance::ACCEPTED_WITHOUT_LOGS,
-                    PromptAcceptance::DENIED));
+    testing::Values(PromptUserResponse::ACCEPTED_WITH_LOGS,
+                    PromptUserResponse::ACCEPTED_WITHOUT_LOGS,
+                    PromptUserResponse::DENIED));
 
 }  // namespace
 }  // namespace chrome_cleaner
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
index 5d01d00b..96653e9 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -1174,7 +1174,7 @@
 
 HRESULT CGaiaCredentialBase::UnAdvise(void) {
   LOGFN(INFO);
-  events_.Release();
+  events_.Reset();
 
   return S_OK;
 }
@@ -1945,7 +1945,7 @@
 HRESULT CGaiaCredentialBase::Terminate() {
   LOGFN(INFO);
   SetDeselected();
-  provider_.Release();
+  provider_.Reset();
   return S_OK;
 }
 
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.h b/chrome/credential_provider/gaiacp/gaia_credential_base.h
index f33a7d37..e9d64b4 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base.h
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base.h
@@ -7,6 +7,8 @@
 
 #include "chrome/credential_provider/gaiacp/stdafx.h"
 
+#include <wrl/client.h>
+
 #include <memory>
 
 #include "base/strings/string16.h"
@@ -62,7 +64,7 @@
     UIProcessInfo();
     ~UIProcessInfo();
 
-    CComPtr<IGaiaCredential> credential;
+    Microsoft::WRL::ComPtr<IGaiaCredential> credential;
     base::win::ScopedHandle logon_token;
     base::win::ScopedProcessInformation procinfo;
     StdParentHandles parent_handles;
@@ -76,7 +78,9 @@
   ~CGaiaCredentialBase();
 
   // Members to access user credentials.
-  const CComPtr<IGaiaCredentialProvider>& provider() const { return provider_; }
+  const Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider() const {
+    return provider_;
+  }
   const CComBSTR& get_username() const { return username_; }
   const CComBSTR& get_password() const { return password_; }
   const CComBSTR& get_sid() const { return user_sid_; }
@@ -269,8 +273,8 @@
 
   HRESULT RecoverWindowsPasswordIfPossible(base::string16* recovered_password);
 
-  CComPtr<ICredentialProviderCredentialEvents> events_;
-  CComPtr<IGaiaCredentialProvider> provider_;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredentialEvents> events_;
+  Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider_;
 
   // Handle to the logon UI process.
   HANDLE logon_ui_process_ = INVALID_HANDLE_VALUE;
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
index 0ac11f1..09dfa76 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
@@ -5,6 +5,7 @@
 #include <windows.h>
 
 #include <sddl.h>  // For ConvertSidToStringSid()
+#include <wrl/client.h>
 
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -67,13 +68,13 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, Advise) {
   // Create provider with credentials. This should Advise the credential.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
   // Release ref count so the credential can be deleted by the call to
   // ReleaseProvider.
-  cred.Release();
+  cred.Reset();
 
   // Release the provider. This should unadvise the credential.
   ASSERT_EQ(S_OK, ReleaseProvider());
@@ -81,7 +82,7 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, SetSelected) {
   // Create provider and credential only.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -97,7 +98,7 @@
       FakeInternetAvailabilityChecker::kHicForceNo);
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -106,12 +107,12 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_GlsLoadingFailed) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
   // Fail loading the gls logon UI.
   test->FailLoadingGaiaLogonStub();
 
@@ -121,7 +122,7 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Start) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -130,12 +131,12 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Finish) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -159,12 +160,12 @@
 TEST_F(GcpGaiaCredentialBaseTest,
        GetSerialization_SetDeselectedBeforeReportResult) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -211,12 +212,12 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Abort) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
   ASSERT_EQ(S_OK, test->SetDefaultExitCode(kUiecAbort));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
@@ -238,12 +239,12 @@
                       &first_sid));
   ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -258,12 +259,12 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_MultipleCalls) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr wchar_t kStartGlsEventName[] =
       L"GetSerialization_MultipleCalls_Wait";
@@ -325,16 +326,16 @@
                 base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(CPFS_HIDDEN,
             fake_credential_provider_credential_events()->GetFieldState(
-                cred, FID_FORGOT_PASSWORD_LINK));
+                cred.Get(), FID_FORGOT_PASSWORD_LINK));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -344,11 +345,11 @@
   if (!enable_forgot_password_registry_value) {
     ASSERT_EQ(CPFS_HIDDEN,
               fake_credential_provider_credential_events()->GetFieldState(
-                  cred, FID_FORGOT_PASSWORD_LINK));
+                  cred.Get(), FID_FORGOT_PASSWORD_LINK));
   } else {
     ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE,
               fake_credential_provider_credential_events()->GetFieldState(
-                  cred, FID_FORGOT_PASSWORD_LINK));
+                  cred.Get(), FID_FORGOT_PASSWORD_LINK));
   }
 
   // Update the Windows password to be the real password created for the user.
@@ -382,16 +383,16 @@
                 base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(CPFS_HIDDEN,
             fake_credential_provider_credential_events()->GetFieldState(
-                cred, FID_FORGOT_PASSWORD_LINK));
+                cred.Get(), FID_FORGOT_PASSWORD_LINK));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -400,7 +401,7 @@
 
   ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE,
             fake_credential_provider_credential_events()->GetFieldState(
-                cred, FID_FORGOT_PASSWORD_LINK));
+                cred.Get(), FID_FORGOT_PASSWORD_LINK));
 
   // Check that the process has not finished yet.
   CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE cpgsr;
@@ -452,12 +453,12 @@
                 base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -499,12 +500,12 @@
                 base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -555,12 +556,12 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Cancel) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   // This event is merely used to keep the gls running while it is cancelled
   // through SetDeselected().
@@ -586,7 +587,7 @@
 
 TEST_F(GcpGaiaCredentialBaseTest, FailedUserCreation) {
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -602,12 +603,12 @@
 TEST_F(GcpGaiaCredentialBaseTest, StripEmailTLD) {
   USES_CONVERSION;
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "foo@imfl.info";
 
@@ -622,7 +623,7 @@
 TEST_F(GcpGaiaCredentialBaseTest, NewUserDisabledThroughUsageScenario) {
   USES_CONVERSION;
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Set the other user tile so that we can get the anonymous credential
   // that may try create a new user.
@@ -662,7 +663,7 @@
   fake_user_array()->SetAccountOptions(CPAO_EMPTY_LOCAL);
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -691,14 +692,14 @@
   ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   // User should have invalid token handle and be locked.
   EXPECT_FALSE(
@@ -743,14 +744,14 @@
   ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with valid token handle response and sign in the anonymous
   // credential with the user that should still be valid.
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -799,12 +800,12 @@
   USES_CONVERSION;
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "bar@gmail.com";
 
@@ -820,12 +821,12 @@
   USES_CONVERSION;
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "toto@googlemail.com";
 
@@ -840,12 +841,12 @@
 TEST_F(GcpGaiaCredentialBaseTest, InvalidUsernameCharacters) {
   USES_CONVERSION;
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "a\\[]:|<>+=;?*z@gmail.com";
 
@@ -861,12 +862,12 @@
   USES_CONVERSION;
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "areallylongemailadressdude@gmail.com";
 
@@ -881,12 +882,12 @@
 TEST_F(GcpGaiaCredentialBaseTest, EmailTooLong2) {
   USES_CONVERSION;
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   constexpr char email[] = "foo@areallylongdomaindude.com";
 
@@ -903,12 +904,12 @@
   constexpr char email[] = "foo";
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email));
 
@@ -924,12 +925,12 @@
   constexpr char email[] = "@com";
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email));
 
@@ -945,12 +946,12 @@
   constexpr char email[] = "@.com";
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email));
 
@@ -966,7 +967,7 @@
   void SetUp() override;
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred_;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred_;
   // The admin sdk users directory get URL.
   std::string get_cd_user_url_ = base::StringPrintf(
       "https://www.googleapis.com/admin/directory/v1/users/"
@@ -996,8 +997,8 @@
   fake_http_url_fetcher_factory()->SetFakeFailedResponse(
       GURL(gaia_urls_->oauth2_token_url().spec().c_str()), E_FAIL);
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1030,8 +1031,8 @@
       GURL(gaia_urls_->oauth2_token_url().spec().c_str()),
       FakeWinHttpUrlFetcher::Headers(), "{}");
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1066,8 +1067,8 @@
   fake_http_url_fetcher_factory()->SetFakeResponse(
       GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(), "{}");
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1096,8 +1097,8 @@
   fake_http_url_fetcher_factory()->SetFakeFailedResponse(
       GURL(get_cd_user_url_.c_str()), E_FAIL);
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1150,8 +1151,8 @@
       GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(),
       admin_sdk_response);
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1205,8 +1206,8 @@
       GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(),
       admin_sdk_response);
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred_.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred_.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -1294,12 +1295,12 @@
   }
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   test->SetGlsEmailAddress(user_email);
 
@@ -1428,7 +1429,7 @@
   // Sign on once to store the password in the LSA
   {
     // Create provider and start logon.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
     ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -1469,12 +1470,12 @@
   // automatically.
   {
     // Create provider and start logon.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
     ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-    CComPtr<ITestCredential> test;
-    ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+    Microsoft::WRL::ComPtr<ITestCredential> test;
+    ASSERT_EQ(S_OK, cred.As(&test));
 
     // Send back a different gaia password to force a password update.
     ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword));
@@ -1485,8 +1486,8 @@
 
     ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-    CComPtr<ITestCredentialProvider> test_provider;
-    ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+    Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+    ASSERT_EQ(S_OK, created_provider().As(&test_provider));
 
     // If either password storage or recovery failed then the user will need to
     // enter their old Windows password.
@@ -1498,7 +1499,7 @@
       // through escros service fails.
       ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE,
                 fake_credential_provider_credential_events()->GetFieldState(
-                    cred, FID_CURRENT_PASSWORD_FIELD));
+                    cred.Get(), FID_CURRENT_PASSWORD_FIELD));
 
       // Set the correct old password so that the user can sign in.
       ASSERT_EQ(S_OK,
@@ -1511,7 +1512,7 @@
       // through escrow service succeeds.
       ASSERT_EQ(CPFS_HIDDEN,
                 fake_credential_provider_credential_events()->GetFieldState(
-                    cred, FID_CURRENT_PASSWORD_FIELD));
+                    cred.Get(), FID_CURRENT_PASSWORD_FIELD));
 
       // Make sure the new password is sent to the provider.
       EXPECT_STREQ(A2OLE(kNewPassword), OLE2CW(test_provider->password()));
@@ -1537,12 +1538,12 @@
   if (generate_public_key_again_result != 0) {
     constexpr char kNewPassword2[] = "password3";
     // Create provider and start logon.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
     ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-    CComPtr<ITestCredential> test;
-    ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+    Microsoft::WRL::ComPtr<ITestCredential> test;
+    ASSERT_EQ(S_OK, cred.As(&test));
 
     // Send back a different gaia password to force a password update.
     ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword2));
@@ -1553,8 +1554,8 @@
 
     ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-    CComPtr<ITestCredentialProvider> test_provider;
-    ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+    Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+    ASSERT_EQ(S_OK, created_provider().As(&test_provider));
 
     // Logon should not complete but there is no error message.
     EXPECT_EQ(test_provider->credentials_changed_fired(), false);
@@ -1647,7 +1648,7 @@
   // Sign on once to store the password in the LSA
   {
     // Create provider and start logon.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
     ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
@@ -1666,12 +1667,12 @@
     constexpr char kNewPassword[] = "password2";
 
     // Create provider and start logon.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
     ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-    CComPtr<ITestCredential> test;
-    ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+    Microsoft::WRL::ComPtr<ITestCredential> test;
+    ASSERT_EQ(S_OK, cred.As(&test));
 
     // Send back a different gaia password to force a password update.
     ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword));
@@ -1682,8 +1683,8 @@
 
     ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-    CComPtr<ITestCredentialProvider> test_provider;
-    ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+    Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+    ASSERT_EQ(S_OK, created_provider().As(&test_provider));
 
     // Empty escrow service url will disable password
     // recovery and force the user to enter their password.
@@ -1745,14 +1746,14 @@
   ASSERT_EQ(current_full_name, (BSTR)full_name);
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string()));
 
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
index 1bfc4ba..fa75de0 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -51,13 +51,14 @@
 namespace {
 
 // Initializes an object that implements IReauthCredential.
-HRESULT InitializeReauthCredential(CGaiaCredentialProvider* provider,
-                                   const base::string16& sid,
-                                   const base::string16& domain,
-                                   const base::string16& username,
-                                   const CComPtr<IGaiaCredential>& gaia_cred) {
-  CComPtr<IReauthCredential> reauth;
-  HRESULT hr = gaia_cred.QueryInterface(&reauth);
+HRESULT InitializeReauthCredential(
+    CGaiaCredentialProvider* provider,
+    const base::string16& sid,
+    const base::string16& domain,
+    const base::string16& username,
+    const Microsoft::WRL::ComPtr<IGaiaCredential>& gaia_cred) {
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth;
+  HRESULT hr = gaia_cred.As(&reauth);
   if (FAILED(hr)) {
     LOG(ERROR) << "Could not get reauth credential interface hr=" << putHR(hr);
     return hr;
@@ -107,8 +108,7 @@
   }
 
   return CComCreator<CComObject<CredentialT>>::CreateInstance(
-      nullptr, IID_IGaiaCredential,
-      reinterpret_cast<void**>(&credential_com_ptr->gaia_cred));
+      nullptr, IID_PPV_ARGS(&credential_com_ptr->gaia_cred));
 }
 
 }  // namespace
@@ -224,7 +224,7 @@
 }
 
 bool CGaiaCredentialProvider::ProviderConcurrentState::SetAutoLogonCredential(
-    const CComPtr<IGaiaCredential>& auto_logon_credential) {
+    const Microsoft::WRL::ComPtr<IGaiaCredential>& auto_logon_credential) {
   base::AutoLock locker(state_update_lock_);
   // Always update the credential.
   auto_logon_credential_ = auto_logon_credential;
@@ -282,7 +282,7 @@
 
 void CGaiaCredentialProvider::ProviderConcurrentState::InternalReset() {
   users_need_to_be_refreshed_ = false;
-  auto_logon_credential_.Release();
+  auto_logon_credential_.Reset();
 }
 
 CGaiaCredentialProvider::CGaiaCredentialProvider() {}
@@ -318,10 +318,10 @@
   CHECK(!token_handle_updater_);
   // Reset event support.
   advise_context_ = 0;
-  events_.Release();
+  events_.Reset();
   set_serialization_sid_.clear();
   concurrent_state_.Reset();
-  user_array_.Release();
+  user_array_.Reset();
 }
 
 void CGaiaCredentialProvider::CleanupOlderVersions() {
@@ -392,7 +392,7 @@
   }
 
   for (DWORD i = 0; i < count; ++i) {
-    CComPtr<ICredentialProviderUser> user;
+    Microsoft::WRL::ComPtr<ICredentialProviderUser> user;
     hr = users->GetAt(i, &user);
     if (FAILED(hr)) {
       LOGFN(ERROR) << "users->GetAt hr=" << putHR(hr);
@@ -469,7 +469,7 @@
 }
 
 void CGaiaCredentialProvider::AddCredentialAndCheckAutoLogon(
-    const CComPtr<IGaiaCredential>& cred,
+    const Microsoft::WRL::ComPtr<IGaiaCredential>& cred,
     const base::string16& sid,
     GaiaCredentialComPtrStorage* auto_logon_credential) {
   USES_CONVERSION;
@@ -486,8 +486,8 @@
 
   // If serialization sid is set, then try to see if this credential is a reauth
   // credential that needs to be auto signed in.
-  CComPtr<IReauthCredential> associated_user;
-  if (FAILED(cred.QueryInterface(&associated_user)))
+  Microsoft::WRL::ComPtr<IReauthCredential> associated_user;
+  if (FAILED(cred.As(&associated_user)))
     return;
 
   if (set_serialization_sid_ != sid)
@@ -512,7 +512,7 @@
   if (FAILED(hr))
     LOG(ERROR) << "Could not create anonymous credential hr=" << putHR(hr);
 
-  hr = CreateReauthCredentials(user_array_, auto_logon_credential);
+  hr = CreateReauthCredentials(user_array_.Get(), auto_logon_credential);
   if (FAILED(hr))
     LOG(ERROR) << "CreateReauthCredentials hr=" << putHR(hr);
 }
@@ -552,10 +552,8 @@
   CHECK(!credential ||
         AssociatedUserValidator::Get()->IsDenyAccessUpdateBlocked());
 
-  CComPtr<IGaiaCredential> gaia_credential;
-  if (credential->QueryInterface(IID_IGaiaCredential,
-                                 reinterpret_cast<void**>(&gaia_credential)) ==
-      S_OK) {
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_credential;
+  if (credential->QueryInterface(IID_PPV_ARGS(&gaia_credential)) == S_OK) {
     // Try to set the auto logon credential. If it succeeds we can raise a
     // credential changed event.
     if (concurrent_state_.SetAutoLogonCredential(gaia_credential) && events_)
@@ -799,7 +797,7 @@
     for (size_t i = 0;
          i < users_.size() && *default_index == CREDENTIAL_PROVIDER_NO_DEFAULT;
          ++i) {
-      if (local_auto_logon_credential.gaia_cred.IsEqualObject(users_[i]))
+      if (local_auto_logon_credential.gaia_cred == users_[i])
         *default_index = i;
     }
 
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.h b/chrome/credential_provider/gaiacp/gaia_credential_provider.h
index 54edb10..e22dd396 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider.h
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_PROVIDER_H_
 #define CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_PROVIDER_H_
 
+#include <wrl/client.h>
+
 #include <limits>
 #include <memory>
 #include <set>
@@ -72,12 +74,12 @@
   // determine the result of this query.
   static bool CanNewUsersBeCreated(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus);
 
-  // Struct to allow passing CComPtr by pointer without the implicit conversion
-  // to ** version of the CComPtr
+  // Struct to allow passing ComPtr by pointer without the implicit conversion
+  // to ** version of the ComPtr
   struct GaiaCredentialComPtrStorage {
     GaiaCredentialComPtrStorage();
     ~GaiaCredentialComPtrStorage();
-    CComPtr<IGaiaCredential> gaia_cred;
+    Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
   };
 
   typedef HRESULT (*CredentialCreatorFn)(GaiaCredentialComPtrStorage*);
@@ -124,7 +126,7 @@
     // required if a previous call to RequestUserRefreshIfNeeded was made that
     // requested a credential changed event.
     bool SetAutoLogonCredential(
-        const CComPtr<IGaiaCredential>& auto_logon_credential);
+        const Microsoft::WRL::ComPtr<IGaiaCredential>& auto_logon_credential);
 
     // Gets the current valid update state of the provider to determnie whether
     // an auto logon needs to be done or a refresh of the credentials. The two
@@ -143,7 +145,7 @@
     void InternalReset();
 
     // Reference to the credential that authenticated the user.
-    CComPtr<IGaiaCredential> auto_logon_credential_;
+    Microsoft::WRL::ComPtr<IGaiaCredential> auto_logon_credential_;
 
     // Set in NotifyUserAccessDenied to notify the main thread that it will need
     // to update credentials on the next call to GetCredentialCount. This
@@ -184,7 +186,7 @@
   // |auto_logon_credential| with a reference to the credential that needs to
   // perform auto logon (if any).
   void AddCredentialAndCheckAutoLogon(
-      const CComPtr<IGaiaCredential>& cred,
+      const Microsoft::WRL::ComPtr<IGaiaCredential>& cred,
       const base::string16& sid,
       GaiaCredentialComPtrStorage* auto_logon_credential);
 
@@ -231,15 +233,15 @@
   CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus_ = CPUS_INVALID;
   DWORD cpus_flags_ = 0;
   UINT_PTR advise_context_;
-  CComPtr<ICredentialProviderEvents> events_;
-  CComPtr<ICredentialProviderUserArray> user_array_;
+  Microsoft::WRL::ComPtr<ICredentialProviderEvents> events_;
+  Microsoft::WRL::ComPtr<ICredentialProviderUserArray> user_array_;
 
   // List of credentials exposed by this provider.  The first is always the
   // Gaia credential for creating new users.  The rest are reauth credentials.
-  std::vector<CComPtr<IGaiaCredential>> users_;
+  std::vector<Microsoft::WRL::ComPtr<IGaiaCredential>> users_;
 
   // Reference to the credential that authenticated the user.
-  CComPtr<IGaiaCredential> auto_logon_credential_;
+  Microsoft::WRL::ComPtr<IGaiaCredential> auto_logon_credential_;
 
   // Background thread updater of token handles that is created on startup to
   // ensure that user must sign in through gaia if their token handle becomes
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
index e610f3c..1e3df553 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -6,6 +6,7 @@
 #include <atlcom.h>
 #include <atlcomcli.h>
 #include <credentialprovider.h>
+#include <wrl/client.h>
 
 #include <tuple>
 
@@ -29,10 +30,10 @@
 class GcpCredentialProviderTest : public GlsRunnerTestBase {};
 
 TEST_F(GcpCredentialProviderTest, Basic) {
-  CComPtr<IGaiaCredentialProvider> provider;
+  Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider;
   ASSERT_EQ(S_OK,
             CComCreator<CComObject<CGaiaCredentialProvider>>::CreateInstance(
-                nullptr, IID_IGaiaCredentialProvider, (void**)&provider));
+                nullptr, IID_PPV_ARGS(&provider)));
 }
 
 TEST_F(GcpCredentialProviderTest, SetUserArray_NoGaiaUsers) {
@@ -41,7 +42,7 @@
                       L"username", L"password", L"full name", L"comment", L"",
                       L"", &sid));
 
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider));
 
@@ -49,14 +50,14 @@
   // requisite registry entry will be counted.
   EXPECT_EQ(1u, count);
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred));
 
-  CComPtr<ICredentialProviderCredential2> cred2;
-  ASSERT_NE(S_OK, cred.QueryInterface(&cred2));
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2;
+  ASSERT_NE(S_OK, cred.As(&cred2));
 
-  CComPtr<IReauthCredential> reauth_cred;
-  ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred));
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred;
+  ASSERT_NE(S_OK, cred.As(&reauth_cred));
 }
 
 TEST_F(GcpCredentialProviderTest, CpusLogon) {
@@ -65,7 +66,7 @@
                       L"username", L"password", L"full name", L"comment", L"",
                       L"", &sid));
 
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider));
 
@@ -73,14 +74,14 @@
   // requisite registry entry will be counted.
   EXPECT_EQ(1u, count);
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred));
 
-  CComPtr<ICredentialProviderCredential2> cred2;
-  ASSERT_NE(S_OK, cred.QueryInterface(&cred2));
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2;
+  ASSERT_NE(S_OK, cred.As(&cred2));
 
-  CComPtr<IReauthCredential> reauth_cred;
-  ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred));
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred;
+  ASSERT_NE(S_OK, cred.As(&reauth_cred));
 }
 
 TEST_F(GcpCredentialProviderTest, CpusUnlock) {
@@ -89,7 +90,7 @@
                       L"username", L"password", L"full name", L"comment", L"",
                       L"", &sid));
 
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   SetUsageScenario(CPUS_UNLOCK_WORKSTATION);
   ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider));
@@ -106,17 +107,17 @@
                       L"username", L"password", L"full name", L"comment", L"",
                       L"", &sid));
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ICredentialProvider> provider = created_provider();
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider = created_provider();
 
-  CComPtr<IGaiaCredentialProvider> gaia_provider;
-  ASSERT_EQ(S_OK, provider.QueryInterface(&gaia_provider));
+  Microsoft::WRL::ComPtr<IGaiaCredentialProvider> gaia_provider;
+  ASSERT_EQ(S_OK, provider.As(&gaia_provider));
 
   // Notify that user access is denied to fake a forced recreation of the users.
-  CComPtr<ICredentialUpdateEventsHandler> update_handler;
-  ASSERT_EQ(S_OK, provider.QueryInterface(&update_handler));
+  Microsoft::WRL::ComPtr<ICredentialUpdateEventsHandler> update_handler;
+  ASSERT_EQ(S_OK, provider.As(&update_handler));
   update_handler->UpdateCredentialsIfNeeded(true);
 
   // Credential changed event should have been received.
@@ -130,8 +131,8 @@
     AssociatedUserValidator::ScopedBlockDenyAccessUpdate deny_update_locker(
         AssociatedUserValidator::Get());
     ASSERT_EQ(S_OK, gaia_provider->OnUserAuthenticated(
-                        cred, CComBSTR(L"username"), CComBSTR(L"password"), sid,
-                        true));
+                        cred.Get(), CComBSTR(L"username"),
+                        CComBSTR(L"password"), sid, true));
   }
 
   // No credential changed should have been signalled here.
@@ -149,9 +150,9 @@
   EXPECT_EQ(0u, default_index);
   EXPECT_TRUE(autologon);
 
-  CComPtr<ICredentialProviderCredential> auto_logon_cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> auto_logon_cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &auto_logon_cred));
-  EXPECT_TRUE(auto_logon_cred.IsEqualObject(cred));
+  EXPECT_EQ(auto_logon_cred, cred);
 
   // The next call to GetCredentialCount should return re-created credentials.
 
@@ -169,9 +170,9 @@
   EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index);
   EXPECT_FALSE(autologon);
 
-  CComPtr<ICredentialProviderCredential> new_cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> new_cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &new_cred));
-  EXPECT_FALSE(new_cred.IsEqualObject(cred));
+  EXPECT_NE(new_cred, cred);
 
   // Another request to refresh the credentials should yield no credential
   // changed event or refresh of credentials.
@@ -189,9 +190,9 @@
   EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index);
   EXPECT_FALSE(autologon);
 
-  CComPtr<ICredentialProviderCredential> unchanged_cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> unchanged_cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &unchanged_cred));
-  EXPECT_TRUE(new_cred.IsEqualObject(unchanged_cred));
+  EXPECT_EQ(new_cred, unchanged_cred);
 }
 
 TEST_F(GcpCredentialProviderTest, AutoLogonBeforeUserRefresh) {
@@ -201,15 +202,15 @@
                       L"username", L"password", L"full name", L"comment", L"",
                       L"", &sid));
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ICredentialProvider> provider = created_provider();
-  CComPtr<IGaiaCredentialProvider> gaia_provider;
-  ASSERT_EQ(S_OK, provider.QueryInterface(&gaia_provider));
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider = created_provider();
+  Microsoft::WRL::ComPtr<IGaiaCredentialProvider> gaia_provider;
+  ASSERT_EQ(S_OK, provider.As(&gaia_provider));
 
-  CComPtr<ICredentialUpdateEventsHandler> update_handler;
-  ASSERT_EQ(S_OK, provider.QueryInterface(&update_handler));
+  Microsoft::WRL::ComPtr<ICredentialUpdateEventsHandler> update_handler;
+  ASSERT_EQ(S_OK, provider.As(&update_handler));
 
   // Notify user auto logon first and then notify user access denied to ensure
   // that auto logon always has precedence over user access denied.
@@ -218,8 +219,8 @@
     AssociatedUserValidator::ScopedBlockDenyAccessUpdate deny_update_locker(
         AssociatedUserValidator::Get());
     ASSERT_EQ(S_OK, gaia_provider->OnUserAuthenticated(
-                        cred, CComBSTR(L"username"), CComBSTR(L"password"), sid,
-                        true));
+                        cred.Get(), CComBSTR(L"username"),
+                        CComBSTR(L"password"), sid, true));
   }
 
   // Credential changed event should have been received.
@@ -245,9 +246,9 @@
   EXPECT_EQ(0u, default_index);
   EXPECT_TRUE(autologon);
 
-  CComPtr<ICredentialProviderCredential> auto_logon_cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> auto_logon_cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &auto_logon_cred));
-  EXPECT_TRUE(auto_logon_cred.IsEqualObject(cred));
+  EXPECT_EQ(auto_logon_cred, cred);
 
   // The next call to GetCredentialCount should return re-created credentials.
 
@@ -265,9 +266,9 @@
   EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index);
   EXPECT_FALSE(autologon);
 
-  CComPtr<ICredentialProviderCredential> new_cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> new_cred;
   ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &new_cred));
-  EXPECT_FALSE(new_cred.IsEqualObject(cred));
+  EXPECT_NE(new_cred, cred);
 
   // Deactivate the CP.
   ASSERT_EQ(S_OK, provider->UnAdvise());
@@ -286,8 +287,8 @@
                       L"gaia-id", L"foo@gmail.com", &sid));
 
   {
-    CComPtr<ICredentialProviderCredential> cred;
-    CComPtr<ICredentialProvider> provider;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProvider> provider;
     DWORD count = 0;
     ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider));
 
@@ -305,7 +306,7 @@
             fake_os_user_manager()->RemoveUser(kDummyUsername, kDummyPassword));
 
   {
-    CComPtr<ICredentialProvider> provider;
+    Microsoft::WRL::ComPtr<ICredentialProvider> provider;
     DWORD count = 0;
     ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider));
 
@@ -313,14 +314,14 @@
     ASSERT_EQ(1u, count);
 
     // And this credential should be the anonymous one.
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
     ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred));
 
-    CComPtr<ICredentialProviderCredential2> cred2;
-    ASSERT_NE(S_OK, cred.QueryInterface(&cred2));
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2;
+    ASSERT_NE(S_OK, cred.As(&cred2));
 
-    CComPtr<IReauthCredential> reauth_cred;
-    ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred));
+    Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred;
+    ASSERT_NE(S_OK, cred.As(&reauth_cred));
 
     // Release the CP.
     ASSERT_EQ(S_OK, provider->UnAdvise());
@@ -332,11 +333,11 @@
 TEST_F(GcpCredentialProviderExecutionTest, UnAdviseDuringGls) {
   USES_CONVERSION;
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   // This event is merely used to keep the gls running while it is killed by
   // Terminate().
@@ -401,8 +402,8 @@
   GetAuthenticationPackageId(&cpcs.ulAuthenticationPackage);
   cpcs.clsidCredentialProvider = CLSID_GaiaCredentialProvider;
 
-  CComPtr<ICredentialProviderCredential> cred;
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   SetDefaultTokenHandleResponse(valid_token_handles
                                     ? kDefaultValidTokenHandleResponse
                                     : kDefaultInvalidTokenHandleResponse);
@@ -480,8 +481,8 @@
   if (!has_token_handle)
     ASSERT_EQ(S_OK, SetUserProperty((BSTR)sid, kUserTokenHandle, L""));
 
-  CComPtr<ICredentialProviderCredential> cred;
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   SetDefaultTokenHandleResponse(valid_token_handle
                                     ? kDefaultValidTokenHandleResponse
@@ -496,10 +497,10 @@
   ASSERT_EQ(should_reauth_user ? 2u : 1u, count);
 
   if (should_reauth_user) {
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
     ASSERT_EQ(S_OK, provider->GetCredentialAt(1, &cred));
-    CComPtr<IReauthCredential> reauth;
-    EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
+    Microsoft::WRL::ComPtr<IReauthCredential> reauth;
+    EXPECT_EQ(S_OK, cred.As(&reauth));
   }
 }
 
@@ -577,8 +578,8 @@
                                     L"non-empty-token-handle"));
   }
 
-  CComPtr<ICredentialProviderCredential> cred;
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   SetDefaultTokenHandleResponse(valid_token_handle
                                     ? kDefaultValidTokenHandleResponse
@@ -600,19 +601,19 @@
   }
 
   if (should_reauth_user) {
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
     ASSERT_EQ(S_OK, provider->GetCredentialAt(1, &cred));
-    CComPtr<IReauthCredential> reauth;
-    EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
+    Microsoft::WRL::ComPtr<IReauthCredential> reauth;
+    EXPECT_EQ(S_OK, cred.As(&reauth));
   }
 
   // When there are two reauth credentials, validate that the second one
   // is also a reauth credential.
   if (should_reauth_user && !valid_token_handle) {
-    CComPtr<ICredentialProviderCredential> cred;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
     ASSERT_EQ(S_OK, provider->GetCredentialAt(2, &cred));
-    CComPtr<IReauthCredential> reauth;
-    EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
+    Microsoft::WRL::ComPtr<IReauthCredential> reauth;
+    EXPECT_EQ(S_OK, cred.As(&reauth));
   }
 }
 
@@ -679,7 +680,7 @@
   SetSidLockingWorkstation(second_user_locking_system ? OLE2CW(second_sid)
                                                       : OLE2CW(first_sid));
 
-  CComPtr<ICredentialProvider> provider;
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   DWORD count = 0;
   SetUsageScenario(cpus);
   SetDefaultTokenHandleResponse(valid_token_handles
@@ -707,9 +708,9 @@
   if (expected_credentials == 0)
     return;
 
-  CComPtr<ICredentialProviderCredential> cred;
-  CComPtr<ICredentialProviderCredential2> cred2;
-  CComPtr<IReauthCredential> reauth;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2;
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth;
 
   DWORD first_non_anonymous_cred_index = 0;
 
@@ -719,7 +720,7 @@
   if (other_user_tile_available) {
     EXPECT_EQ(S_OK, provider->GetCredentialAt(first_non_anonymous_cred_index++,
                                               &cred));
-    EXPECT_EQ(S_OK, cred.QueryInterface(&cred2));
+    EXPECT_EQ(S_OK, cred.As(&cred2));
   }
 
   // Not unlocking workstation: if there are more credentials then they should
@@ -731,21 +732,21 @@
     if (first_non_anonymous_cred_index < expected_credentials) {
       EXPECT_EQ(S_OK, provider->GetCredentialAt(
                           first_non_anonymous_cred_index++, &cred));
-      EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
-      EXPECT_EQ(S_OK, cred.QueryInterface(&cred2));
+      EXPECT_EQ(S_OK, cred.As(&reauth));
+      EXPECT_EQ(S_OK, cred.As(&cred2));
 
       EXPECT_EQ(S_OK, provider->GetCredentialAt(
                           first_non_anonymous_cred_index++, &cred));
-      EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
-      EXPECT_EQ(S_OK, cred.QueryInterface(&cred2));
+      EXPECT_EQ(S_OK, cred.As(&reauth));
+      EXPECT_EQ(S_OK, cred.As(&cred2));
     }
   } else if (!other_user_tile_available) {
     // Only the user who locked the computer should be returned as a credential
     // and it should be a ICredentialProviderCredential2 with the correct sid.
     EXPECT_EQ(S_OK, provider->GetCredentialAt(first_non_anonymous_cred_index++,
                                               &cred));
-    EXPECT_EQ(S_OK, cred.QueryInterface(&reauth));
-    EXPECT_EQ(S_OK, cred.QueryInterface(&cred2));
+    EXPECT_EQ(S_OK, cred.As(&reauth));
+    EXPECT_EQ(S_OK, cred.As(&cred2));
 
     wchar_t* sid;
     EXPECT_EQ(S_OK, cred2->GetUserSid(&sid));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
index 51fa2c8..3f2f692 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
@@ -5,6 +5,7 @@
 #include <atlbase.h>
 #include <atlcom.h>
 #include <atlcomcli.h>
+#include <wrl/client.h>
 
 #include "base/json/json_writer.h"
 #include "base/strings/string_number_conversions.h"
@@ -55,35 +56,35 @@
 TEST_F(GcpGaiaCredentialTest, OnUserAuthenticated) {
   USES_CONVERSION;
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<IGaiaCredential> gaia_cred;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred));
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
+  ASSERT_EQ(S_OK, cred.As(&gaia_cred));
 
   CComBSTR error;
   ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error));
-  CComPtr<ITestCredentialProvider> test_provider;
-  ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+  Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+  ASSERT_EQ(S_OK, created_provider().As(&test_provider));
   EXPECT_TRUE(test_provider->credentials_changed_fired());
 }
 
 TEST_F(GcpGaiaCredentialTest, OnUserAuthenticated_SamePassword) {
   USES_CONVERSION;
 
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<IGaiaCredential> gaia_cred;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred));
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
+  ASSERT_EQ(S_OK, cred.As(&gaia_cred));
 
   CComBSTR error;
   ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error));
 
-  CComPtr<ITestCredentialProvider> test_provider;
-  ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+  Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+  ASSERT_EQ(S_OK, created_provider().As(&test_provider));
   CComBSTR first_sid = test_provider->sid();
 
   // Report to register the user.
@@ -115,18 +116,18 @@
           base::UTF8ToUTF16(test_data_storage.GetSuccessId()).c_str(),
           base::UTF8ToUTF16(test_data_storage.GetSuccessEmail()).c_str(),
           &sid));
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<IGaiaCredential> gaia_cred;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred));
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
+  ASSERT_EQ(S_OK, cred.As(&gaia_cred));
 
   CComBSTR error;
   ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error));
 
-  CComPtr<ITestCredentialProvider> test_provider;
-  ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider));
+  Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+  ASSERT_EQ(S_OK, created_provider().As(&test_provider));
   EXPECT_TRUE(test_provider->credentials_changed_fired());
 
   test_provider->ResetCredentialsChangedFired();
@@ -157,15 +158,15 @@
   ASSERT_EQ(2u, fake_os_user_manager()->GetUserCount());
 
   // Start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<IGaiaCredential> gaia_cred;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred));
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
+  ASSERT_EQ(S_OK, cred.As(&gaia_cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(base::UTF16ToUTF8(base_username) +
                                            "@gmail.com"));
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
@@ -227,14 +228,14 @@
             fake_os_user_manager()->GetUserCount());
 
   // Create provider.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred));
 
-  CComPtr<IGaiaCredential> gaia_cred;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred));
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred;
+  ASSERT_EQ(S_OK, cred.As(&gaia_cred));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   // Start logon.
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
diff --git a/chrome/credential_provider/gaiacp/internet_availability_checker.cc b/chrome/credential_provider/gaiacp/internet_availability_checker.cc
index 86ebb67..29ecdde8 100644
--- a/chrome/credential_provider/gaiacp/internet_availability_checker.cc
+++ b/chrome/credential_provider/gaiacp/internet_availability_checker.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/credential_provider/gaiacp/internet_availability_checker.h"
 
-#include <netlistmgr.h>  // For CLSID_NetworkListManager
-
 #include <atlbase.h>
 #include <atlcom.h>
+#include <netlistmgr.h>  // For CLSID_NetworkListManager
+#include <wrl/client.h>
 
 #include "chrome/credential_provider/gaiacp/gcp_utils.h"
 #include "chrome/credential_provider/gaiacp/logging.h"
@@ -20,8 +20,9 @@
   // If any errors occur, return that internet connection is available.  At
   // worst the credential provider will try to connect and fail.
 
-  CComPtr<INetworkListManager> manager;
-  HRESULT hr = manager.CoCreateInstance(CLSID_NetworkListManager);
+  Microsoft::WRL::ComPtr<INetworkListManager> manager;
+  HRESULT hr = ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL,
+                                  IID_PPV_ARGS(&manager));
   if (FAILED(hr)) {
     LOGFN(ERROR) << "CoCreateInstance(NetworkListManager) hr=" << putHR(hr);
     return true;
diff --git a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
index 4ea60f1..57a7fb60 100644
--- a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
+++ b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
@@ -5,6 +5,7 @@
 #include <atlbase.h>
 #include <atlcom.h>
 #include <atlcomcli.h>
+#include <wrl/client.h>
 
 #include "base/json/json_writer.h"
 #include "base/strings/utf_string_conversions.h"
@@ -49,7 +50,7 @@
   USES_CONVERSION;
   CredentialProviderSigninDialogTestDataStorage test_data_storage;
 
-  CComPtr<IReauthCredential> reauth;
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth;
   ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance(
                       nullptr, IID_IReauthCredential, (void**)&reauth));
   ASSERT_TRUE(!!reauth);
@@ -61,9 +62,8 @@
   ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR(
                       A2COLE(test_data_storage.GetSuccessEmail().c_str()))));
 
-  CComPtr<ICredentialProviderCredential2> cpc2;
-  ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2,
-                                         reinterpret_cast<void**>(&cpc2)));
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2;
+  ASSERT_EQ(S_OK, reauth.As(&cpc2));
   wchar_t* sid;
   CComBSTR username;
   ASSERT_EQ(S_OK, cpc2->GetUserSid(&sid));
@@ -97,7 +97,7 @@
   ASSERT_EQ(S_OK, SetGlobalFlagForTesting(kRegEnableADAssociation,
                                           is_ad_association_enabled));
 
-  CComPtr<IReauthCredential> reauth;
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth;
   ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance(
                       nullptr, IID_IReauthCredential, (void**)&reauth));
   ASSERT_TRUE(!!reauth);
@@ -132,9 +132,8 @@
     ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR(email)));
   }
 
-  CComPtr<ICredentialProviderCredential2> cpc2;
-  ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2,
-                                         reinterpret_cast<void**>(&cpc2)));
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2;
+  ASSERT_EQ(S_OK, reauth.As(&cpc2));
   LPWSTR string_value = nullptr;
   ASSERT_EQ(S_OK, cpc2->GetStringValue(FID_DESCRIPTION, &string_value));
 
@@ -193,7 +192,7 @@
 
   GoogleMdmEnrolledStatusForTesting forced_enrolled_status(enrolled_mdm);
 
-  CComPtr<IReauthCredential> reauth;
+  Microsoft::WRL::ComPtr<IReauthCredential> reauth;
   ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance(
                       nullptr, IID_IReauthCredential, (void**)&reauth));
   ASSERT_TRUE(!!reauth);
@@ -231,9 +230,8 @@
 
   ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR(email)));
 
-  CComPtr<ICredentialProviderCredential2> cpc2;
-  ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2,
-                                         reinterpret_cast<void**>(&cpc2)));
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2;
+  ASSERT_EQ(S_OK, reauth.As(&cpc2));
   LPWSTR string_value = nullptr;
   ASSERT_EQ(S_OK, cpc2->GetStringValue(FID_DESCRIPTION, &string_value));
 
@@ -282,7 +280,7 @@
                 OLE2CW(email), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
@@ -331,7 +329,7 @@
                       OLE2CW(email), L"domain", &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
@@ -387,14 +385,14 @@
                       &second_sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   // Force the GLS to return an invalid Gaia Id without reporting the usual
   // kUiecEMailMissmatch exit code when this happens. This will test whether
@@ -425,14 +423,14 @@
                 OLE2CW(email), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string()));
 
@@ -459,14 +457,14 @@
                 base::string16(), &sid));
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
@@ -496,14 +494,14 @@
   std::string unexpected_gaia_id = "unexpected-gaia-id";
 
   // Create provider and start logon.
-  CComPtr<ICredentialProviderCredential> cred;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
 
   // Create with invalid token handle response so that a reauth occurs.
   SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
   ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred));
 
-  CComPtr<ITestCredential> test;
-  ASSERT_EQ(S_OK, cred.QueryInterface(&test));
+  Microsoft::WRL::ComPtr<ITestCredential> test;
+  ASSERT_EQ(S_OK, cred.As(&test));
 
   ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string()));
   ASSERT_EQ(S_OK, test->SetGaiaIdOverride(unexpected_gaia_id,
diff --git a/chrome/credential_provider/test/com_fakes.cc b/chrome/credential_provider/test/com_fakes.cc
index 577ad91a..7c19b992 100644
--- a/chrome/credential_provider/test/com_fakes.cc
+++ b/chrome/credential_provider/test/com_fakes.cc
@@ -262,23 +262,18 @@
       [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage*
              cred_ptr_storage) {
         return CComCreator<CComObject<CTestGaiaCredential>>::CreateInstance(
-            nullptr, IID_IGaiaCredential,
-            reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred));
+            nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred));
       },
       [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage*
              cred_ptr_storage) {
         return CComCreator<CComObject<CTestOtherUserGaiaCredential>>::
-            CreateInstance(
-                nullptr, IID_IGaiaCredential,
-                reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred));
+            CreateInstance(nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred));
       },
       [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage*
              cred_ptr_storage) {
         return CComCreator<CComObject<testing::CTestCredentialForInherited<
             CReauthCredential, IReauthCredential>>>::
-            CreateInstance(
-                nullptr, IID_IGaiaCredential,
-                reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred));
+            CreateInstance(nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred));
       });
 }
 
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc
index 394790f..408d1f49 100644
--- a/chrome/credential_provider/test/gcp_setup_unittests.cc
+++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -8,6 +8,7 @@
 #include <lmerr.h>
 #include <objbase.h>
 #include <unknwn.h>
+#include <wrl/client.h>
 
 #include <memory>
 
@@ -348,10 +349,10 @@
 
   locked_file.Close();
 
-  CComPtr<IGaiaCredentialProvider> provider;
+  Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider;
   ASSERT_EQ(S_OK,
             CComCreator<CComObject<CGaiaCredentialProvider>>::CreateInstance(
-                nullptr, IID_IGaiaCredentialProvider, (void**)&provider));
+                nullptr, IID_PPV_ARGS(&provider)));
 
   // Make sure newer version exists and old version is gone.
   ExpectAllFilesToExist(true, product_version());
diff --git a/chrome/credential_provider/test/gls_runner_test_base.cc b/chrome/credential_provider/test/gls_runner_test_base.cc
index 4feb0569..9032c5f 100644
--- a/chrome/credential_provider/test/gls_runner_test_base.cc
+++ b/chrome/credential_provider/test/gls_runner_test_base.cc
@@ -176,7 +176,7 @@
       gaia_provider_->GetCredentialCount(&count, &default_index, &autologon);
   if (SUCCEEDED(get_count_hr)) {
     for (DWORD i = 0; i < count; ++i) {
-      CComPtr<ICredentialProviderCredential> credential;
+      Microsoft::WRL::ComPtr<ICredentialProviderCredential> credential;
       HRESULT get_hr = gaia_provider_->GetCredentialAt(i, &credential);
       EXPECT_EQ(get_hr, S_OK);
       if (SUCCEEDED(get_hr)) {
@@ -195,7 +195,7 @@
   HRESULT unadvise_hr = gaia_provider_->UnAdvise();
   if (FAILED(unadvise_hr))
     hr = unadvise_hr;
-  gaia_provider_.Release();
+  gaia_provider_.Reset();
 
   return hr;
 }
@@ -208,7 +208,7 @@
   if (FAILED(hr))
     return hr;
 
-  return gaia_provider_.QueryInterface(provider);
+  return gaia_provider_.CopyTo(IID_PPV_ARGS(provider));
 }
 
 HRESULT GlsRunnerTestBase::InitializeProviderWithRemoteCredentials(
@@ -218,7 +218,7 @@
   if (FAILED(hr))
     return hr;
 
-  return gaia_provider_.QueryInterface(provider);
+  return gaia_provider_.CopyTo(IID_PPV_ARGS(provider));
 }
 
 HRESULT GlsRunnerTestBase::InitializeProviderAndGetCredential(
@@ -240,7 +240,7 @@
   if (FAILED(hr))
     return hr;
 
-  EXPECT_EQ(S_OK, testing_cred_.QueryInterface(credential));
+  EXPECT_EQ(S_OK, testing_cred_.CopyTo(IID_PPV_ARGS(credential)));
   return S_OK;
 }
 
@@ -250,12 +250,10 @@
   if (count)
     *count = 0;
 
-  CComPtr<ICredentialProvider> provider;
-
+  Microsoft::WRL::ComPtr<ICredentialProvider> provider;
   HRESULT hr =
       CComCreator<CComObject<CTestGaiaCredentialProvider>>::CreateInstance(
-          nullptr, IID_ICredentialProvider,
-          reinterpret_cast<void**>(&provider));
+          nullptr, IID_PPV_ARGS(&provider));
   if (FAILED(hr))
     return hr;
 
@@ -285,8 +283,8 @@
   }
 
   // Give list of users visible on welcome screen.
-  CComPtr<ICredentialProviderSetUserArray> provider_user_array;
-  hr = provider.QueryInterface(&provider_user_array);
+  Microsoft::WRL::ComPtr<ICredentialProviderSetUserArray> provider_user_array;
+  hr = provider.As(&provider_user_array);
   if (FAILED(hr))
     return hr;
 
@@ -342,7 +340,7 @@
 
     // Advise all the credentials
     for (DWORD i = 0; i < *count; ++i) {
-      CComPtr<ICredentialProviderCredential> current_credential;
+      Microsoft::WRL::ComPtr<ICredentialProviderCredential> current_credential;
       hr = gaia_provider_->GetCredentialAt(i, &current_credential);
       if (FAILED(hr))
         return hr;
@@ -370,7 +368,7 @@
   // Initialize the default field states by calling GetFieldState of
   // ICredentialProviderCredential.
   for (DWORD i = 0; count && i < *count; ++i) {
-    CComPtr<ICredentialProviderCredential> current_credential;
+    Microsoft::WRL::ComPtr<ICredentialProviderCredential> current_credential;
     hr = gaia_provider_->GetCredentialAt(i, &current_credential);
     if (FAILED(hr))
       return hr;
@@ -383,7 +381,7 @@
         return hr;
 
       hr = fake_credential_provider_credential_events()->SetFieldState(
-          current_credential, fieldID, cpfs);
+          current_credential.Get(), fieldID, cpfs);
       if (FAILED(hr))
         return hr;
     }
@@ -393,7 +391,7 @@
 }
 
 HRESULT GlsRunnerTestBase::ApplyProviderFilter(
-    const CComPtr<ICredentialProvider>& provider,
+    const Microsoft::WRL::ComPtr<ICredentialProvider>& provider,
     const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in,
     CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_out,
     HRESULT* update_remote_credentials_hr) {
@@ -402,7 +400,7 @@
 
   // Filter only lives long enough to apply filter and get serialization
   // credentials.
-  CComPtr<ICredentialProviderFilter> filter;
+  Microsoft::WRL::ComPtr<ICredentialProviderFilter> filter;
   HRESULT hr =
       CComCreator<CComObject<CGaiaCredentialProviderFilter>>::CreateInstance(
           nullptr, IID_ICredentialProviderFilter, (void**)&filter);
@@ -469,8 +467,8 @@
 }
 
 HRESULT GlsRunnerTestBase::WaitForLogonProcess() {
-  CComPtr<testing::ITestCredential> test;
-  HRESULT hr = testing_cred_->QueryInterface(&test);
+  Microsoft::WRL::ComPtr<testing::ITestCredential> test;
+  HRESULT hr = testing_cred_.As(&test);
   if (FAILED(hr))
     return hr;
   return test->WaitForGls();
@@ -533,9 +531,10 @@
   if (!logon_process_started_successfully_)
     return S_OK;
 
-  CComPtr<ICredentialProviderCredential> local_testing_cred = testing_cred_;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> local_testing_cred =
+      testing_cred_;
   // Release ownership on the testing_cred_ which should be finishing.
-  testing_cred_.Release();
+  testing_cred_.Reset();
 
   HRESULT hr = FinishLogonProcessWithCred(
       expected_success, expected_credentials_change_fired,
@@ -558,7 +557,8 @@
     bool expected_success,
     bool expected_credentials_change_fired,
     int expected_error_message,
-    const CComPtr<ICredentialProviderCredential>& local_testing_cred) {
+    const Microsoft::WRL::ComPtr<ICredentialProviderCredential>&
+        local_testing_cred) {
   // If no logon process was started, there is nothing to finish.
   if (!logon_process_started_successfully_)
     return S_OK;
@@ -566,13 +566,13 @@
   logon_process_started_successfully_ = false;
   DCHECK(gaia_provider_);
 
-  CComPtr<ITestCredential> test_cred;
-  HRESULT hr = local_testing_cred.QueryInterface(&test_cred);
+  Microsoft::WRL::ComPtr<ITestCredential> test_cred;
+  HRESULT hr = local_testing_cred.As(&test_cred);
   if (FAILED(hr))
     return hr;
 
-  CComPtr<ITestCredentialProvider> test_provider;
-  hr = gaia_provider_.QueryInterface(&test_provider);
+  Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider;
+  hr = gaia_provider_.As(&test_provider);
   if (FAILED(hr))
     return hr;
 
@@ -624,9 +624,10 @@
 }
 
 HRESULT GlsRunnerTestBase::ReportLogonProcessResult(
-    const CComPtr<ICredentialProviderCredential>& local_testing_cred) {
-  CComPtr<ITestCredential> test_cred;
-  HRESULT hr = local_testing_cred.QueryInterface(&test_cred);
+    const Microsoft::WRL::ComPtr<ICredentialProviderCredential>&
+        local_testing_cred) {
+  Microsoft::WRL::ComPtr<ITestCredential> test_cred;
+  HRESULT hr = local_testing_cred.As(&test_cred);
   if (FAILED(hr))
     return hr;
 
diff --git a/chrome/credential_provider/test/gls_runner_test_base.h b/chrome/credential_provider/test/gls_runner_test_base.h
index 5196358..6f813d5 100644
--- a/chrome/credential_provider/test/gls_runner_test_base.h
+++ b/chrome/credential_provider/test/gls_runner_test_base.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_CREDENTIAL_PROVIDER_TEST_GLS_RUNNER_TEST_BASE_H_
 #define CHROME_CREDENTIAL_PROVIDER_TEST_GLS_RUNNER_TEST_BASE_H_
 
+#include <wrl/client.h>
+
 #include "base/test/test_reg_util_win.h"
 #include "chrome/credential_provider/common/gcp_strings.h"
 #include "chrome/credential_provider/gaiacp/gaia_credential_provider.h"
@@ -74,7 +76,7 @@
     return &fake_internet_checker_;
   }
 
-  const CComPtr<ICredentialProvider>& created_provider() const {
+  const Microsoft::WRL::ComPtr<ICredentialProvider>& created_provider() const {
     return gaia_provider_;
   }
 
@@ -159,16 +161,18 @@
       bool expected_success,
       bool expected_credentials_change_fired,
       int expected_error_message,
-      const CComPtr<ICredentialProviderCredential>& local_testing_cred);
+      const Microsoft::WRL::ComPtr<ICredentialProviderCredential>&
+          local_testing_cred);
   HRESULT ReportLogonProcessResult(
-      const CComPtr<ICredentialProviderCredential>& local_testing_cred);
+      const Microsoft::WRL::ComPtr<ICredentialProviderCredential>&
+          local_testing_cred);
 
  private:
   HRESULT InternalInitializeProvider(
       const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in,
       DWORD* count);
   HRESULT ApplyProviderFilter(
-      const CComPtr<ICredentialProvider>& provider,
+      const Microsoft::WRL::ComPtr<ICredentialProvider>& provider,
       const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in,
       CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_out,
       HRESULT* update_remote_credentials_hr);
@@ -193,14 +197,14 @@
   base::string16 sid_locking_workstation_;
 
   // Reference to the provider that is created and owned by this class.
-  CComPtr<ICredentialProvider> gaia_provider_;
+  Microsoft::WRL::ComPtr<ICredentialProvider> gaia_provider_;
 
   // Reference to the credential in provider that is being tested by this class.
   // This member is kept so that it can be automatically released on destruction
   // of the test if the test did not explicitly release it. This allows us to
   // write less boiler plate test code and ensures that proper destruction order
   // of the credentials is respected.
-  CComPtr<ICredentialProviderCredential> testing_cred_;
+  Microsoft::WRL::ComPtr<ICredentialProviderCredential> testing_cred_;
 
   // Keeps track of whether a logon process has started for |testing_cred_|.
   // Testers who do not explicitly call FinishLogonProcess before the end of
diff --git a/chrome/installer/util/copy_tree_work_item.cc b/chrome/installer/util/copy_tree_work_item.cc
index 4dd39a73..9dcf4b2 100644
--- a/chrome/installer/util/copy_tree_work_item.cc
+++ b/chrome/installer/util/copy_tree_work_item.cc
@@ -126,14 +126,25 @@
   }
 }
 
+// static
 bool CopyTreeWorkItem::IsFileInUse(const base::FilePath& path) {
   if (!base::PathExists(path))
     return false;
 
-  HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS,
-                               NULL, NULL, OPEN_EXISTING, NULL, NULL);
-  if (handle  == INVALID_HANDLE_VALUE)
+  // A running executable is open with exclusive write access, so attempting to
+  // write to it will fail with a sharing violation. A more precise method would
+  // be to open the file with DELETE access and attempt to set the delete
+  // disposition on the handle. This would fail if the file was mapped into a
+  // process's address space, but succeed otherwise. This seems like overkill,
+  // however.
+  HANDLE handle =
+      ::CreateFile(path.value().c_str(), FILE_WRITE_DATA,
+                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                   nullptr, OPEN_EXISTING, 0, nullptr);
+  if (handle == INVALID_HANDLE_VALUE) {
+    DPCHECK(::GetLastError() == ERROR_SHARING_VIOLATION);
     return true;
+  }
 
   CloseHandle(handle);
   return false;
diff --git a/chrome/installer/util/copy_tree_work_item.h b/chrome/installer/util/copy_tree_work_item.h
index 56e5cf67..c69aa92 100644
--- a/chrome/installer/util/copy_tree_work_item.h
+++ b/chrome/installer/util/copy_tree_work_item.h
@@ -46,7 +46,7 @@
   void RollbackImpl() override;
 
   // Checks if the path specified is in use (and hence can not be deleted)
-  bool IsFileInUse(const base::FilePath& path);
+  static bool IsFileInUse(const base::FilePath& path);
 
   // Source path to copy files from.
   base::FilePath source_path_;
diff --git a/chrome/installer/util/copy_tree_work_item_unittest.cc b/chrome/installer/util/copy_tree_work_item_unittest.cc
index cea4012..4d1b94b 100644
--- a/chrome/installer/util/copy_tree_work_item_unittest.cc
+++ b/chrome/installer/util/copy_tree_work_item_unittest.cc
@@ -44,19 +44,6 @@
   file.close();
 }
 
-bool IsFileInUse(const base::FilePath& path) {
-  if (!base::PathExists(path))
-    return false;
-
-  HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS,
-                               NULL, NULL, OPEN_EXISTING, NULL, NULL);
-  if (handle  == INVALID_HANDLE_VALUE)
-    return true;
-
-  CloseHandle(handle);
-  return false;
-}
-
 // Simple function to read text from a file.
 std::wstring ReadTextFile(const std::wstring& filename) {
   WCHAR contents[64];
@@ -398,6 +385,7 @@
   alternate_to = alternate_to.AppendASCII("Alternate_To");
   base::CopyFile(exe_full_path, file_name_to);
   ASSERT_TRUE(base::PathExists(file_name_to));
+  ASSERT_FALSE(CopyTreeWorkItem::IsFileInUse(file_name_to));
 
   VLOG(1) << "copy ourself from " << exe_full_path.value()
           << " to " << file_name_to.value();
@@ -446,10 +434,10 @@
   work_item.reset(WorkItem::CreateCopyTreeWorkItem(
       file_name_from, file_name_to, temp_dir_.GetPath(),
       WorkItem::NEW_NAME_IF_IN_USE, alternate_to));
-  if (IsFileInUse(file_name_to))
+  if (CopyTreeWorkItem::IsFileInUse(file_name_to))
     base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2));
   // If file is still in use, the rest of the test will fail.
-  ASSERT_FALSE(IsFileInUse(file_name_to));
+  ASSERT_FALSE(CopyTreeWorkItem::IsFileInUse(file_name_to));
   EXPECT_TRUE(work_item->Do());
 
   // Get the path of backup file
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index c14d79d..048cdfb 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1426,7 +1426,6 @@
         "//chrome/browser/media/router:test_support",
         "//chrome/browser/resources/chromeos/autoclick:browser_tests",
         "//chrome/browser/resources/chromeos/chromevox:browser_tests",
-        "//chrome/browser/resources/chromeos/login:browser_tests",
         "//chrome/browser/resources/chromeos/select_to_speak:browser_tests",
         "//chrome/browser/resources/chromeos/switch_access:browser_tests",
         "//chrome/services/file_util/public/cpp:browser_tests",
@@ -1458,6 +1457,7 @@
       ]
       if (is_chromeos) {
         deps += [
+          "//chrome/browser/resources/chromeos/login:browser_tests",
           "//chromeos/components/help_app_ui:browser_tests_js",
           "//chromeos/components/media_app_ui:browser_tests_js",
         ]
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
index 3690ebc..5174bbd 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
@@ -12,7 +12,7 @@
 
 import org.chromium.chrome.browser.ntp.IncognitoNewTabPage;
 import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.suggestions.SiteSuggestion;
 import org.chromium.chrome.browser.suggestions.tile.TileSectionType;
@@ -101,6 +101,6 @@
         fakeAccountManager.addAccountHolderExplicitly(new AccountHolder.Builder(account).build());
         assertFalse(AccountManagerFacade.get().isUpdatePending().get());
         assertFalse(SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false));
+                ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false));
     }
 }
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 915b614..8722e24 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -67,11 +67,20 @@
 const base::Feature kCrostiniWebUIInstaller{"CrostiniWebUIInstaller",
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Deprecates the CryptAuth v1 DeviceSync flow. Note: During the first phase
+// of the v2 DeviceSync rollout, v1 and v2 DeviceSync run in parallel. This flag
+// is needed to deprecate the v1 service during the second phase of the rollout.
+// kCryptAuthV2DeviceSync should be enabled before this flag is flipped.
+const base::Feature kCryptAuthV1DeviceSyncDeprecate{
+    "CryptAuthV1DeviceSyncDeprecate", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables or disables using Cryptauth's GetDevicesActivityStatus API.
 const base::Feature kCryptAuthV2DeviceActivityStatus{
     "CryptAuthV2DeviceActivityStatus", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enables or disables the CryptAuth v2 DeviceSync flow.
+// Enables or disables the CryptAuth v2 DeviceSync flow. Regardless of this
+// flag, v1 DeviceSync will continue to operate until it is deprecated via the
+// feature flag kCryptAuthV1DeviceSyncDeprecate.
 const base::Feature kCryptAuthV2DeviceSync{"CryptAuthV2DeviceSync",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index b59fe29..2d17f750 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -41,6 +41,8 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCrostiniWebUIInstaller;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+extern const base::Feature kCryptAuthV1DeviceSyncDeprecate;
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCryptAuthV2DeviceActivityStatus;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCryptAuthV2DeviceSync;
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 7e247c6..800f4a7c 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -568,6 +568,7 @@
       "//testing/gmock",
       "//testing/gtest",
       "//ui/base",
+      "//ui/native_theme:native_theme",
       "//url",
     ]
 
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
index 8233f06..7882fa0 100644
--- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc
+++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -309,15 +309,19 @@
     std::unique_ptr<CollectUserDataOptions> collect_user_data_options,
     std::vector<WebsiteLoginFetcher::Login> logins) {
   for (const auto& login : logins) {
-    LoginChoice choice = {
-        base::NumberToString(collect_user_data_options->login_choices.size()),
-        login.username, login_option.preselection_priority()};
-    collect_user_data_options->login_choices.emplace_back(std::move(choice));
+    auto identifier =
+        base::NumberToString(collect_user_data_options->login_choices.size());
+    collect_user_data_options->login_choices.emplace_back(
+        identifier, login.username, login_option.sublabel(),
+        login_option.sublabel_accessibility_hint(),
+        login_option.preselection_priority(),
+        login_option.has_info_popup()
+            ? base::make_optional(login_option.info_popup())
+            : base::nullopt);
     login_details_map_.emplace(
-        choice.identifier,
-        std::make_unique<LoginDetails>(
-            login_option.choose_automatically_if_no_other_options(),
-            login_option.payload(), login));
+        identifier, std::make_unique<LoginDetails>(
+                        login_option.choose_automatically_if_no_other_options(),
+                        login_option.payload(), login));
   }
   ShowToUser(std::move(collect_user_data_options));
 }
@@ -577,9 +581,14 @@
             base::NumberToString(
                 collect_user_data_options->login_choices.size()),
             login_option.custom().label(),
+            login_option.sublabel(),
+            login_option.sublabel_accessibility_hint(),
             login_option.has_preselection_priority()
                 ? login_option.preselection_priority()
-                : -1};
+                : -1,
+            login_option.has_info_popup()
+                ? base::make_optional(login_option.info_popup())
+                : base::nullopt};
         collect_user_data_options->login_choices.emplace_back(
             std::move(choice));
         login_details_map_.emplace(
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 9e8f5df..4e0ea92 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -1206,6 +1206,14 @@
   optional bool request_payer_phone = 4;
 }
 
+// A generic read-only popup message.
+message InfoPopupProto {
+  // The title of the popup window.
+  optional string title = 1;
+  // The text of the popup window.
+  optional string text = 2;
+}
+
 message LoginDetailsProto {
   // A custom login option which will be handled by the backend, e.g.,
   // 'Guest checkout' or 'Log in with Google'.
@@ -1218,6 +1226,13 @@
   message LoginOptionPasswordManagerProto {}
 
   message LoginOptionProto {
+    // If set, an info icon will be shown that displays a popup when tapped.
+    optional InfoPopupProto info_popup = 6;
+
+    // The optional sublabel to display beneath the label.
+    optional string sublabel = 7;
+    optional string sublabel_accessibility_hint = 8;
+
     // If the option was chosen, this payload will be returned to the server.
     optional bytes payload = 1;
 
diff --git a/components/autofill_assistant/browser/user_data.cc b/components/autofill_assistant/browser/user_data.cc
index c518bdf..2ba170b 100644
--- a/components/autofill_assistant/browser/user_data.cc
+++ b/components/autofill_assistant/browser/user_data.cc
@@ -10,10 +10,19 @@
 
 namespace autofill_assistant {
 
-LoginChoice::LoginChoice(const std::string& id,
-                         const std::string& text,
-                         int priority)
-    : identifier(id), label(text), preselect_priority(priority) {}
+LoginChoice::LoginChoice(const std::string& _identifier,
+                         const std::string& _label,
+                         const std::string& _sublabel,
+                         const std::string& _sublabel_accessibility_hint,
+                         int _preselect_priority,
+                         const base::Optional<InfoPopupProto>& _info_popup)
+    : identifier(_identifier),
+      label(_label),
+      sublabel(_sublabel),
+      sublabel_accessibility_hint(_sublabel_accessibility_hint),
+      preselect_priority(_preselect_priority),
+      info_popup(_info_popup) {}
+LoginChoice::LoginChoice(const LoginChoice& another) = default;
 LoginChoice::~LoginChoice() = default;
 
 UserData::UserData() = default;
diff --git a/components/autofill_assistant/browser/user_data.h b/components/autofill_assistant/browser/user_data.h
index 9337f3e..4b1815d 100644
--- a/components/autofill_assistant/browser/user_data.h
+++ b/components/autofill_assistant/browser/user_data.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/optional.h"
 #include "components/autofill_assistant/browser/service.pb.h"
 #include "components/autofill_assistant/browser/user_action.h"
 
@@ -38,15 +39,27 @@
 // Represents a concrete login choice in the UI, e.g., 'Guest checkout' or
 // a particular Chrome PWM login account.
 struct LoginChoice {
-  LoginChoice(const std::string& id, const std::string& text, int priority);
+  LoginChoice(const std::string& id,
+              const std::string& label,
+              const std::string& sublabel,
+              const std::string& sublabel_accessibility_hint,
+              int priority,
+              const base::Optional<InfoPopupProto>& info_popup);
+  LoginChoice(const LoginChoice& another);
   ~LoginChoice();
 
   // Uniquely identifies this login choice.
   std::string identifier;
   // The label to display to the user.
   std::string label;
+  // The sublabel to display to the user.
+  std::string sublabel;
+  // The a11y hint for |sublabel|.
+  std::string sublabel_accessibility_hint;
   // The priority to pre-select this choice (-1 == not set/automatic).
   int preselect_priority = -1;
+  // The popup to show to provide more information about this login choice.
+  base::Optional<InfoPopupProto> info_popup;
 };
 
 // Struct for holding the user data.
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc
index 2c4d92be..2ae3cb5b 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -319,26 +319,10 @@
   }
 
 #if defined(OS_CHROMEOS)
-  if (chromeos::features::IsSplitSettingsSyncEnabled()) {
-    if (!disabled_types.Has(syncer::OS_PREFERENCES)) {
-      controllers.push_back(
-          std::make_unique<SyncableServiceBasedModelTypeController>(
-              syncer::OS_PREFERENCES,
-              sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
-              sync_client_->GetSyncableServiceForType(syncer::OS_PREFERENCES),
-              dump_stack));
-    }
-    if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) {
-      controllers.push_back(
-          std::make_unique<SyncableServiceBasedModelTypeController>(
-              syncer::OS_PRIORITY_PREFERENCES,
-              sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
-              sync_client_->GetSyncableServiceForType(
-                  syncer::OS_PRIORITY_PREFERENCES),
-              dump_stack));
-    }
-  }
-  if (!disabled_types.Has(syncer::PRINTERS)) {
+  // When SplitSettingsSync is enabled the controller is created in
+  // ChromeSyncClient so it can live near other printer-related sync code.
+  if (!disabled_types.Has(syncer::PRINTERS) &&
+      !chromeos::features::IsSplitSettingsSyncEnabled()) {
     controllers.push_back(
         CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS));
   }
diff --git a/components/dom_distiller/content/browser/BUILD.gn b/components/dom_distiller/content/browser/BUILD.gn
index cc183878..aa6f3a99 100644
--- a/components/dom_distiller/content/browser/BUILD.gn
+++ b/components/dom_distiller/content/browser/BUILD.gn
@@ -16,7 +16,6 @@
     "distiller_javascript_utils.h",
     "distiller_page_web_contents.cc",
     "distiller_page_web_contents.h",
-    "distiller_ui_handle.h",
     "dom_distiller_viewer_source.cc",
     "dom_distiller_viewer_source.h",
     "web_contents_main_frame_observer.cc",
diff --git a/components/dom_distiller/content/browser/distillability_driver.cc b/components/dom_distiller/content/browser/distillability_driver.cc
index 683917f..75606c3 100644
--- a/components/dom_distiller/content/browser/distillability_driver.cc
+++ b/components/dom_distiller/content/browser/distillability_driver.cc
@@ -63,12 +63,6 @@
       std::move(receiver));
 }
 
-void DistillabilityDriver::AddObserver(DistillabilityObserver* observer) {
-  if (!observers_.HasObserver(observer)) {
-    observers_.AddObserver(observer);
-  }
-}
-
 void DistillabilityDriver::OnDistillability(
     const DistillabilityResult& result) {
   latest_result_ = result;
diff --git a/components/dom_distiller/content/browser/distillability_driver.h b/components/dom_distiller/content/browser/distillability_driver.h
index 516311f..272eab9 100644
--- a/components/dom_distiller/content/browser/distillability_driver.h
+++ b/components/dom_distiller/content/browser/distillability_driver.h
@@ -28,7 +28,9 @@
   void CreateDistillabilityService(
       mojo::PendingReceiver<mojom::DistillabilityService> receiver);
 
-  void AddObserver(DistillabilityObserver* observer);
+  base::ObserverList<DistillabilityObserver>* GetObserverList() {
+    return &observers_;
+  }
   base::Optional<DistillabilityResult> GetLatestResult() const {
     return latest_result_;
   }
diff --git a/components/dom_distiller/content/browser/distillable_page_utils.cc b/components/dom_distiller/content/browser/distillable_page_utils.cc
index b666b154..24ac793 100644
--- a/components/dom_distiller/content/browser/distillable_page_utils.cc
+++ b/components/dom_distiller/content/browser/distillable_page_utils.cc
@@ -59,13 +59,34 @@
 
 void AddObserver(content::WebContents* web_contents,
                  DistillabilityObserver* observer) {
+  DCHECK(observer);
   CHECK(web_contents);
   DistillabilityDriver::CreateForWebContents(web_contents);
 
   DistillabilityDriver* driver =
       DistillabilityDriver::FromWebContents(web_contents);
   CHECK(driver);
-  driver->AddObserver(observer);
+  base::ObserverList<DistillabilityObserver>* observer_list =
+      driver->GetObserverList();
+  if (!observer_list->HasObserver(observer)) {
+    observer_list->AddObserver(observer);
+  }
+}
+
+void RemoveObserver(content::WebContents* web_contents,
+                    DistillabilityObserver* observer) {
+  DCHECK(observer);
+  CHECK(web_contents);
+  DistillabilityDriver::CreateForWebContents(web_contents);
+
+  DistillabilityDriver* driver =
+      DistillabilityDriver::FromWebContents(web_contents);
+  CHECK(driver);
+  base::ObserverList<DistillabilityObserver>* observer_list =
+      driver->GetObserverList();
+  if (observer_list->HasObserver(observer)) {
+    observer_list->RemoveObserver(observer);
+  }
 }
 
 base::Optional<DistillabilityResult> GetLatestResult(
diff --git a/components/dom_distiller/content/browser/distillable_page_utils.h b/components/dom_distiller/content/browser/distillable_page_utils.h
index 3754622..599a7ab 100644
--- a/components/dom_distiller/content/browser/distillable_page_utils.h
+++ b/components/dom_distiller/content/browser/distillable_page_utils.h
@@ -40,11 +40,14 @@
   virtual void OnResult(const DistillabilityResult& result) = 0;
 };
 
-// Set the delegate to receive the result of whether the page is distillable.
+// Add/remove objects to the list of observers to notify when the distillability
+// service returns a result.
 //
-// |web_contents| must be non-null.
+// |web_contents| and |observer| must both be non-null.
 void AddObserver(content::WebContents* web_contents,
                  DistillabilityObserver* observer);
+void RemoveObserver(content::WebContents* web_contents,
+                    DistillabilityObserver* observer);
 
 base::Optional<DistillabilityResult> GetLatestResult(
     content::WebContents* web_contents);
diff --git a/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc b/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
index 9d993ad87..faf05be 100644
--- a/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
+++ b/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
@@ -4,21 +4,13 @@
 
 #include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h"
 
-#include <memory>
-#include <utility>
-
-#include "base/metrics/user_metrics.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
-#include "components/dom_distiller/core/feedback_reporter.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
 namespace dom_distiller {
 
 DistillerJavaScriptServiceImpl::DistillerJavaScriptServiceImpl(
-    content::RenderFrameHost* render_frame_host,
     DistillerUIHandle* distiller_ui_handle)
-    : render_frame_host_(render_frame_host),
-      distiller_ui_handle_(distiller_ui_handle) {}
+    : distiller_ui_handle_(distiller_ui_handle) {}
 
 DistillerJavaScriptServiceImpl::~DistillerJavaScriptServiceImpl() {}
 
@@ -26,18 +18,16 @@
   if (!distiller_ui_handle_) {
     return;
   }
-  content::WebContents* contents =
-      content::WebContents::FromRenderFrameHost(render_frame_host_);
-  distiller_ui_handle_->OpenSettings(contents);
+
+  distiller_ui_handle_->OpenSettings();
 }
 
 void CreateDistillerJavaScriptService(
     DistillerUIHandle* distiller_ui_handle,
-    mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver,
-    content::RenderFrameHost* render_frame_host) {
-  mojo::MakeSelfOwnedReceiver(std::make_unique<DistillerJavaScriptServiceImpl>(
-                                  render_frame_host, distiller_ui_handle),
-                              std::move(receiver));
+    mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver) {
+  mojo::MakeSelfOwnedReceiver(
+      std::make_unique<DistillerJavaScriptServiceImpl>(distiller_ui_handle),
+      std::move(receiver));
 }
 
 }  // namespace dom_distiller
diff --git a/components/dom_distiller/content/browser/distiller_javascript_service_impl.h b/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
index 1bd75c26..b5c5dd8 100644
--- a/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
+++ b/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
@@ -6,8 +6,8 @@
 #define COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_JAVASCRIPT_SERVICE_IMPL_H_
 
 #include "base/macros.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
 #include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h"
+#include "components/dom_distiller/core/distiller_ui_handle.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 
 namespace dom_distiller {
@@ -16,8 +16,7 @@
 class DistillerJavaScriptServiceImpl
     : public mojom::DistillerJavaScriptService {
  public:
-  DistillerJavaScriptServiceImpl(content::RenderFrameHost* render_frame_host,
-                                 DistillerUIHandle* distiller_ui_handle);
+  DistillerJavaScriptServiceImpl(DistillerUIHandle* distiller_ui_handle);
   ~DistillerJavaScriptServiceImpl() override;
 
   // Mojo mojom::DistillerJavaScriptService implementation.
@@ -26,7 +25,6 @@
   void HandleDistillerOpenSettingsCall() override;
 
  private:
-  content::RenderFrameHost* render_frame_host_;
   DistillerUIHandle* distiller_ui_handle_;
 
   DISALLOW_COPY_AND_ASSIGN(DistillerJavaScriptServiceImpl);
@@ -35,8 +33,7 @@
 // static
 void CreateDistillerJavaScriptService(
     DistillerUIHandle* distiller_ui_handle,
-    mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver,
-    content::RenderFrameHost* render_frame_host);
+    mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver);
 
 }  // namespace dom_distiller
 
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc b/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
index d9208b5..6f57f7b4 100644
--- a/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
+++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
@@ -18,9 +18,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h"
 #include "components/dom_distiller/content/browser/distiller_javascript_utils.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
 #include "components/dom_distiller/content/common/mojom/distiller_page_notifier_service.mojom.h"
 #include "components/dom_distiller/core/distilled_page_prefs.h"
 #include "components/dom_distiller/core/dom_distiller_request_view_base.h"
@@ -41,7 +39,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/url_util.h"
 #include "net/url_request/url_request.h"
-#include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -56,8 +53,7 @@
  public:
   RequestViewerHandle(content::WebContents* web_contents,
                       const GURL& expected_url,
-                      DistilledPagePrefs* distilled_page_prefs,
-                      DistillerUIHandle* ui_handle);
+                      DistilledPagePrefs* distilled_page_prefs);
   ~RequestViewerHandle() override;
 
   // content::WebContentsObserver implementation:
@@ -66,10 +62,6 @@
   void RenderProcessGone(base::TerminationStatus status) override;
   void WebContentsDestroyed() override;
   void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override;
-  void OnInterfaceRequestFromFrame(
-      content::RenderFrameHost* render_frame_host,
-      const std::string& interface_name,
-      mojo::ScopedMessagePipeHandle* interface_pipe) override;
 
  private:
   // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't
@@ -91,30 +83,17 @@
   // Temporary store of pending JavaScript if the page isn't ready to receive
   // data from distillation.
   std::string buffer_;
-
-  // An object for accessing chrome-specific UI controls including external
-  // feedback and opening the distiller settings. Guaranteed to outlive this
-  // object.
-  DistillerUIHandle* distiller_ui_handle_;
-
-  service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>
-      frame_interfaces_;
 };
 
 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
     content::WebContents* web_contents,
     const GURL& expected_url,
-    DistilledPagePrefs* distilled_page_prefs,
-    DistillerUIHandle* ui_handle)
+    DistilledPagePrefs* distilled_page_prefs)
     : DomDistillerRequestViewBase(distilled_page_prefs),
       expected_url_(expected_url),
-      waiting_for_page_ready_(true),
-      distiller_ui_handle_(ui_handle) {
+      waiting_for_page_ready_(true) {
   content::WebContentsObserver::Observe(web_contents);
   distilled_page_prefs_->AddObserver(this);
-
-  frame_interfaces_.AddInterface(
-      base::Bind(&CreateDistillerJavaScriptService, distiller_ui_handle_));
 }
 
 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
@@ -213,21 +192,10 @@
   // No need to Cancel() here.
 }
 
-void DomDistillerViewerSource::RequestViewerHandle::OnInterfaceRequestFromFrame(
-    content::RenderFrameHost* render_frame_host,
-    const std::string& interface_name,
-    mojo::ScopedMessagePipeHandle* interface_pipe) {
-  frame_interfaces_.TryBindInterface(interface_name, interface_pipe,
-                                     render_frame_host);
-}
-
 DomDistillerViewerSource::DomDistillerViewerSource(
     DomDistillerServiceInterface* dom_distiller_service,
-    const std::string& scheme,
-    std::unique_ptr<DistillerUIHandle> ui_handle)
-    : scheme_(scheme),
-      dom_distiller_service_(dom_distiller_service),
-      distiller_ui_handle_(std::move(ui_handle)) {}
+    const std::string& scheme)
+    : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {}
 
 DomDistillerViewerSource::~DomDistillerViewerSource() {}
 
@@ -277,8 +245,7 @@
   }
   RequestViewerHandle* request_viewer_handle =
       new RequestViewerHandle(web_contents, request_url,
-                              dom_distiller_service_->GetDistilledPagePrefs(),
-                              distiller_ui_handle_.get());
+                              dom_distiller_service_->GetDistilledPagePrefs());
   std::unique_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
       dom_distiller_service_, request_url, request_viewer_handle,
       web_contents->GetContainerBounds().size());
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source.h b/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
index 85f1899..f011c182 100644
--- a/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
+++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
@@ -10,7 +10,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
 
@@ -23,8 +22,7 @@
 class DomDistillerViewerSource : public content::URLDataSource {
  public:
   DomDistillerViewerSource(DomDistillerServiceInterface* dom_distiller_service,
-                           const std::string& scheme,
-                           std::unique_ptr<DistillerUIHandle> ui_handle);
+                           const std::string& scheme);
   ~DomDistillerViewerSource() override;
 
   class RequestViewerHandle;
@@ -52,10 +50,6 @@
   // the list of articles.
   DomDistillerServiceInterface* dom_distiller_service_;
 
-  // An object for accessing chrome-specific UI controls including external
-  // feedback and opening the distiller settings.
-  std::unique_ptr<DistillerUIHandle> distiller_ui_handle_;
-
   DISALLOW_COPY_AND_ASSIGN(DomDistillerViewerSource);
 };
 
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc b/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc
index 5238069e..7da63c81 100644
--- a/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc
+++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc
@@ -14,7 +14,7 @@
 class DomDistillerViewerSourceTest : public testing::Test {
  public:
   void SetUp() override {
-    source_.reset(new DomDistillerViewerSource(nullptr, kTestScheme, nullptr));
+    source_.reset(new DomDistillerViewerSource(nullptr, kTestScheme));
   }
 
  protected:
diff --git a/components/dom_distiller/content/renderer/distiller_native_javascript.cc b/components/dom_distiller/content/renderer/distiller_native_javascript.cc
index e6a4ce4..0c1831e 100644
--- a/components/dom_distiller/content/renderer/distiller_native_javascript.cc
+++ b/components/dom_distiller/content/renderer/distiller_native_javascript.cc
@@ -12,7 +12,7 @@
 #include "content/public/renderer/render_frame.h"
 #include "gin/arguments.h"
 #include "gin/function_template.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/web/blink.h"
 #include "v8/include/v8.h"
 
@@ -66,7 +66,7 @@
 
 void DistillerNativeJavaScript::EnsureServiceConnected() {
   if (!distiller_js_service_) {
-    render_frame_->GetRemoteInterfaces()->GetInterface(
+    render_frame_->GetBrowserInterfaceBroker()->GetInterface(
         distiller_js_service_.BindNewPipeAndPassReceiver());
   }
 }
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn
index 4a681d84..14bf4db 100644
--- a/components/dom_distiller/core/BUILD.gn
+++ b/components/dom_distiller/core/BUILD.gn
@@ -20,6 +20,7 @@
     "distiller.h",
     "distiller_page.cc",
     "distiller_page.h",
+    "distiller_ui_handle.h",
     "distiller_url_fetcher.cc",
     "distiller_url_fetcher.h",
     "dom_distiller_constants.cc",
diff --git a/components/dom_distiller/content/browser/distiller_ui_handle.h b/components/dom_distiller/core/distiller_ui_handle.h
similarity index 62%
rename from components/dom_distiller/content/browser/distiller_ui_handle.h
rename to components/dom_distiller/core/distiller_ui_handle.h
index 36e58ff..6ecb7a6 100644
--- a/components/dom_distiller/content/browser/distiller_ui_handle.h
+++ b/components/dom_distiller/core/distiller_ui_handle.h
@@ -2,11 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_
-#define COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_
+#ifndef COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_
+#define COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_
 
 #include "base/macros.h"
-#include "content/public/browser/web_contents.h"
 #include "url/gurl.h"
 
 namespace dom_distiller {
@@ -19,7 +18,7 @@
   virtual ~DistillerUIHandle() {}
 
   // Open the UI settings for dom distiller.
-  virtual void OpenSettings(content::WebContents* web_contents) = 0;
+  virtual void OpenSettings() = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DistillerUIHandle);
@@ -27,4 +26,4 @@
 
 }  // namespace dom_distiller
 
-#endif  // COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_
+#endif  // COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_
diff --git a/components/dom_distiller/core/dom_distiller_service.cc b/components/dom_distiller/core/dom_distiller_service.cc
index 34abda8..2311459c 100644
--- a/components/dom_distiller/core/dom_distiller_service.cc
+++ b/components/dom_distiller/core/dom_distiller_service.cc
@@ -35,11 +35,13 @@
 DomDistillerService::DomDistillerService(
     std::unique_ptr<DistillerFactory> distiller_factory,
     std::unique_ptr<DistillerPageFactory> distiller_page_factory,
-    std::unique_ptr<DistilledPagePrefs> distilled_page_prefs)
+    std::unique_ptr<DistilledPagePrefs> distilled_page_prefs,
+    std::unique_ptr<DistillerUIHandle> distiller_ui_handle)
     : content_store_(new InMemoryContentStore(kDefaultMaxNumCachedEntries)),
       distiller_factory_(std::move(distiller_factory)),
       distiller_page_factory_(std::move(distiller_page_factory)),
-      distilled_page_prefs_(std::move(distilled_page_prefs)) {}
+      distilled_page_prefs_(std::move(distilled_page_prefs)),
+      distiller_ui_handle_(std::move(distiller_ui_handle)) {}
 
 DomDistillerService::~DomDistillerService() {}
 
@@ -123,4 +125,8 @@
   return distilled_page_prefs_.get();
 }
 
+DistillerUIHandle* DomDistillerService::GetDistillerUIHandle() {
+  return distiller_ui_handle_.get();
+}
+
 }  // namespace dom_distiller
diff --git a/components/dom_distiller/core/dom_distiller_service.h b/components/dom_distiller/core/dom_distiller_service.h
index bb9d000..2cf44ba 100644
--- a/components/dom_distiller/core/dom_distiller_service.h
+++ b/components/dom_distiller/core/dom_distiller_service.h
@@ -14,6 +14,7 @@
 #include "components/dom_distiller/core/article_entry.h"
 #include "components/dom_distiller/core/distilled_page_prefs.h"
 #include "components/dom_distiller/core/distiller_page.h"
+#include "components/dom_distiller/core/distiller_ui_handle.h"
 
 class GURL;
 
@@ -53,6 +54,10 @@
   // DomDistillerService.
   virtual DistilledPagePrefs* GetDistilledPagePrefs() = 0;
 
+  // Returns the DistillerUIHandle owned by the instance of
+  // DomDistillerService.
+  virtual DistillerUIHandle* GetDistillerUIHandle() = 0;
+
  protected:
   DomDistillerServiceInterface() {}
 
@@ -66,7 +71,8 @@
   DomDistillerService(
       std::unique_ptr<DistillerFactory> distiller_factory,
       std::unique_ptr<DistillerPageFactory> distiller_page_factory,
-      std::unique_ptr<DistilledPagePrefs> distilled_page_prefs);
+      std::unique_ptr<DistilledPagePrefs> distilled_page_prefs,
+      std::unique_ptr<DistillerUIHandle> distiller_ui_handle);
   ~DomDistillerService() override;
 
   // DomDistillerServiceInterface implementation.
@@ -79,6 +85,7 @@
   std::unique_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle(
       std::unique_ptr<SourcePageHandle> handle) override;
   DistilledPagePrefs* GetDistilledPagePrefs() override;
+  DistillerUIHandle* GetDistillerUIHandle() override;
 
  private:
   void CancelTask(TaskTracker* task);
@@ -99,6 +106,10 @@
   std::unique_ptr<DistillerPageFactory> distiller_page_factory_;
   std::unique_ptr<DistilledPagePrefs> distilled_page_prefs_;
 
+  // An object for accessing chrome-specific UI controls including external
+  // feedback and opening the distiller settings.
+  std::unique_ptr<DistillerUIHandle> distiller_ui_handle_;
+
   typedef std::vector<std::unique_ptr<TaskTracker>> TaskList;
   TaskList tasks_;
 
diff --git a/components/dom_distiller/core/dom_distiller_service_unittest.cc b/components/dom_distiller/core/dom_distiller_service_unittest.cc
index 24f8b0d..b2efb10 100644
--- a/components/dom_distiller/core/dom_distiller_service_unittest.cc
+++ b/components/dom_distiller/core/dom_distiller_service_unittest.cc
@@ -68,7 +68,8 @@
     service_.reset(new DomDistillerService(
         std::unique_ptr<DistillerFactory>(distiller_factory_),
         std::unique_ptr<DistillerPageFactory>(distiller_page_factory_),
-        std::unique_ptr<DistilledPagePrefs>()));
+        /* distilled_page_prefs */ nullptr,
+        /* distiller_ui_handle */ nullptr));
   }
 
   void TearDown() override {
diff --git a/components/dom_distiller/core/viewer_unittest.cc b/components/dom_distiller/core/viewer_unittest.cc
index 20285cd..a03ec3c2 100644
--- a/components/dom_distiller/core/viewer_unittest.cc
+++ b/components/dom_distiller/core/viewer_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/dom_distiller/core/viewer.h"
 
 #include "components/dom_distiller/core/distilled_page_prefs.h"
+#include "components/dom_distiller/core/distiller_ui_handle.h"
 #include "components/dom_distiller/core/dom_distiller_service.h"
 #include "components/dom_distiller/core/task_tracker.h"
 #include "components/dom_distiller/core/url_constants.h"
@@ -57,6 +58,7 @@
     return std::unique_ptr<DistillerPage>();
   }
   DistilledPagePrefs* GetDistilledPagePrefs() override;
+  DistillerUIHandle* GetDistillerUIHandle() override;
 };
 
 class DomDistillerViewerTest : public testing::Test {
@@ -113,6 +115,10 @@
   return nullptr;
 }
 
+DistillerUIHandle* TestDomDistillerService::GetDistillerUIHandle() {
+  return nullptr;
+}
+
 TEST_F(DomDistillerViewerTest, TestGetDistilledPageThemeJsOutput) {
   std::string kDarkJs = "useTheme('dark');";
   std::string kSepiaJs = "useTheme('sepia');";
diff --git a/components/dom_distiller/standalone/content_extractor_browsertest.cc b/components/dom_distiller/standalone/content_extractor_browsertest.cc
index b0c9284..44bf091 100644
--- a/components/dom_distiller/standalone/content_extractor_browsertest.cc
+++ b/components/dom_distiller/standalone/content_extractor_browsertest.cc
@@ -164,7 +164,8 @@
 
   return std::make_unique<DomDistillerService>(
       std::move(distiller_factory), std::move(distiller_page_factory),
-      std::make_unique<DistilledPagePrefs>(pref_service));
+      std::make_unique<DistilledPagePrefs>(pref_service),
+      /* distiller_ui_handle */ nullptr);
 }
 
 void AddComponentsTestResources() {
diff --git a/components/drive/BUILD.gn b/components/drive/BUILD.gn
index 9b8cb960..dec1fd2 100644
--- a/components/drive/BUILD.gn
+++ b/components/drive/BUILD.gn
@@ -17,26 +17,10 @@
     "drive_uploader.h",
     "event_logger.cc",
     "event_logger.h",
-    "file_change.cc",
-    "file_change.h",
     "file_errors.cc",
     "file_errors.h",
     "file_system_core_util.cc",
     "file_system_core_util.h",
-    "file_system_metadata.cc",
-    "file_system_metadata.h",
-    "file_write_watcher.cc",
-    "file_write_watcher.h",
-    "job_list.cc",
-    "job_list.h",
-    "job_queue.cc",
-    "job_queue.h",
-    "job_scheduler.cc",
-    "job_scheduler.h",
-    "local_file_reader.cc",
-    "local_file_reader.h",
-    "resource_entry_conversion.cc",
-    "resource_entry_conversion.h",
     "resource_metadata_storage.cc",
     "resource_metadata_storage.h",
     "service/drive_api_service.cc",
@@ -46,17 +30,11 @@
   ]
   deps = [
     "//base",
-    "//base:i18n",
     "//components/invalidation/public",
     "//components/keyed_service/core",
-    "//components/prefs",
-
-    # TODO(lukasza): Remove this dependency (see DEPS file for more info).
-    "//content/public/browser",
-    "//google_apis",
     "//google_apis/drive",
-    "//net",
     "//services/device/public/mojom",
+    "//services/network/public/cpp:cpp",
     "//third_party/cacheinvalidation",
     "//third_party/leveldatabase",
     "//third_party/re2",
@@ -84,11 +62,7 @@
   ]
   deps = [
     ":drive",
-    ":proto",
     "//base",
-    "//components/prefs:test_support",
-    "//content/test:test_support",
-    "//google_apis:test_support",
     "//google_apis/drive:test_support",
     "//net:net",
   ]
@@ -97,56 +71,14 @@
 if (is_chromeos) {
   source_set("drive_chromeos") {
     sources = [
-      "chromeos/change_list_processor.cc",
-      "chromeos/change_list_processor.h",
-      "chromeos/drive_file_util.cc",
-      "chromeos/drive_file_util.h",
-      "chromeos/drive_operation_queue.h",
-      "chromeos/file_cache.cc",
-      "chromeos/file_cache.h",
-      "chromeos/file_system_interface.cc",
-      "chromeos/file_system_interface.h",
-      "chromeos/file_system_observer.h",
-      "chromeos/remove_stale_cache_files.cc",
-      "chromeos/remove_stale_cache_files.h",
-      "chromeos/resource_metadata.cc",
-      "chromeos/resource_metadata.h",
       "chromeos/search_metadata.cc",
       "chromeos/search_metadata.h",
-      "chromeos/team_drive.cc",
-      "chromeos/team_drive.h",
-      "chromeos/team_drive_list_observer.h",
     ]
     deps = [
       ":drive",
       "//base",
       "//base:i18n",
-      "//components/prefs",
-      "//google_apis",
-      "//google_apis/drive",
       "//net",
     ]
-    public_deps = [
-      ":proto",
-    ]
-  }
-  static_library("test_support_chromeos") {
-    testonly = true
-    sources = [
-      "chromeos/drive_test_util.cc",
-      "chromeos/drive_test_util.h",
-      "chromeos/fake_free_disk_space_getter.cc",
-      "chromeos/fake_free_disk_space_getter.h",
-    ]
-    deps = [
-      ":drive",
-      ":drive_chromeos",
-      ":proto",
-      "//base",
-      "//components/prefs:test_support",
-      "//content/test:test_support",
-      "//google_apis:test_support",
-      "//google_apis/drive:test_support",
-    ]
   }
 }
diff --git a/components/drive/DEPS b/components/drive/DEPS
index 851b225..5885c14 100644
--- a/components/drive/DEPS
+++ b/components/drive/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+components/invalidation",
   "+components/keyed_service",
-  "+components/prefs",
   "+google_apis",
   "+google/cacheinvalidation/types.pb.h",
   "+mojo/public",
@@ -16,37 +15,8 @@
 specific_include_rules = {
   # The following test dependencies should be removed to fully componentize this
   # directory. crbug.com/498951
-  "drive_test_util\.h": [
-    "+content/public/test/test_utils.h",
-  ],
-
-  # The following test dependencies should be removed to fully componentize this
-  # directory. crbug.com/498951
-  r"(change_list_processor_unittest\.cc"
-  r"|drive_file_util_unittest\.cc"
-  r"|file_cache_unittest\.cc"
-  r"|file_system_core_util_unittest\.cc"
-  r"|file_write_watcher_unittest\.cc"
-  r"|job_scheduler_unittest\.cc"
-  r"|remove_stale_cache_files_unittest\.cc"
-  r"|resource_metadata_storage_unittest\.cc"
-  r"|resource_metadata_unittest\.cc"
-  r"|search_metadata_unittest\.cc"
-  r")": [
+  "resource_metadata_storage_unittest\.cc": [
     "+content/public/test/browser_task_environment.h",
-  ],
-
-  # The following test dependencies should be removed to fully componentize this
-  # directory. crbug.com/498951
-  r"(drive_uploader\.cc"
-  r"|file_write_watcher_unittest\.cc"
-  r")": [
-    "+content/public/browser/browser_thread.h",
-  ],
-
-  # The dependency below is ok and can stay here for the long-term, because it
-  # is guarded by #if defined(OS_CHROMEOS) in the source code.
-  "file_cache\.h": [
-    "+third_party/cros_system_api/constants/cryptohome.h",
+    "+content/public/test/test_utils.h",
   ],
 }
diff --git a/components/drive/change_list_processor_unittest.cc b/components/drive/change_list_processor_unittest.cc
deleted file mode 100644
index 4213205..0000000
--- a/components/drive/change_list_processor_unittest.cc
+++ /dev/null
@@ -1,803 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/change_list_processor.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <memory>
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_change.h"
-#include "components/drive/file_system_core_util.h"
-#include "content/public/test/browser_task_environment.h"
-#include "google_apis/drive/drive_api_parser.h"
-#include "google_apis/drive/test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-
-namespace {
-
-constexpr char kBaseStartPageToken[] = "123";
-constexpr char kRootId[] = "fake_root";
-
-enum FileOrDirectory {
-  FILE,
-  DIRECTORY,
-};
-
-struct EntryExpectation {
-  std::string path;
-  std::string id;
-  std::string parent_id;
-  FileOrDirectory type;
-};
-
-// Returns a basic change list which contains some files and directories.
-std::vector<std::unique_ptr<ChangeList>> CreateBaseChangeList() {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  // Add directories to the change list.
-  ResourceEntry directory;
-  directory.mutable_file_info()->set_is_directory(true);
-
-  directory.set_title("Directory 1");
-  directory.set_resource_id("1_folder_resource_id");
-  change_lists[0]->mutable_entries()->push_back(directory);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  directory.set_title("Sub Directory Folder");
-  directory.set_resource_id("sub_dir_folder_resource_id");
-  change_lists[0]->mutable_entries()->push_back(directory);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "1_folder_resource_id");
-
-  directory.set_title("Sub Sub Directory Folder");
-  directory.set_resource_id("sub_sub_directory_folder_id");
-  change_lists[0]->mutable_entries()->push_back(directory);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "sub_dir_folder_resource_id");
-
-  directory.set_title("Directory 2 excludeDir-test");
-  directory.set_resource_id("sub_dir_folder_2_self_link");
-  change_lists[0]->mutable_entries()->push_back(directory);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  // Add files to the change list.
-  ResourceEntry file;
-
-  file.set_title("File 1.txt");
-  file.set_resource_id("2_file_resource_id");
-  change_lists[0]->mutable_entries()->push_back(file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  file.set_title("SubDirectory File 1.txt");
-  file.set_resource_id("subdirectory_file_1_id");
-  Property* const property = file.mutable_new_properties()->Add();
-  property->set_key("hello");
-  property->set_value("world");
-  change_lists[0]->mutable_entries()->push_back(file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "1_folder_resource_id");
-
-  file.set_title("Orphan File 1.txt");
-  file.set_resource_id("1_orphanfile_resource_id");
-  change_lists[0]->mutable_entries()->push_back(file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("");
-
-  change_lists[0]->set_new_start_page_token(kBaseStartPageToken);
-  return change_lists;
-}
-
-class ChangeListProcessorTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_TRUE(metadata_storage_->Initialize());
-
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-    ASSERT_TRUE(cache_->Initialize());
-
-    metadata_.reset(
-        new internal::ResourceMetadata(metadata_storage_.get(), cache_.get(),
-                                       base::ThreadTaskRunnerHandle::Get()));
-    ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
-  }
-
-  // Applies the |changes| to |metadata_| as a full resource list of
-  // start page token |kBaseStartPageToken|.
-  FileError ApplyFullResourceList(
-      std::vector<std::unique_ptr<ChangeList>> changes) {
-    ChangeListProcessor processor(util::kTeamDriveIdDefaultCorpus,
-                                  util::GetDriveMyDriveRootPath(),
-                                  metadata_.get(), nullptr);
-    return processor.ApplyUserChangeList(kBaseStartPageToken, kRootId,
-                                         std::move(changes),
-                                         false /* is_delta_update */);
-  }
-
-  // Applies |changes| to |metadata_| as a delta update. The |changes| are
-  // treated as user's changelists. Delta changelists should contain their
-  // start page token in themselves. |changede_team_drives| returns any team
-  // drives that were added or removed as part of the change list.
-  FileError ApplyUserChangeList(
-      std::vector<std::unique_ptr<ChangeList>> changes,
-      FileChange* changed_files,
-      FileChange* changed_team_drives) {
-    ChangeListProcessor processor(util::kTeamDriveIdDefaultCorpus,
-                                  util::GetDriveMyDriveRootPath(),
-                                  metadata_.get(), nullptr);
-    FileError error = processor.ApplyUserChangeList(kBaseStartPageToken,
-                                                    kRootId, std::move(changes),
-                                                    true /* is_delta_update */);
-    *changed_files = processor.changed_files();
-    *changed_team_drives = processor.changed_team_drives();
-    return error;
-  }
-
-  // Gets the resource entry for the path from |metadata_| synchronously.
-  // Returns null if the entry does not exist.
-  std::unique_ptr<ResourceEntry> GetResourceEntry(const std::string& path) {
-    std::unique_ptr<ResourceEntry> entry(new ResourceEntry);
-    FileError error = metadata_->GetResourceEntryByPath(
-        base::FilePath::FromUTF8Unsafe(path), entry.get());
-    if (error != FILE_ERROR_OK)
-      entry.reset();
-    return entry;
-  }
-
-  content::BrowserTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
-};
-
-}  // namespace
-
-TEST_F(ChangeListProcessorTest, ApplyFullResourceList) {
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  const EntryExpectation kExpected[] = {
-      // Root files
-      {"drive/root", kRootId, "", DIRECTORY},
-      {"drive/root/File 1.txt",
-          "2_file_resource_id", kRootId, FILE},
-      // Subdirectory files
-      {"drive/root/Directory 1",
-          "1_folder_resource_id", kRootId, DIRECTORY},
-      {"drive/root/Directory 1/SubDirectory File 1.txt",
-          "subdirectory_file_1_id", "1_folder_resource_id", FILE},
-      {"drive/root/Directory 2 excludeDir-test",
-          "sub_dir_folder_2_self_link", kRootId, DIRECTORY},
-      // Deeper
-      {"drive/root/Directory 1/Sub Directory Folder",
-          "sub_dir_folder_resource_id",
-          "1_folder_resource_id", DIRECTORY},
-      {"drive/root/Directory 1/Sub Directory Folder/Sub Sub Directory Folder",
-          "sub_sub_directory_folder_id",
-          "sub_dir_folder_resource_id", DIRECTORY},
-      // Orphan
-      {"drive/other/Orphan File 1.txt", "1_orphanfile_resource_id",
-           "", FILE},
-  };
-
-  for (size_t i = 0; i < base::size(kExpected); ++i) {
-    std::unique_ptr<ResourceEntry> entry = GetResourceEntry(kExpected[i].path);
-    ASSERT_TRUE(entry) << "for path: " << kExpected[i].path;
-    EXPECT_EQ(kExpected[i].id, entry->resource_id());
-
-    ResourceEntry parent_entry;
-    EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(
-        entry->parent_local_id(), &parent_entry));
-    EXPECT_EQ(kExpected[i].parent_id, parent_entry.resource_id());
-    EXPECT_EQ(kExpected[i].type,
-              entry->file_info().is_directory() ? DIRECTORY : FILE);
-  }
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ(kBaseStartPageToken, start_page_token);
-}
-
-TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry new_folder;
-  new_folder.set_resource_id("new_folder_resource_id");
-  new_folder.set_title("New Directory");
-  new_folder.mutable_file_info()->set_is_directory(true);
-  change_lists[0]->mutable_entries()->push_back(new_folder);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  ResourceEntry new_file;
-  new_file.set_resource_id("file_added_in_new_dir_id");
-  new_file.set_title("File in new dir.txt");
-  change_lists[0]->mutable_entries()->push_back(new_file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      new_folder.resource_id());
-
-  change_lists[0]->set_new_start_page_token("16730");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16730", start_page_token);
-  EXPECT_TRUE(GetResourceEntry("drive/root/New Directory"));
-  EXPECT_TRUE(GetResourceEntry(
-      "drive/root/New Directory/File in new dir.txt"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(2U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/New Directory/File in new dir.txt")));
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/New Directory")));
-}
-
-TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry entry;
-  entry.set_resource_id("1_folder_resource_id");
-  entry.set_title("Directory 1");
-  entry.mutable_file_info()->set_is_directory(true);
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "sub_dir_folder_2_self_link");
-
-  change_lists[0]->set_new_start_page_token("16809");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16809", start_page_token);
-  EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1"));
-  EXPECT_TRUE(GetResourceEntry(
-      "drive/root/Directory 2 excludeDir-test/Directory 1"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(2U, changed_files.size());
-  EXPECT_TRUE(changed_files.CountDirectory(
-      base::FilePath::FromUTF8Unsafe("drive/root")));
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
-  EXPECT_TRUE(changed_files.CountDirectory(base::FilePath::FromUTF8Unsafe(
-      "drive/root/Directory 2 excludeDir-test")));
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/Directory 2 excludeDir-test/Directory 1")));
-}
-
-TEST_F(ChangeListProcessorTest, DeltaFileMovedFromDirectoryToRoot) {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry entry;
-  entry.set_resource_id("subdirectory_file_1_id");
-  entry.set_title("SubDirectory File 1.txt");
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  change_lists[0]->set_new_start_page_token("16815");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16815", start_page_token);
-  EXPECT_FALSE(GetResourceEntry(
-      "drive/root/Directory 1/SubDirectory File 1.txt"));
-  EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(2U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/SubDirectory File 1.txt")));
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/Directory 1/SubDirectory File 1.txt")));
-}
-
-TEST_F(ChangeListProcessorTest, DeltaFileRenamedInDirectory) {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry entry;
-  entry.set_resource_id("subdirectory_file_1_id");
-  entry.set_title("New SubDirectory File 1.txt");
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "1_folder_resource_id");
-
-  change_lists[0]->set_new_start_page_token("16767");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(2U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/Directory 1/SubDirectory File 1.txt")));
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/Directory 1/New SubDirectory File 1.txt")));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16767", start_page_token);
-  EXPECT_FALSE(GetResourceEntry(
-      "drive/root/Directory 1/SubDirectory File 1.txt"));
-  std::unique_ptr<ResourceEntry> new_entry(
-      GetResourceEntry("drive/root/Directory 1/New SubDirectory File 1.txt"));
-  ASSERT_TRUE(new_entry);
-
-  // Keep the to-be-synced properties.
-  ASSERT_EQ(1, new_entry->mutable_new_properties()->size());
-  const Property& new_property = new_entry->new_properties().Get(0);
-  EXPECT_EQ("hello", new_property.key());
-}
-
-TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileInRoot) {
-  // Create ChangeList to add a file.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry entry;
-  entry.set_resource_id("added_in_root_id");
-  entry.set_title("Added file.txt");
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  change_lists[0]->set_new_start_page_token("16683");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16683", start_page_token);
-  EXPECT_TRUE(GetResourceEntry("drive/root/Added file.txt"));
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/Added file.txt")));
-
-  // Create ChangeList to delete the file.
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  entry.set_deleted(true);
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  change_lists[0]->set_new_start_page_token("16687");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16687", start_page_token);
-  EXPECT_FALSE(GetResourceEntry("drive/root/Added file.txt"));
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/Added file.txt")));
-}
-
-
-TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileFromExistingDirectory) {
-  // Create ChangeList to add a file.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry entry;
-  entry.set_resource_id("added_in_root_id");
-  entry.set_title("Added file.txt");
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "1_folder_resource_id");
-
-  change_lists[0]->set_new_start_page_token("16730");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16730", start_page_token);
-  EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.txt"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/Directory 1/Added file.txt")));
-
-  // Create ChangeList to delete the file.
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  entry.set_deleted(true);
-  change_lists[0]->mutable_entries()->push_back(entry);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "1_folder_resource_id");
-
-  change_lists[0]->set_new_start_page_token("16770");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16770", start_page_token);
-  EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.txt"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/Directory 1/Added file.txt")));
-}
-
-TEST_F(ChangeListProcessorTest, DeltaAddFileToNewButDeletedDirectory) {
-  // Create a change which contains the following updates:
-  // 1) A new PDF file is added to a new directory
-  // 2) but the new directory is marked "deleted" (i.e. moved to Trash)
-  // Hence, the PDF file should be just ignored.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry file;
-  file.set_resource_id("file_added_in_deleted_id");
-  file.set_title("new_pdf_file.pdf");
-  file.set_deleted(true);
-  change_lists[0]->mutable_entries()->push_back(file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      "new_folder_resource_id");
-
-  ResourceEntry directory;
-  directory.set_resource_id("new_folder_resource_id");
-  directory.set_title("New Directory");
-  directory.mutable_file_info()->set_is_directory(true);
-  directory.set_deleted(true);
-  change_lists[0]->mutable_entries()->push_back(directory);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-
-  change_lists[0]->set_new_start_page_token("16730");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16730", start_page_token);
-  EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf"));
-
-  EXPECT_TRUE(changed_team_drives.empty());
-  EXPECT_TRUE(changed_files.empty());
-}
-
-TEST_F(ChangeListProcessorTest, RefreshDirectory) {
-  // Prepare metadata.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  // Create change list.
-  std::unique_ptr<ChangeList> change_list(new ChangeList);
-
-  // Add a new file to the change list.
-  ResourceEntry new_file;
-  new_file.set_title("new_file");
-  new_file.set_resource_id("new_file_id");
-  change_list->mutable_entries()->push_back(new_file);
-  change_list->mutable_parent_resource_ids()->push_back(kRootId);
-
-  // Add "Directory 1" to the map with a new name.
-  ResourceEntry dir1;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath().AppendASCII("Directory 1"), &dir1));
-  dir1.set_title(dir1.title() + " (renamed)");
-  change_list->mutable_entries()->push_back(dir1);
-  change_list->mutable_parent_resource_ids()->push_back(kRootId);
-
-  // Update the directory with the map.
-  ResourceEntry root;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath(), &root));
-  const std::string kNewStartpageToken = "12345";
-  ResourceEntryVector refreshed_entries;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ChangeListProcessor::RefreshDirectory(
-                metadata_.get(),
-                DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken,
-                                   util::GetDriveMyDriveRootPath(),
-                                   util::GetDriveMyDriveRootPath()),
-                std::move(change_list), &refreshed_entries));
-
-  // "new_file" should be added.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry));
-
-  // "Directory 1" should be renamed.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath().AppendASCII(dir1.title()), &entry));
-}
-
-TEST_F(ChangeListProcessorTest, RefreshDirectory_WrongParentId) {
-  // Prepare metadata.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  // Create change list and add a new file to it.
-  std::unique_ptr<ChangeList> change_list(new ChangeList);
-  ResourceEntry new_file;
-  new_file.set_title("new_file");
-  new_file.set_resource_id("new_file_id");
-  // This entry should not be added because the parent ID does not match.
-  change_list->mutable_parent_resource_ids()->push_back(
-      "some-random-resource-id");
-  change_list->mutable_entries()->push_back(new_file);
-
-
-  // Update the directory.
-  ResourceEntry root;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath(), &root));
-  const std::string kNewStartpageToken = "12345";
-  ResourceEntryVector refreshed_entries;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ChangeListProcessor::RefreshDirectory(
-                metadata_.get(),
-                DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken,
-                                   util::GetDriveMyDriveRootPath(),
-                                   util::GetDriveMyDriveRootPath()),
-                std::move(change_list), &refreshed_entries));
-
-  // "new_file" should not be added.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry));
-}
-
-TEST_F(ChangeListProcessorTest, SharedFilesWithNoParentInFeed) {
-  // Prepare metadata.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  // Create change lists.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  // Add a new file with non-existing parent resource id to the change lists.
-  ResourceEntry new_file;
-  new_file.set_title("new_file");
-  new_file.set_resource_id("new_file_id");
-  change_lists[0]->mutable_entries()->push_back(new_file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("nonexisting");
-  change_lists[0]->set_new_start_page_token("123");
-
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  // "new_file" should be added under drive/other.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveGrandRootPath().AppendASCII("other/new_file"), &entry));
-}
-
-TEST_F(ChangeListProcessorTest, ModificationDate) {
-  // Prepare metadata.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  // Create change lists with a new file.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  const base::Time now = base::Time::Now();
-  ResourceEntry new_file_remote;
-  new_file_remote.set_title("new_file_remote");
-  new_file_remote.set_resource_id("new_file_id");
-  new_file_remote.set_modification_date(now.ToInternalValue());
-
-  change_lists[0]->mutable_entries()->push_back(new_file_remote);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-  change_lists[0]->set_new_start_page_token("123");
-
-  // Add the same file locally, but with a different name, a dirty metadata
-  // state, and a newer modification date.
-  ResourceEntry root;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath(), &root));
-
-  ResourceEntry new_file_local;
-  new_file_local.set_resource_id(new_file_remote.resource_id());
-  new_file_local.set_parent_local_id(root.local_id());
-  new_file_local.set_title("new_file_local");
-  new_file_local.set_metadata_edit_state(ResourceEntry::DIRTY);
-  new_file_local.set_modification_date(
-      (now + base::TimeDelta::FromSeconds(1)).ToInternalValue());
-  std::string local_id;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(new_file_local, &local_id));
-
-  // Apply the change.
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  // The change is rejected due to the old modification date.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id, &entry));
-  EXPECT_EQ(new_file_local.title(), entry.title());
-}
-
-TEST_F(ChangeListProcessorTest, AddNewTeamDrive) {
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry team_drive;
-  team_drive.set_resource_id("team_drive_resource_id");
-  team_drive.set_title("New Team Drive");
-  team_drive.mutable_file_info()->set_is_directory(true);
-  team_drive.mutable_file_info()->set_is_team_drive_root(true);
-  team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      util::kDriveTeamDrivesDirLocalId);
-
-  change_lists[0]->set_new_start_page_token("16730");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16730", start_page_token);
-
-  constexpr char kExpectedPath[] = "drive/team_drives/New Team Drive";
-  EXPECT_TRUE(GetResourceEntry(kExpectedPath));
-
-  // A new team drive will be in both changed_files and changed_team_drives.
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(
-      changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-
-  EXPECT_EQ(1U, changed_team_drives.size());
-  EXPECT_TRUE(
-      changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-}
-
-TEST_F(ChangeListProcessorTest, AddAndDeleteTeamDrive) {
-  // Create ChangeList to add a file.
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  ResourceEntry team_drive;
-  team_drive.set_resource_id("team_drive_resource_id");
-  team_drive.set_title("New Team Drive");
-  team_drive.mutable_file_info()->set_is_directory(true);
-  team_drive.mutable_file_info()->set_is_team_drive_root(true);
-  team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      util::kDriveTeamDrivesDirLocalId);
-
-  change_lists[0]->set_new_start_page_token("16683");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  FileChange changed_team_drives;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16683", start_page_token);
-  constexpr char kExpectedPath[] = "drive/team_drives/New Team Drive";
-
-  EXPECT_TRUE(GetResourceEntry(kExpectedPath));
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(
-      changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-  EXPECT_EQ(1U, changed_team_drives.size());
-  EXPECT_TRUE(
-      changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-
-  // Create ChangeList to delete the file.
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  team_drive.set_deleted(true);
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      util::kDriveTeamDrivesDirLocalId);
-
-  change_lists[0]->set_new_start_page_token("16687");
-
-  // Apply.
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files,
-                                &changed_team_drives));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ("16687", start_page_token);
-  EXPECT_FALSE(GetResourceEntry(kExpectedPath));
-  EXPECT_EQ(1U, changed_files.size());
-  EXPECT_TRUE(
-      changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-  EXPECT_EQ(1U, changed_team_drives.size());
-  EXPECT_TRUE(
-      changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath)));
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/change_list_processor.cc b/components/drive/chromeos/change_list_processor.cc
deleted file mode 100644
index 42fbcbf..0000000
--- a/components/drive/chromeos/change_list_processor.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/change_list_processor.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/atomic_flag.h"
-#include "components/drive/chromeos/drive_file_util.h"
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_api_util.h"
-#include "components/drive/file_change.h"
-#include "components/drive/file_system_core_util.h"
-#include "components/drive/resource_entry_conversion.h"
-#include "google_apis/drive/drive_api_parser.h"
-
-namespace drive {
-namespace internal {
-
-namespace {
-
-// Returns true if it's OK to overwrite the local entry with the remote one.
-bool ShouldApplyChange(const ResourceEntry& local_entry,
-                       const ResourceEntry& remote_entry) {
-  if (local_entry.metadata_edit_state() == ResourceEntry::CLEAN)
-    return true;
-  return base::Time::FromInternalValue(remote_entry.modification_date()) >
-         base::Time::FromInternalValue(local_entry.modification_date());
-}
-
-}  // namespace
-
-DirectoryFetchInfo::DirectoryFetchInfo() = default;
-
-DirectoryFetchInfo::~DirectoryFetchInfo() = default;
-
-DirectoryFetchInfo::DirectoryFetchInfo(const std::string& local_id,
-                                       const std::string& resource_id,
-                                       const std::string& start_page_token,
-                                       const base::FilePath& root_entry_path,
-                                       const base::FilePath& directory_path)
-    : local_id_(local_id),
-      resource_id_(resource_id),
-      start_page_token_(start_page_token),
-      root_entry_path_(root_entry_path),
-      directory_path_(directory_path) {}
-
-DirectoryFetchInfo::DirectoryFetchInfo(const DirectoryFetchInfo& other) =
-    default;
-
-std::string DirectoryFetchInfo::ToString() const {
-  return ("local_id: " + local_id_ + ", resource_id: " + resource_id_ +
-          ", start_page_token: " + start_page_token_ +
-          ", root_entry_path: " + root_entry_path_.value() +
-          ", directory_path: " + directory_path_.value());
-}
-
-ChangeList::ChangeList() = default;
-
-ChangeList::ChangeList(const google_apis::TeamDriveList& team_drive_list) {
-  const std::vector<std::unique_ptr<google_apis::TeamDriveResource>>& items =
-      team_drive_list.items();
-  entries_.resize(items.size());
-  parent_resource_ids_.resize(items.size(), "");
-  for (size_t i = 0; i < items.size(); ++i) {
-    ConvertTeamDriveResourceToResourceEntry(*items[i], &entries_[i]);
-  }
-}
-
-ChangeList::ChangeList(const google_apis::ChangeList& change_list)
-    : next_url_(change_list.next_link()),
-      new_start_page_token_(change_list.new_start_page_token()) {
-  const std::vector<std::unique_ptr<google_apis::ChangeResource>>& items =
-      change_list.items();
-  entries_.resize(items.size());
-  parent_resource_ids_.resize(items.size());
-  for (size_t i = 0; i < items.size(); ++i) {
-    ConvertChangeResourceToResourceEntry(*items[i], &entries_[i],
-                                         &parent_resource_ids_[i]);
-  }
-}
-
-ChangeList::ChangeList(const google_apis::FileList& file_list)
-    : next_url_(file_list.next_link()) {
-  const std::vector<std::unique_ptr<google_apis::FileResource>>& items =
-      file_list.items();
-  entries_.resize(items.size());
-  parent_resource_ids_.resize(items.size());
-  for (size_t i = 0; i < items.size(); ++i) {
-    ConvertFileResourceToResourceEntry(*items[i], &entries_[i],
-                                       &parent_resource_ids_[i]);
-  }
-}
-
-ChangeList::~ChangeList() = default;
-
-class ChangeListProcessor::ChangeListToEntryMapUMAStats {
- public:
-  ChangeListToEntryMapUMAStats()
-      : num_regular_files_(0), num_hosted_documents_(0) {}
-
-  // Increments number of files.
-  void IncrementNumFiles(bool is_hosted_document) {
-    is_hosted_document ? num_hosted_documents_++ : num_regular_files_++;
-  }
-
-  // Updates UMA histograms with file counts.
-  void UpdateFileCountUmaHistograms() {
-    const int num_total_files = num_hosted_documents_ + num_regular_files_;
-    UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfRegularFiles", num_regular_files_);
-    UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfHostedDocuments",
-                            num_hosted_documents_);
-    UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfTotalFiles", num_total_files);
-  }
-
- private:
-  int num_regular_files_;
-  int num_hosted_documents_;
-};
-
-ChangeListProcessor::ChangeListProcessor(const std::string& team_drive_id,
-                                         const base::FilePath& root_entry_path,
-                                         ResourceMetadata* resource_metadata,
-                                         base::AtomicFlag* in_shutdown)
-    : resource_metadata_(resource_metadata),
-      in_shutdown_(in_shutdown),
-      changed_files_(new FileChange),
-      changed_team_drives_(new FileChange),
-      team_drive_id_(team_drive_id),
-      root_entry_path_(root_entry_path) {}
-
-ChangeListProcessor::~ChangeListProcessor() = default;
-
-FileError ChangeListProcessor::ApplyUserChangeList(
-    const std::string& start_page_token,
-    const std::string& root_resource_id,
-    std::vector<std::unique_ptr<ChangeList>> change_lists,
-    bool is_delta_update) {
-  std::string new_start_page_token = start_page_token;
-  if (is_delta_update) {
-    if (!change_lists.empty()) {
-      // The start_page_token appears in the first page of the change list.
-      // The start_page_token does not appear in the full resource list.
-      new_start_page_token = change_lists[0]->new_start_page_token();
-      DCHECK(!new_start_page_token.empty());
-    }
-  }
-
-  // Update the resource ID of the entry, if required.
-
-  // Multiple team drives can have the same root_entry_path_, so try looking up
-  // via the team_drive_id first.
-  ResourceEntry root;
-  FileError error = FILE_ERROR_OK;
-  if (!team_drive_id_.empty()) {
-    std::string local_id;
-    error = resource_metadata_->GetIdByResourceId(team_drive_id_, &local_id);
-    if (error != FILE_ERROR_OK) {
-      LOG(ERROR) << "Failed to get team drive local id: "
-                 << FileErrorToString(error);
-      return error;
-    }
-    error = resource_metadata_->GetResourceEntryById(local_id, &root);
-    if (error != FILE_ERROR_OK) {
-      LOG(ERROR) << "Failed to get team drive root entry: "
-                 << FileErrorToString(error);
-      return error;
-    }
-  } else {
-    error = resource_metadata_->GetResourceEntryByPath(root_entry_path_, &root);
-    if (error != FILE_ERROR_OK) {
-      LOG(ERROR) << "Failed to get root entry: " << FileErrorToString(error);
-      return error;
-    }
-  }
-  // Only update if the root resource id has changed. This will happen for the
-  // default corpus on the first load, as we obtain the resource id lazily.
-  if (root_resource_id != root.resource_id()) {
-    root.set_resource_id(root_resource_id);
-    error = resource_metadata_->RefreshEntry(root);
-    if (error != FILE_ERROR_OK) {
-      LOG(ERROR) << "Failed to update root entry: " << FileErrorToString(error);
-      return error;
-    }
-  }
-
-  ChangeListToEntryMapUMAStats uma_stats;
-  error = ApplyChangeListInternal(std::move(change_lists), new_start_page_token,
-                                  &root, &uma_stats);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  // Update start_page_token in the metadata header.
-  error = SetStartPageToken(resource_metadata_, team_drive_id_,
-                            new_start_page_token);
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "SetStartPageToken failed: " << FileErrorToString(error);
-    return error;
-  }
-
-  // Shouldn't record histograms when processing delta update.
-  if (!is_delta_update)
-    uma_stats.UpdateFileCountUmaHistograms();
-
-  return FILE_ERROR_OK;
-}
-
-FileError ChangeListProcessor::ApplyChangeListInternal(
-    std::vector<std::unique_ptr<ChangeList>> change_lists,
-    const std::string& start_page_token,
-    ResourceEntry* root,
-    ChangeListToEntryMapUMAStats* uma_stats) {
-  ConvertChangeListsToMap(std::move(change_lists), start_page_token, uma_stats);
-  FileError error = ApplyEntryMap(root->resource_id());
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "ApplyEntryMap failed: " << FileErrorToString(error);
-    return error;
-  }
-  // Update start_page_token of the root entry.
-  root->mutable_directory_specific_info()->set_start_page_token(
-      start_page_token);
-  error = resource_metadata_->RefreshEntry(*root);
-  if (error != FILE_ERROR_OK)
-    DLOG(ERROR) << "RefreshEntry failed: " << FileErrorToString(error);
-  return error;
-}
-
-void ChangeListProcessor::ConvertChangeListsToMap(
-    std::vector<std::unique_ptr<ChangeList>> change_lists,
-    const std::string& start_page_token,
-    ChangeListToEntryMapUMAStats* uma_stats) {
-  for (size_t i = 0; i < change_lists.size(); ++i) {
-    ChangeList* change_list = change_lists[i].get();
-
-    std::vector<ResourceEntry>* entries = change_list->mutable_entries();
-    for (size_t i = 0; i < entries->size(); ++i) {
-      ResourceEntry* entry = &(*entries)[i];
-
-      // Count the number of files.
-      if (!entry->file_info().is_directory()) {
-        uma_stats->IncrementNumFiles(
-            entry->file_specific_info().is_hosted_document());
-      }
-      parent_resource_id_map_[entry->resource_id()] =
-          change_list->parent_resource_ids()[i];
-      entry_map_[entry->resource_id()].Swap(entry);
-      LOG_IF(WARNING, !entry->resource_id().empty())
-          << "Found duplicated file: " << entry->base_name();
-    }
-  }
-
-  // Add the largest start_page_token for directories.
-  for (ResourceEntryMap::iterator it = entry_map_.begin();
-       it != entry_map_.end(); ++it) {
-    if (it->second.file_info().is_directory()) {
-      it->second.mutable_directory_specific_info()->set_start_page_token(
-          start_page_token);
-    }
-  }
-}
-
-FileError ChangeListProcessor::ApplyEntryMap(
-    const std::string& root_resource_id) {
-  // Gather the set of changes in the old path.
-  // Note that we want to notify the change in both old and new paths (suppose
-  // /a/b/c is moved to /x/y/c. We want to notify both "/a/b" and "/x/y".)
-  // The old paths must be calculated before we apply any actual changes.
-  // The new paths are calculated after each change is applied. It correctly
-  // sets the new path because we apply changes in such an order (see below).
-  for (ResourceEntryMap::iterator it = entry_map_.begin();
-       it != entry_map_.end(); ++it) {
-    UpdateChangedDirs(it->second);
-  }
-
-  // Apply all entries except deleted ones to the metadata.
-  std::vector<std::string> deleted_resource_ids;
-  while (!entry_map_.empty()) {
-    if (in_shutdown_ && in_shutdown_->IsSet())
-      return FILE_ERROR_ABORT;
-
-    ResourceEntryMap::iterator it = entry_map_.begin();
-
-    // Process deleted entries later to avoid deleting moved entries under it.
-    if (it->second.deleted()) {
-      deleted_resource_ids.push_back(it->first);
-      entry_map_.erase(it);
-      continue;
-    }
-
-    // Start from entry_map_.begin() and traverse ancestors using the
-    // parent-child relationships in the result (after this apply) tree.
-    // Then apply the topmost change first.
-    //
-    // By doing this, assuming the result tree does not contain any cycles, we
-    // can guarantee that no cycle is made during this apply (i.e. no entry gets
-    // moved under any of its descendants) because the following conditions are
-    // always satisfied in any move:
-    // - The new parent entry is not a descendant of the moved entry.
-    // - The new parent and its ancestors will no longer move during this apply.
-    std::vector<ResourceEntryMap::iterator> entries;
-    for (ResourceEntryMap::iterator it = entry_map_.begin();
-         it != entry_map_.end();) {
-      entries.push_back(it);
-
-      DCHECK(parent_resource_id_map_.count(it->first)) << it->first;
-      const std::string& parent_resource_id =
-          parent_resource_id_map_[it->first];
-
-      if (parent_resource_id.empty())  // This entry has no parent.
-        break;
-
-      ResourceEntryMap::iterator it_parent =
-          entry_map_.find(parent_resource_id);
-      if (it_parent == entry_map_.end()) {
-        // Current entry's parent is already updated or not going to be updated,
-        // get the parent from the local tree.
-        std::string parent_local_id;
-        FileError error = resource_metadata_->GetIdByResourceId(
-            parent_resource_id, &parent_local_id);
-        if (error != FILE_ERROR_OK) {
-          // See crbug.com/326043. In some complicated situations, parent folder
-          // for shared entries may be accessible (and hence its resource id is
-          // included), but not in the change/file list.
-          // In such a case, clear the parent and move it to drive/other.
-          if (error == FILE_ERROR_NOT_FOUND) {
-            parent_resource_id_map_[it->first] = "";
-          } else {
-            LOG(ERROR) << "Failed to get local ID: " << parent_resource_id
-                       << ", error = " << FileErrorToString(error);
-          }
-          break;
-        }
-        ResourceEntry parent_entry;
-        while (it_parent == entry_map_.end() && !parent_local_id.empty()) {
-          error = resource_metadata_->GetResourceEntryById(
-              parent_local_id, &parent_entry);
-          if (error != FILE_ERROR_OK) {
-            LOG(ERROR) << "Failed to get local entry: "
-                       << FileErrorToString(error);
-            break;
-          }
-          it_parent = entry_map_.find(parent_entry.resource_id());
-          parent_local_id = parent_entry.parent_local_id();
-        }
-      }
-      it = it_parent;
-    }
-
-    // Apply the parent first.
-    std::reverse(entries.begin(), entries.end());
-    for (size_t i = 0; i < entries.size(); ++i) {
-      // Skip root entry in the change list. We don't expect servers to send
-      // root entry, but we should better be defensive (see crbug.com/297259).
-      ResourceEntryMap::iterator it = entries[i];
-      if (it->first != root_resource_id) {
-        FileError error = ApplyEntry(it->second);
-        if (error != FILE_ERROR_OK) {
-          LOG(ERROR) << "ApplyEntry failed: " << FileErrorToString(error)
-                     << ", title = " << it->second.title();
-          return error;
-        }
-      }
-      entry_map_.erase(it);
-    }
-  }
-
-  // Apply deleted entries.
-  for (size_t i = 0; i < deleted_resource_ids.size(); ++i) {
-    std::string local_id;
-    FileError error = resource_metadata_->GetIdByResourceId(
-        deleted_resource_ids[i], &local_id);
-    switch (error) {
-      case FILE_ERROR_OK:
-        error = resource_metadata_->RemoveEntry(local_id);
-        break;
-      case FILE_ERROR_NOT_FOUND:
-        error = FILE_ERROR_OK;
-        break;
-      default:
-        break;
-    }
-    if (error != FILE_ERROR_OK) {
-      LOG(ERROR) << "Failed to delete: " << FileErrorToString(error)
-                 << ", resource_id = " << deleted_resource_ids[i];
-      return error;
-    }
-  }
-
-  return FILE_ERROR_OK;
-}
-
-FileError ChangeListProcessor::ApplyEntry(const ResourceEntry& entry) {
-  DCHECK(!entry.deleted());
-  DCHECK(!entry.resource_id().empty());
-  DCHECK(parent_resource_id_map_.count(entry.resource_id()));
-  const std::string& parent_resource_id =
-      parent_resource_id_map_[entry.resource_id()];
-
-  ResourceEntry new_entry(entry);
-  FileError error = SetParentLocalIdOfEntry(resource_metadata_, &new_entry,
-                                            parent_resource_id);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  // Lookup the entry.
-  std::string local_id;
-  error = resource_metadata_->GetIdByResourceId(entry.resource_id(), &local_id);
-
-  ResourceEntry existing_entry;
-  if (error == FILE_ERROR_OK)
-    error = resource_metadata_->GetResourceEntryById(local_id, &existing_entry);
-
-  switch (error) {
-    case FILE_ERROR_OK:
-      if (ShouldApplyChange(existing_entry, new_entry)) {
-        // Entry exists and needs to be refreshed.
-        new_entry.set_local_id(local_id);
-        // Keep the to-be-synced properties of the existing resource entry.
-        new_entry.mutable_new_properties()->CopyFrom(
-            existing_entry.new_properties());
-        error = resource_metadata_->RefreshEntry(new_entry);
-      } else {
-        if (entry.file_info().is_directory()) {
-          // No need to refresh, but update the start_page_token.
-          new_entry = existing_entry;
-          new_entry.mutable_directory_specific_info()->set_start_page_token(
-              new_entry.directory_specific_info().start_page_token());
-          error = resource_metadata_->RefreshEntry(new_entry);
-        }
-        DVLOG(1) << "Change was discarded for: " << entry.resource_id();
-      }
-      break;
-    case FILE_ERROR_NOT_FOUND: {  // Adding a new entry.
-      std::string local_id;
-      error = resource_metadata_->AddEntry(new_entry, &local_id);
-      break;
-    }
-    default:
-      return error;
-  }
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  UpdateChangedDirs(entry);
-  return FILE_ERROR_OK;
-}
-
-// static
-FileError ChangeListProcessor::RefreshDirectory(
-    ResourceMetadata* resource_metadata,
-    const DirectoryFetchInfo& directory_fetch_info,
-    std::unique_ptr<ChangeList> change_list,
-    std::vector<ResourceEntry>* out_refreshed_entries) {
-  DCHECK(!directory_fetch_info.empty());
-
-  ResourceEntry directory;
-  FileError error = resource_metadata->GetResourceEntryById(
-      directory_fetch_info.local_id(), &directory);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  if (!directory.file_info().is_directory())
-    return FILE_ERROR_NOT_A_DIRECTORY;
-
-  std::vector<ResourceEntry>* entries = change_list->mutable_entries();
-  for (size_t i = 0; i < entries->size(); ++i) {
-    ResourceEntry* entry = &(*entries)[i];
-    const std::string& parent_resource_id =
-        change_list->parent_resource_ids()[i];
-
-    // Skip if the parent resource ID does not match. This is needed to
-    // handle entries with multiple parents. For such entries, the first
-    // parent is picked and other parents are ignored, hence some entries may
-    // have a parent resource ID which does not match the target directory's.
-    if (parent_resource_id != directory_fetch_info.resource_id()) {
-      DVLOG(1) << "Wrong-parent entry rejected: " << entry->resource_id();
-      continue;
-    }
-
-    entry->set_parent_local_id(directory_fetch_info.local_id());
-
-    std::string local_id;
-    error = resource_metadata->GetIdByResourceId(entry->resource_id(),
-                                                 &local_id);
-    if (error == FILE_ERROR_OK) {
-      entry->set_local_id(local_id);
-      error = resource_metadata->RefreshEntry(*entry);
-    }
-
-    if (error == FILE_ERROR_NOT_FOUND) {  // If refreshing fails, try adding.
-      entry->clear_local_id();
-      error = resource_metadata->AddEntry(*entry, &local_id);
-    }
-
-    if (error != FILE_ERROR_OK)
-      return error;
-
-    ResourceEntry result_entry;
-    error = resource_metadata->GetResourceEntryById(local_id, &result_entry);
-    if (error != FILE_ERROR_OK)
-      return error;
-    out_refreshed_entries->push_back(result_entry);
-  }
-  return FILE_ERROR_OK;
-}
-
-// static
-FileError ChangeListProcessor::SetParentLocalIdOfEntry(
-    ResourceMetadata* resource_metadata,
-    ResourceEntry* entry,
-    const std::string& parent_resource_id) {
-  if (entry->parent_local_id() == util::kDriveTeamDrivesDirLocalId) {
-    // When |entry| is a root directory of a Team Drive, the parent directory
-    // of it is "/team_drives", which doesn't have resource ID.
-    return FILE_ERROR_OK;
-  }
-  std::string parent_local_id;
-  if (parent_resource_id.empty()) {
-    // Entries without parents should go under "other" directory.
-    parent_local_id = util::kDriveOtherDirLocalId;
-  } else {
-    FileError error = resource_metadata->GetIdByResourceId(
-        parent_resource_id, &parent_local_id);
-    if (error != FILE_ERROR_OK)
-      return error;
-  }
-  entry->set_parent_local_id(parent_local_id);
-  return FILE_ERROR_OK;
-}
-
-void ChangeListProcessor::UpdateChangedDirs(const ResourceEntry& entry) {
-  DCHECK(!entry.resource_id().empty());
-
-  std::string local_id;
-  base::FilePath file_path;
-  if (resource_metadata_->GetIdByResourceId(
-          entry.resource_id(), &local_id) == FILE_ERROR_OK)
-    resource_metadata_->GetFilePath(local_id, &file_path);
-
-  if (!file_path.empty()) {
-    FileChange::ChangeType type = entry.deleted()
-                                      ? FileChange::CHANGE_TYPE_DELETE
-                                      : FileChange::CHANGE_TYPE_ADD_OR_UPDATE;
-    changed_files_->Update(file_path, entry, type);
-
-    if (entry.file_info().is_team_drive_root()) {
-      changed_team_drives_->Update(file_path, entry, type);
-    }
-  }
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/change_list_processor.h b/components/drive/chromeos/change_list_processor.h
deleted file mode 100644
index 133315b..0000000
--- a/components/drive/chromeos/change_list_processor.h
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_
-#define COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "components/drive/file_errors.h"
-#include "url/gurl.h"
-
-namespace base {
-class AtomicFlag;
-}  // namespace base
-
-namespace google_apis {
-class ChangeList;
-class FileList;
-class TeamDriveList;
-}  // namespace google_apis
-
-namespace drive {
-
-class FileChange;
-class ResourceEntry;
-
-namespace internal {
-
-class ResourceMetadata;
-
-// Holds information needed to fetch contents of a directory.
-// This object is copyable.
-class DirectoryFetchInfo {
- public:
-  DirectoryFetchInfo();
-  ~DirectoryFetchInfo();
-
-  DirectoryFetchInfo(const std::string& local_id,
-                     const std::string& resource_id,
-                     const std::string& start_page_token,
-                     const base::FilePath& root_entry_path,
-                     const base::FilePath& directory_path);
-
-  DirectoryFetchInfo(const DirectoryFetchInfo& other);
-
-  // Returns true if the object is empty.
-  bool empty() const { return local_id_.empty(); }
-
-  // Local ID of the directory.
-  const std::string& local_id() const { return local_id_; }
-
-  // Resource ID of the directory.
-  const std::string& resource_id() const { return resource_id_; }
-
-  // Start Page Token of the directory. The start page token is used to
-  // determine if the directory contents should be fetched.
-  const std::string& start_page_token() const { return start_page_token_; }
-
-  // The root path of the directory being fetched.
-  const base::FilePath& root_entry_path() const { return root_entry_path_; }
-
-  // The directory path that we are fetching. Used for logging.
-  const base::FilePath& directory_path() const { return directory_path_; }
-
-  // Returns a string representation of this object.
-  std::string ToString() const;
-
- private:
-  const std::string local_id_;
-  const std::string resource_id_;
-  const std::string start_page_token_;
-  const base::FilePath root_entry_path_;
-  const base::FilePath directory_path_;
-};
-
-// Class to represent a change list.
-class ChangeList {
- public:
-  ChangeList();  // For tests.
-  explicit ChangeList(const google_apis::ChangeList& change_list);
-  explicit ChangeList(const google_apis::FileList& file_list);
-  explicit ChangeList(const google_apis::TeamDriveList& team_drive_list);
-  ~ChangeList();
-
-  const std::vector<ResourceEntry>& entries() const { return entries_; }
-  std::vector<ResourceEntry>* mutable_entries() { return &entries_; }
-  const std::vector<std::string>& parent_resource_ids() const {
-    return parent_resource_ids_;
-  }
-  std::vector<std::string>* mutable_parent_resource_ids() {
-    return &parent_resource_ids_;
-  }
-  const GURL& next_url() const { return next_url_; }
-
-  const std::string& new_start_page_token() const {
-    return new_start_page_token_;
-  }
-
-  void set_new_start_page_token(const std::string& start_page_token) {
-    new_start_page_token_ = start_page_token;
-  }
-
- private:
-  std::vector<ResourceEntry> entries_;
-  std::vector<std::string> parent_resource_ids_;
-  GURL next_url_;
-  std::string new_start_page_token_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChangeList);
-};
-
-// ChangeListProcessor is used to process change lists, or full resource
-// lists from WAPI (codename for Documents List API) or Google Drive API, and
-// updates the resource metadata stored locally.
-class ChangeListProcessor {
- public:
-  ChangeListProcessor(const std::string& team_drive_id,
-                      const base::FilePath& root_entry_path,
-                      ResourceMetadata* resource_metadata,
-                      base::AtomicFlag* in_shutdown);
-  ~ChangeListProcessor();
-
-  // Applies user's change lists or full resource lists to
-  // |resource_metadata_|.
-  //
-  // |is_delta_update| determines the type of input data to process, whether
-  // it is full resource lists (false) or change lists (true).
-  //
-  // Must be run on the same task runner as |resource_metadata_| uses.
-  // |start_page_token| is the start page token used to retrieve the change
-  // list.
-  // |root_resource_id| is the resource id to lookup the root folder of the
-  // changeslists in resource metadata.
-  FileError ApplyUserChangeList(
-      const std::string& start_page_token,
-      const std::string& root_resource_id,
-      std::vector<std::unique_ptr<ChangeList>> change_lists,
-      bool is_delta_update);
-
-  // The set of changed files as a result of change list processing.
-  const FileChange& changed_files() const { return *changed_files_; }
-
-  // The set of team drives changes as a result of change list processing.
-  // Note that a team drive change will appear in both changed_files() and
-  // changed_team_drives()
-  const FileChange& changed_team_drives() const {
-    return *changed_team_drives_;
-  }
-
-  // Adds or refreshes the child entries from |change_list| to the directory.
-  static FileError RefreshDirectory(
-      ResourceMetadata* resource_metadata,
-      const DirectoryFetchInfo& directory_fetch_info,
-      std::unique_ptr<ChangeList> change_list,
-      std::vector<ResourceEntry>* out_refreshed_entries);
-
-  // Sets |entry|'s parent_local_id.
-  static FileError SetParentLocalIdOfEntry(
-      ResourceMetadata* resource_metadata,
-      ResourceEntry* entry,
-      const std::string& parent_resource_id);
-
- private:
-  class ChangeListToEntryMapUMAStats;
-
-  typedef std::map<std::string /* resource_id */, ResourceEntry>
-      ResourceEntryMap;
-  typedef std::map<std::string /* resource_id */,
-                   std::string /* parent_resource_id*/> ParentResourceIdMap;
-
-  // Common logic between ApplyTeamDriveChangeList and ApplyUserChangeList.
-  // Applies the |change_lists| to |resource_metadta_|.
-  FileError ApplyChangeListInternal(
-      std::vector<std::unique_ptr<ChangeList>> change_lists,
-      const std::string& start_page_token,
-      ResourceEntry* root,
-      ChangeListToEntryMapUMAStats* uma_stats);
-
-  // Converts the |change_lists| to |entry_map_| and |parent_resource_id_map_|,
-  // to be applied by ApplyEntryMap() later.
-  void ConvertChangeListsToMap(
-      std::vector<std::unique_ptr<ChangeList>> change_lists,
-      const std::string& start_page_token,
-      ChangeListToEntryMapUMAStats* uma_stats);
-
-  // Applies the pre-processed metadata from entry_map_ onto the resource
-  // metadata.
-  FileError ApplyEntryMap(const std::string& root_resource_id);
-
-  // Apply |entry| to resource_metadata_.
-  FileError ApplyEntry(const ResourceEntry& entry);
-
-  // Adds the directories changed by the update on |entry| to |changed_dirs_|.
-  void UpdateChangedDirs(const ResourceEntry& entry);
-
-  ResourceMetadata* resource_metadata_;  // Not owned.
-  base::AtomicFlag* in_shutdown_;        // Not owned.
-
-  ResourceEntryMap entry_map_;
-  ParentResourceIdMap parent_resource_id_map_;
-  std::unique_ptr<FileChange> changed_files_;
-  std::unique_ptr<FileChange> changed_team_drives_;
-  const std::string team_drive_id_;
-  const base::FilePath& root_entry_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChangeListProcessor);
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_
diff --git a/components/drive/chromeos/drive_file_util.cc b/components/drive/chromeos/drive_file_util.cc
deleted file mode 100644
index 96e1bb7..0000000
--- a/components/drive/chromeos/drive_file_util.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/drive_file_util.h"
-
-#include <string>
-
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-
-namespace drive {
-namespace internal {
-
-FileError GetStartPageToken(internal::ResourceMetadata* resource_metadata,
-                            const std::string& team_drive_id,
-                            std::string* out_value) {
-  DCHECK(resource_metadata);
-  DCHECK(out_value);
-
-  if (team_drive_id == util::kTeamDriveIdDefaultCorpus) {
-    return resource_metadata->GetStartPageToken(out_value);
-  }
-
-  std::string local_id;
-  FileError error =
-      resource_metadata->GetIdByResourceId(team_drive_id, &local_id);
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "Failed to get team drive local id.";
-    return error;
-  }
-
-  ResourceEntry entry;
-  error = resource_metadata->GetResourceEntryById(local_id, &entry);
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "Filed to get the team drive resource.";
-    return error;
-  }
-
-  DCHECK(entry.file_info().is_directory());
-  DCHECK_EQ(entry.parent_local_id(), util::kDriveTeamDrivesDirLocalId);
-  out_value->assign(entry.team_drive_root_specific_info().start_page_token());
-  return FILE_ERROR_OK;
-}
-
-FileError SetStartPageToken(internal::ResourceMetadata* resource_metadata,
-                            const std::string& team_drive_id,
-                            const std::string& value) {
-  DCHECK(resource_metadata);
-
-  if (team_drive_id == util::kTeamDriveIdDefaultCorpus) {
-    return resource_metadata->SetStartPageToken(value);
-  }
-
-  std::string local_id;
-  FileError error =
-      resource_metadata->GetIdByResourceId(team_drive_id, &local_id);
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "Failed to get team drive local id.";
-    return error;
-  }
-
-  ResourceEntry entry;
-  error = resource_metadata->GetResourceEntryById(local_id, &entry);
-  if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "Failed to get the team drive resource.";
-    return error;
-  }
-
-  DCHECK(entry.file_info().is_directory());
-  DCHECK_EQ(entry.parent_local_id(), util::kDriveTeamDrivesDirLocalId);
-  entry.mutable_team_drive_root_specific_info()->set_start_page_token(value);
-  return resource_metadata->RefreshEntry(entry);
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/drive_file_util.h b/components/drive/chromeos/drive_file_util.h
deleted file mode 100644
index e7986ab..0000000
--- a/components/drive/chromeos/drive_file_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_
-#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_
-
-#include <string>
-
-#include "components/drive/file_errors.h"
-
-namespace drive {
-namespace internal {
-
-class ResourceMetadata;
-
-// Obtains the start page token for the supplied |team_drive_id|. If the
-// |team_drive_id| equals kTeamDriveIdDefaultCorpus then it will retrieve
-// the start page token just for the users default corpus.
-FileError GetStartPageToken(internal::ResourceMetadata* resource_metadata,
-                            const std::string& team_drive_id,
-                            std::string* out_value);
-
-// Sets the start page token for the supplied |team_drive_id|. If the
-// |team_drive_id| equals kTeamDriveIdDefaultCorpus then it will set
-// the start page token just for the users default corpus.
-FileError SetStartPageToken(internal::ResourceMetadata* resource_metadata,
-                            const std::string& team_drive_id,
-                            const std::string& value);
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_
diff --git a/components/drive/chromeos/drive_operation_queue.h b/components/drive/chromeos/drive_operation_queue.h
deleted file mode 100644
index 43d807c..0000000
--- a/components/drive/chromeos/drive_operation_queue.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_
-#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/containers/queue.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/time/default_tick_clock.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "components/drive/file_errors.h"
-
-namespace drive {
-namespace internal {
-
-// A rate limited queue for making calls to the drive backend. This is a basic
-// token based queue that will loosely rate limit requests to the qps specified
-// on construction. When enquing operations to an empty queue, the queue will
-// operate in burst mode and rapidly schedule up to |desired_qps| operations.
-template <typename T>
-class DriveBackgroundOperationQueue {
- public:
-  // |tick_clock| can be injected for testing.
-  explicit DriveBackgroundOperationQueue(
-      int desired_qps,
-      const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance())
-      : tick_clock_(tick_clock),
-        token_count_(desired_qps),
-        per_token_time_delta_(
-            base::TimeDelta::FromMilliseconds(1000 / desired_qps)),
-        desired_qps_(desired_qps) {}
-
-  ~DriveBackgroundOperationQueue() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  }
-
-  // Add a new operation to the queue. When the operation is scheduled to be
-  // executed start_callback will be called. When the operation completes
-  // finish_callback will be with the result.
-  void AddOperation(
-      base::WeakPtr<T> target,
-      base::OnceCallback<void(const FileOperationCallback&)> start_callback,
-      FileOperationCallback finish_callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    DCHECK(start_callback);
-    DCHECK(finish_callback);
-
-    drive_operation_queue_.emplace(std::move(target), std::move(start_callback),
-                                   std::move(finish_callback));
-
-    CheckAndMaybeStartTokenRefillTimer();
-    CheckAndMaybeStartDriveOperation();
-  }
-
-  // Effectively disables the rate limiting for test purposes.
-  void DisableQueueForTesting() {
-    desired_qps_ = INT_MAX;
-    token_count_ = INT_MAX;
-  }
-
- private:
-  struct DriveOperation;
-
-  using OperationQueue = base::queue<DriveOperation>;
-  using StartOperationCallback =
-      base::OnceCallback<void(const FileOperationCallback&)>;
-  using EndOperationCallback = FileOperationCallback;
-
-  struct DriveOperation {
-    DriveOperation(base::WeakPtr<T> target,
-                   StartOperationCallback start_callback,
-                   EndOperationCallback finish)
-        : target(std::move(target)),
-          start_callback(std::move(start_callback)),
-          finish_callback(std::move(finish)) {}
-
-    base::WeakPtr<T> target;
-    StartOperationCallback start_callback;
-    EndOperationCallback finish_callback;
-  };
-
-  void CheckAndMaybeStartDriveOperation() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    while (token_count_ > 0 && !drive_operation_queue_.empty()) {
-      auto next = std::move(drive_operation_queue_.front());
-      drive_operation_queue_.pop();
-
-      if (!next.target) {
-        continue;
-      }
-      base::SequencedTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE,
-          base::BindOnce(
-              std::move(next.start_callback),
-              base::BindRepeating(
-                  &DriveBackgroundOperationQueue<T>::OnDriveOperationComplete,
-                  weak_ptr_factory_.GetWeakPtr(),
-                  std::move(next.finish_callback))));
-      --token_count_;
-    }
-  }
-
-  void OnDriveOperationComplete(FileOperationCallback callback,
-                                FileError error) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    callback.Run(error);
-  }
-
-  void CheckAndMaybeStartTokenRefillTimer() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    if (token_refill_timer_.IsRunning()) {
-      return;
-    }
-
-    base::TimeDelta elapsed_since_stopped =
-        tick_clock_->NowTicks() - last_timer_stop_ticks_;
-    int additional_tokens = elapsed_since_stopped / per_token_time_delta_;
-
-    // Do not overflow when adding additional tokens.
-    if (desired_qps_ - token_count_ < additional_tokens) {
-      token_count_ = desired_qps_;
-    } else {
-      token_count_ += additional_tokens;
-    }
-
-    token_refill_timer_.Start(
-        FROM_HERE, per_token_time_delta_,
-        base::BindRepeating(&DriveBackgroundOperationQueue<T>::RefillTokens,
-                            weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void RefillTokens() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    if (token_count_ < desired_qps_) {
-      ++token_count_;
-    }
-    CheckAndMaybeStartDriveOperation();
-
-    if (drive_operation_queue_.empty()) {
-      token_refill_timer_.Stop();
-      last_timer_stop_ticks_ = tick_clock_->NowTicks();
-    }
-  }
-
-  OperationQueue drive_operation_queue_;
-
-  // Token Bucket timer, to refill tokens if required.
-  const base::TickClock* tick_clock_;  // Not owned.
-  base::RepeatingTimer token_refill_timer_;
-  int token_count_;
-  const base::TimeDelta per_token_time_delta_;
-  int desired_qps_;
-  base::TimeTicks last_timer_stop_ticks_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  base::WeakPtrFactory<DriveBackgroundOperationQueue> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(DriveBackgroundOperationQueue<T>);
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_
diff --git a/components/drive/chromeos/drive_test_util.cc b/components/drive/chromeos/drive_test_util.cc
deleted file mode 100644
index 15134271..0000000
--- a/components/drive/chromeos/drive_test_util.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/drive_test_util.h"
-
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-
-namespace drive {
-namespace test_util {
-
-void RegisterDrivePrefs(PrefRegistrySimple* pref_registry) {
-  pref_registry->RegisterBooleanPref(
-      prefs::kDisableDrive,
-      false);
-  pref_registry->RegisterBooleanPref(
-      prefs::kDisableDriveOverCellular,
-      true);
-}
-
-}  // namespace test_util
-}  // namespace drive
diff --git a/components/drive/chromeos/drive_test_util.h b/components/drive/chromeos/drive_test_util.h
deleted file mode 100644
index c65fff11..0000000
--- a/components/drive/chromeos/drive_test_util.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_
-#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_
-
-#include <stdint.h>
-
-#include <string>
-
-#include "components/drive/chromeos/file_cache.h"
-#include "content/public/test/test_utils.h"
-#include "google_apis/drive/test_util.h"
-#include "net/base/io_buffer.h"
-#include "net/base/test_completion_callback.h"
-
-class PrefRegistrySimple;
-
-namespace drive {
-
-namespace test_util {
-
-// Disk space size used by FakeFreeDiskSpaceGetter.
-const int64_t kLotsOfSpace = drive::internal::kMinFreeSpaceInBytes * 10;
-
-// Helper to destroy objects which needs Destroy() to be called on destruction.
-// Note: When using this helper, you should destruct objects before
-// BrowserThread.
-struct DestroyHelperForTests {
-  template<typename T>
-  void operator()(T* object) const {
-    if (object) {
-      object->Destroy();
-      content::RunAllTasksUntilIdle();  // Finish destruction.
-    }
-  }
-};
-
-// Reads all the data from |reader| and copies to |content|. Returns net::Error
-// code.
-template<typename Reader>
-int ReadAllData(Reader* reader, std::string* content) {
-  const int kBufferSize = 10;
-  scoped_refptr<net::IOBuffer> buffer =
-      base::MakeRefCounted<net::IOBuffer>(kBufferSize);
-  while (true) {
-    net::TestCompletionCallback callback;
-    int result = reader->Read(buffer.get(), kBufferSize, callback.callback());
-    result = callback.GetResult(result);
-    if (result <= 0) {
-      // Found an error or EOF. Return it. Note: net::OK is 0.
-      return result;
-    }
-    content->append(buffer->data(), result);
-  }
-}
-
-// Registers Drive related preferences in |pref_registry|. Drive related
-// preferences should be registered as TestingPrefServiceSimple will crash if
-// unregistered preference is referenced.
-void RegisterDrivePrefs(PrefRegistrySimple* pref_registry);
-
-}  // namespace test_util
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_
diff --git a/components/drive/chromeos/fake_free_disk_space_getter.cc b/components/drive/chromeos/fake_free_disk_space_getter.cc
deleted file mode 100644
index 11ee033..0000000
--- a/components/drive/chromeos/fake_free_disk_space_getter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-
-#include "components/drive/chromeos/drive_test_util.h"
-
-namespace drive {
-
-FakeFreeDiskSpaceGetter::FakeFreeDiskSpaceGetter()
-    : default_value_(test_util::kLotsOfSpace) {
-}
-
-FakeFreeDiskSpaceGetter::~FakeFreeDiskSpaceGetter() = default;
-
-void FakeFreeDiskSpaceGetter::PushFakeValue(int64_t value) {
-  fake_values_.push_back(value);
-}
-
-int64_t FakeFreeDiskSpaceGetter::AmountOfFreeDiskSpace() {
-  if (fake_values_.empty())
-    return default_value_;
-
-  const int64_t value = fake_values_.front();
-  fake_values_.pop_front();
-  return value;
-}
-
-}  // namespace drive
diff --git a/components/drive/chromeos/fake_free_disk_space_getter.h b/components/drive/chromeos/fake_free_disk_space_getter.h
deleted file mode 100644
index 3a71b3c8..0000000
--- a/components/drive/chromeos/fake_free_disk_space_getter.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_
-#define COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_
-
-#include <stdint.h>
-
-#include <list>
-
-#include "base/macros.h"
-#include "components/drive/chromeos/file_cache.h"
-
-namespace drive {
-
-// This class is used to report fake free disk space. In particular, this
-// class can be used to simulate a case where disk is full, or nearly full.
-class FakeFreeDiskSpaceGetter : public internal::FreeDiskSpaceGetterInterface {
- public:
-  FakeFreeDiskSpaceGetter();
-  ~FakeFreeDiskSpaceGetter() override;
-
-  void set_default_value(int64_t value) { default_value_ = value; }
-
-  // Pushes the given value to the back of the fake value list.
-  //
-  // If the fake value list is empty, AmountOfFreeDiskSpace() will return
-  // |default_value_| repeatedly.
-  // Otherwise, AmountOfFreeDiskSpace() will return the value at the front of
-  // the list and removes it from the list.
-  void PushFakeValue(int64_t value);
-
-  // FreeDiskSpaceGetterInterface overrides.
-  int64_t AmountOfFreeDiskSpace() override;
-
- private:
-  std::list<int64_t> fake_values_;
-  int64_t default_value_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeFreeDiskSpaceGetter);
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_
diff --git a/components/drive/chromeos/file_cache.cc b/components/drive/chromeos/file_cache.cc
deleted file mode 100644
index d8737a6..0000000
--- a/components/drive/chromeos/file_cache.cc
+++ /dev/null
@@ -1,961 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/file_cache.h"
-
-#include <linux/fs.h>
-#include <sys/ioctl.h>
-#include <sys/xattr.h>
-
-#include <memory>
-#include <queue>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback_helpers.h"
-#include "base/files/file.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/system/sys_info.h"
-#include "build/build_config.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_api_util.h"
-#include "components/drive/file_system_core_util.h"
-#include "components/drive/resource_metadata_storage.h"
-#include "google_apis/drive/task_util.h"
-#include "net/base/filename_util.h"
-#include "net/base/mime_sniffer.h"
-#include "net/base/mime_util.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-typedef std::pair<base::File::Info, ResourceEntry> CacheInfo;
-typedef long FileAttributes;  // NOLINT(runtime/int)
-
-// Returns ID extracted from the path.
-std::string GetIdFromPath(const base::FilePath& path) {
-  return util::UnescapeCacheFileName(path.BaseName().AsUTF8Unsafe());
-}
-
-base::FilePath GetPathForId(const base::FilePath& cache_directory,
-                            const std::string& id) {
-  return cache_directory.Append(
-      base::FilePath::FromUTF8Unsafe(util::EscapeCacheFileName(id)));
-}
-
-// Returns if the filesystem backing |path| supports file attributes.
-// This will return false if the filesystem is for example tmpfs, which is used
-// for ephemeral mode.
-bool IsFileAttributesSupported(const base::FilePath& path) {
-  if (getxattr(path.value().c_str(), "user.foo", nullptr, 0) >= 0) {
-    return true;
-  }
-  return errno != ENOTSUP;
-}
-
-// Sets extended file attribute as |name| |value| pair.
-bool SetExtendedFileAttributes(const base::FilePath& path,
-    const std::string& name, const std::string& value) {
-  if (setxattr(path.value().c_str(), name.c_str(), value.c_str(),
-               value.size() + 1, 0) != 0) {
-    PLOG(ERROR) << "setxattr: " << path.value();
-    return false;
-  }
-  return true;
-}
-
-// Remove extended file attribute with |name|.
-bool UnsetExtendedFileAttributes(const base::FilePath& path,
-                                 const std::string& name) {
-  if (removexattr(path.value().c_str(), name.c_str()) != 0) {
-    PLOG_IF(ERROR, errno != ENODATA) << "removexattr: " << path.value();
-    return false;
-  }
-  return true;
-}
-
-// Changes attributes of the file with |flags|, e.g. FS_NODUMP_FL (cryptohome
-// will remove Drive caches with this attribute).
-// See linux/fs.h for available flags, and chattr(1) which does similar thing.
-// Returns whether operation succeeded.
-bool SetFileAttributes(const base::FilePath& path, FileAttributes flags) {
-  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid()) {
-    PLOG(ERROR) << "Failed to open file: " << path.value();
-    return false;
-  }
-  if (ioctl(file.GetPlatformFile(), FS_IOC_SETFLAGS, &flags) < 0) {
-    PLOG(ERROR) << "ioctl: " << path.value();
-    return false;
-  }
-  return true;
-}
-
-// Gets file attributes similarly to lsattr(1). Returns flags or -1 on error.
-// See linux/fs.h for the definition of the returned flags e.g. FS_NODUMP_FL.
-FileAttributes GetFileAttributes(const base::FilePath& path) {
-  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid()) {
-    PLOG(ERROR) << "Failed to open file: " << path.value();
-    return -1;
-  }
-  FileAttributes flags = 0;
-  if (ioctl(file.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) < 0) {
-    PLOG(ERROR) << "ioctl: " << path.value();
-    return -1;
-  }
-  return flags;
-}
-
-// Marks the cache file to be removable by cryptohome, or do nothing if
-// underlying filesystem doesn't support file attributes, as tmpfs for ephemeral
-// mode.
-bool SetRemovable(const base::FilePath& path) {
-  // For ephemeral mode.
-  if (!IsFileAttributesSupported(path)) {
-    return true;
-  }
-  FileAttributes flags = GetFileAttributes(path);
-  bool xattr = flags >= 0 && SetFileAttributes(path, flags | FS_NODUMP_FL);
-  bool fattr = SetExtendedFileAttributes(
-      path, FileCache::kGCacheRemovableAttribute, "1");
-  return xattr || fattr;
-}
-
-// Marks the cache file to be unremovable by cryptohome, or do nothing if
-// underlying filesystem doesn't support file attributes, as tmpfs for ephemeral
-// mode.
-bool UnsetRemovable(const base::FilePath& path) {
-  // For ephemeral mode.
-  if (!IsFileAttributesSupported(path)) {
-    return true;
-  }
-  FileAttributes flags = GetFileAttributes(path);
-  bool xattr = flags >= 0 && SetFileAttributes(path, flags & ~FS_NODUMP_FL);
-  bool fattr =
-      UnsetExtendedFileAttributes(path, FileCache::kGCacheRemovableAttribute);
-  return xattr || fattr;
-}
-
-// Marks |path| as drive cache dir, or do nothing if underlying filesystem
-// doesn't support file attributes, as tmpfs for ephemeral mode. Returns if the
-// operation succeeded.
-bool MarkAsDriveCacheDir(const base::FilePath& path) {
-  // For ephemeral mode.
-  if (!IsFileAttributesSupported(path)) {
-    return true;
-  }
-  return SetRemovable(path)
-      && SetExtendedFileAttributes(path, FileCache::kGCacheFilesAttribute, "");
-}
-
-class CacheInfoLatestCompare {
- public:
-  bool operator()(const CacheInfo& info_a, const CacheInfo& info_b) {
-    return info_a.first.last_accessed < info_b.first.last_accessed;
-  }
-};
-
-// Returns true if the cache file is present.
-bool IsPresent(const ResourceEntry& entry) {
-  return entry.has_file_specific_info() &&
-         entry.file_specific_info().has_cache_state() &&
-         entry.file_specific_info().cache_state().is_present();
-}
-
-const size_t kMaxNumOfEvictedCacheFiles = 30000;
-
-}  // namespace
-
-// static
-const char FileCache::kGCacheFilesAttribute[] = "user.GCacheFiles";
-const char FileCache::kGCacheRemovableAttribute[] = "user.GCacheRemovable";
-
-FileCache::FileCache(ResourceMetadataStorage* storage,
-                     const base::FilePath& cache_file_directory,
-                     base::SequencedTaskRunner* blocking_task_runner,
-                     FreeDiskSpaceGetterInterface* free_disk_space_getter)
-    : cache_file_directory_(cache_file_directory),
-      blocking_task_runner_(blocking_task_runner),
-      storage_(storage),
-      free_disk_space_getter_(free_disk_space_getter),
-      max_num_of_evicted_cache_files_(kMaxNumOfEvictedCacheFiles) {
-  DCHECK(blocking_task_runner_.get());
-}
-
-FileCache::~FileCache() {
-  // Must be on the sequenced worker pool, as |metadata_| must be deleted on
-  // the sequenced worker pool.
-  AssertOnSequencedWorkerPool();
-}
-
-void FileCache::SetMaxNumOfEvictedCacheFilesForTest(
-    size_t max_num_of_evicted_cache_files) {
-  max_num_of_evicted_cache_files_ = max_num_of_evicted_cache_files;
-}
-
-base::FilePath FileCache::GetCacheFilePath(const std::string& id) const {
-  return GetPathForId(cache_file_directory_, id);
-}
-
-void FileCache::AssertOnSequencedWorkerPool() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-}
-
-bool FileCache::IsUnderFileCacheDirectory(const base::FilePath& path) const {
-  return cache_file_directory_.IsParent(path);
-}
-
-bool FileCache::FreeDiskSpaceIfNeededFor(int64_t num_bytes) {
-  AssertOnSequencedWorkerPool();
-
-  // Do nothing and return if we have enough space.
-  if (GetAvailableSpace() >= num_bytes)
-    return true;
-
-  // Otherwise, try to free up the disk space.
-  DVLOG(1) << "Freeing up disk space for " << num_bytes;
-
-  // Remove all files which have no corresponding cache entries.
-  base::FileEnumerator enumerator(cache_file_directory_,
-                                  false,  // not recursive
-                                  base::FileEnumerator::FILES);
-  ResourceEntry entry;
-  for (base::FilePath current = enumerator.Next(); !current.empty();
-       current = enumerator.Next()) {
-    const std::string id = GetIdFromPath(current);
-    const FileError error = storage_->GetEntry(id, &entry);
-
-    if (error == FILE_ERROR_NOT_FOUND)
-      base::DeleteFile(current, false /* recursive */);
-    else if (error != FILE_ERROR_OK)
-      return false;
-  }
-
-  // Check available space again. If we have enough space here, do nothing.
-  const int64_t available_space = GetAvailableSpace();
-  if (available_space >= num_bytes)
-    return true;
-
-  const int64_t requested_space = num_bytes - available_space;
-
-  // Put all entries in priority queue where latest entry becomes top.
-  std::priority_queue<CacheInfo, std::vector<CacheInfo>, CacheInfoLatestCompare>
-      cache_info_queue;
-  std::unique_ptr<ResourceMetadataStorage::Iterator> it =
-      storage_->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (IsEvictable(it->GetID(), it->GetValue())) {
-      const ResourceEntry& entry = it->GetValue();
-
-      const base::FilePath& cache_path = GetCacheFilePath(entry.local_id());
-      base::File::Info info;
-      // If it fails to get file info of |cache_path|, use default value as its
-      // file info. i.e. the file becomes least recently used one.
-      base::GetFileInfo(cache_path, &info);
-
-      CacheInfo cache_info = std::make_pair(info, entry);
-
-      if (cache_info_queue.size() < max_num_of_evicted_cache_files_) {
-        cache_info_queue.push(cache_info);
-      } else if (cache_info_queue.size() >= max_num_of_evicted_cache_files_ &&
-                 cache_info.first.last_accessed <
-                     cache_info_queue.top().first.last_accessed) {
-        // Do not enqueue more than max_num_of_evicted_cache_files_ not to use
-        // up memory with this queue.
-        cache_info_queue.pop();
-        cache_info_queue.push(cache_info);
-      }
-    }
-  }
-  if (it->HasError())
-    return false;
-
-  // Copy entries to the vector. This becomes last-accessed desc order.
-  std::vector<CacheInfo> cache_info_list;
-  while (!cache_info_queue.empty()) {
-    cache_info_list.push_back(cache_info_queue.top());
-    cache_info_queue.pop();
-  }
-
-  // Update DB and delete files with accessing to the vector in ascending order.
-  int64_t evicted_cache_size = 0;
-  auto iter = cache_info_list.rbegin();
-  while (evicted_cache_size < requested_space &&
-         iter != cache_info_list.rend()) {
-    const CacheInfo& cache_info = *iter;
-
-    // Update DB.
-    ResourceEntry entry = cache_info.second;
-    entry.mutable_file_specific_info()->clear_cache_state();
-    storage_->PutEntry(entry);
-
-    // Delete cache file.
-    const base::FilePath& path = GetCacheFilePath(entry.local_id());
-
-    if (base::DeleteFile(path, false /* recursive */))
-      evicted_cache_size += cache_info.first.size;
-
-    ++iter;
-  }
-
-  // Check the disk space again.
-  return GetAvailableSpace() >= num_bytes;
-}
-
-int64_t FileCache::CalculateCacheSize() {
-  AssertOnSequencedWorkerPool();
-
-  int64_t total_cache_size = 0;
-  int64_t cache_size = 0;
-
-  std::unique_ptr<ResourceMetadataStorage::Iterator> it =
-      storage_->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (IsPresent(it->GetValue()) &&
-        base::GetFileSize(GetCacheFilePath(it->GetID()), &cache_size)) {
-      DCHECK_GE(cache_size, 0);
-      total_cache_size += cache_size;
-    }
-  }
-
-  if (it->HasError())
-    return 0;
-
-  return total_cache_size;
-}
-
-int64_t FileCache::CalculateEvictableCacheSize() {
-  AssertOnSequencedWorkerPool();
-
-  int64_t evictable_cache_size = 0;
-  int64_t cache_size = 0;
-
-  std::unique_ptr<ResourceMetadataStorage::Iterator> it =
-      storage_->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (IsEvictable(it->GetID(), it->GetValue()) &&
-        base::GetFileSize(GetCacheFilePath(it->GetID()), &cache_size)) {
-      DCHECK_GE(cache_size, 0);
-      evictable_cache_size += cache_size;
-    }
-  }
-
-  if (it->HasError())
-    return 0;
-
-  return evictable_cache_size;
-}
-
-FileError FileCache::GetFile(const std::string& id,
-                             base::FilePath* cache_file_path) {
-  AssertOnSequencedWorkerPool();
-  DCHECK(cache_file_path);
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().cache_state().is_present())
-    return FILE_ERROR_NOT_FOUND;
-
-  *cache_file_path = GetCacheFilePath(id);
-  return FILE_ERROR_OK;
-}
-
-FileError FileCache::Store(const std::string& id,
-                           const std::string& md5,
-                           const base::FilePath& source_path,
-                           FileOperationType file_operation_type) {
-  AssertOnSequencedWorkerPool();
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  int64_t file_size = 0;
-  if (file_operation_type == FILE_OPERATION_COPY) {
-    if (!base::GetFileSize(source_path, &file_size)) {
-      LOG(WARNING) << "Couldn't get file size for: " << source_path.value();
-      return FILE_ERROR_FAILED;
-    }
-  }
-  if (!FreeDiskSpaceIfNeededFor(file_size))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  // If file is mounted, return error.
-  if (mounted_files_.count(id))
-    return FILE_ERROR_IN_USE;
-
-  base::FilePath dest_path = GetCacheFilePath(id);
-  bool success = false;
-  switch (file_operation_type) {
-    case FILE_OPERATION_MOVE:
-      success = base::Move(source_path, dest_path);
-      break;
-    case FILE_OPERATION_COPY:
-      success = base::CopyFile(source_path, dest_path);
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  if (!success) {
-    LOG(ERROR) << "Failed to store: "
-               << "source_path = " << source_path.value() << ", "
-               << "dest_path = " << dest_path.value() << ", "
-               << "file_operation_type = " << file_operation_type;
-    return FILE_ERROR_FAILED;
-  }
-
-  // Now that file operations have completed, update metadata.
-  FileCacheEntry* cache_state =
-      entry.mutable_file_specific_info()->mutable_cache_state();
-  cache_state->set_md5(md5);
-  cache_state->set_is_present(true);
-  if (md5.empty())
-    cache_state->set_is_dirty(true);
-
-  if (!cache_state->is_pinned() && !cache_state->is_dirty()) {
-    if (!SetRemovable(dest_path))
-      return FILE_ERROR_FAILED;
-  } else {
-    if (!UnsetRemovable(dest_path))
-      return FILE_ERROR_FAILED;
-  }
-
-  return storage_->PutEntry(entry);
-}
-
-FileError FileCache::Pin(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  entry.mutable_file_specific_info()->mutable_cache_state()->set_is_pinned(
-      true);
-
-  base::FilePath file_path = GetCacheFilePath(entry.local_id());
-  // Cache file can be created later.
-  if (entry.file_specific_info().cache_state().is_present()) {
-    if (!UnsetRemovable(file_path))
-      return FILE_ERROR_FAILED;
-  }
-
-  return storage_->PutEntry(entry);
-}
-
-FileError FileCache::Unpin(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  // Unpinning a file means its entry must exist in cache.
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  // Now that file operations have completed, update metadata.
-  if (entry.file_specific_info().cache_state().is_present()) {
-    entry.mutable_file_specific_info()->mutable_cache_state()->set_is_pinned(
-        false);
-    if (!entry.file_specific_info().cache_state().is_dirty()) {
-      if (!SetRemovable(GetCacheFilePath(entry.local_id())))
-        return FILE_ERROR_FAILED;
-    }
-  } else {
-    // Remove the existing entry if we are unpinning a non-present file.
-    entry.mutable_file_specific_info()->clear_cache_state();
-  }
-  error = storage_->PutEntry(entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  // Now it's a chance to free up space if needed.
-  FreeDiskSpaceIfNeededFor(0);
-
-  return FILE_ERROR_OK;
-}
-
-bool FileCache::IsMarkedAsMounted(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-  return mounted_files_.count(id);
-}
-
-FileError FileCache::MarkAsMounted(const std::string& id,
-                                   base::FilePath* cache_file_path) {
-  AssertOnSequencedWorkerPool();
-  DCHECK(cache_file_path);
-
-  // Get cache entry associated with the id and md5
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().cache_state().is_present())
-    return FILE_ERROR_NOT_FOUND;
-
-  if (mounted_files_.count(id))
-    return FILE_ERROR_INVALID_OPERATION;
-
-  base::FilePath path = GetCacheFilePath(id);
-
-#if defined(OS_CHROMEOS)
-  // Ensure the file is readable to cros_disks. See crbug.com/236994.
-  if (!base::SetPosixFilePermissions(
-          path,
-          base::FILE_PERMISSION_READ_BY_USER |
-          base::FILE_PERMISSION_WRITE_BY_USER |
-          base::FILE_PERMISSION_READ_BY_GROUP |
-          base::FILE_PERMISSION_READ_BY_OTHERS))
-    return FILE_ERROR_FAILED;
-#endif
-
-  mounted_files_.insert(id);
-
-  *cache_file_path = path;
-  return FILE_ERROR_OK;
-}
-
-FileError FileCache::OpenForWrite(
-    const std::string& id,
-    std::unique_ptr<base::ScopedClosureRunner>* file_closer) {
-  AssertOnSequencedWorkerPool();
-
-  // Marking a file dirty means its entry and actual file blob must exist in
-  // cache.
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().cache_state().is_present()) {
-    LOG(WARNING) << "Can't mark dirty a file that wasn't cached: " << id;
-    return FILE_ERROR_NOT_FOUND;
-  }
-
-  entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(true);
-  if (!UnsetRemovable(GetCacheFilePath(entry.local_id())))
-    return FILE_ERROR_FAILED;
-
-  entry.mutable_file_specific_info()->mutable_cache_state()->clear_md5();
-  error = storage_->PutEntry(entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  write_opened_files_[id]++;
-  *file_closer = std::make_unique<base::ScopedClosureRunner>(
-      base::Bind(&google_apis::RunTaskWithTaskRunner, blocking_task_runner_,
-                 base::Bind(&FileCache::CloseForWrite,
-                            weak_ptr_factory_.GetWeakPtr(), id)));
-  return FILE_ERROR_OK;
-}
-
-bool FileCache::IsOpenedForWrite(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-  return write_opened_files_.count(id) != 0;
-}
-
-FileError FileCache::UpdateMd5(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  if (IsOpenedForWrite(id))
-    return FILE_ERROR_IN_USE;
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().cache_state().is_present())
-    return FILE_ERROR_NOT_FOUND;
-
-  const std::string& md5 =
-      util::GetMd5Digest(GetCacheFilePath(id), &in_shutdown_);
-  if (in_shutdown_.IsSet())
-    return FILE_ERROR_ABORT;
-  if (md5.empty())
-    return FILE_ERROR_NOT_FOUND;
-
-  entry.mutable_file_specific_info()->mutable_cache_state()->set_md5(md5);
-  return storage_->PutEntry(entry);
-}
-
-FileError FileCache::ClearDirty(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  if (IsOpenedForWrite(id))
-    return FILE_ERROR_IN_USE;
-
-  // Clearing a dirty file means its entry and actual file blob must exist in
-  // cache.
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().cache_state().is_present()) {
-    LOG(WARNING) << "Can't clear dirty state of a file that wasn't cached: "
-                 << id;
-    return FILE_ERROR_NOT_FOUND;
-  }
-
-  // If a file is not dirty (it should have been marked dirty via OpenForWrite),
-  // clearing its dirty state is an invalid operation.
-  if (!entry.file_specific_info().cache_state().is_dirty()) {
-    LOG(WARNING) << "Can't clear dirty state of a non-dirty file: " << id;
-    return FILE_ERROR_INVALID_OPERATION;
-  }
-
-  entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(
-      false);
-  if (!entry.file_specific_info().cache_state().is_pinned()) {
-    if (!SetRemovable(GetCacheFilePath(entry.local_id())))
-      return FILE_ERROR_FAILED;
-  }
-
-  return storage_->PutEntry(entry);
-}
-
-FileError FileCache::Remove(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  ResourceEntry entry;
-
-  // If entry doesn't exist, nothing to do.
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error == FILE_ERROR_NOT_FOUND)
-    return FILE_ERROR_OK;
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!entry.file_specific_info().has_cache_state())
-    return FILE_ERROR_OK;
-
-  // Cannot delete a mounted file.
-  if (mounted_files_.count(id))
-    return FILE_ERROR_IN_USE;
-
-  // Delete the file.
-  base::FilePath path = GetCacheFilePath(id);
-  if (!base::DeleteFile(path, false /* recursive */))
-    return FILE_ERROR_FAILED;
-
-  // Now that all file operations have completed, remove from metadata.
-  entry.mutable_file_specific_info()->clear_cache_state();
-  return storage_->PutEntry(entry);
-}
-
-bool FileCache::ClearAll() {
-  AssertOnSequencedWorkerPool();
-
-  // Remove files.
-  base::FileEnumerator enumerator(cache_file_directory_,
-                                  false,  // not recursive
-                                  base::FileEnumerator::FILES);
-  for (base::FilePath file = enumerator.Next(); !file.empty();
-       file = enumerator.Next())
-    base::DeleteFile(file, false /* recursive */);
-
-  return true;
-}
-
-bool FileCache::Initialize() {
-  AssertOnSequencedWorkerPool();
-
-  // Older versions do not clear MD5 when marking entries dirty.
-  // Clear MD5 of all dirty entries to deal with old data.
-  std::unique_ptr<ResourceMetadataStorage::Iterator> it =
-      storage_->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (it->GetValue().file_specific_info().cache_state().is_dirty()) {
-      ResourceEntry new_entry(it->GetValue());
-      new_entry.mutable_file_specific_info()->mutable_cache_state()->
-          clear_md5();
-      if (storage_->PutEntry(new_entry) != FILE_ERROR_OK)
-        return false;
-    }
-  }
-  if (it->HasError())
-    return false;
-
-  if (!RenameCacheFilesToNewFormat())
-    return false;
-
-  // Run this every time to resolve inconsistency between metadata
-  // and file attributes which possibly occurs on abrupt power failure.
-  if (!FixMetadataAndFileAttributes()) {
-    return false;
-  }
-
-  return true;
-}
-
-void FileCache::Destroy() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  in_shutdown_.Set();
-
-  // Destroy myself on the blocking pool.
-  // Note that base::DeletePointer<> cannot be used as the destructor of this
-  // class is private.
-  blocking_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&FileCache::DestroyOnBlockingPool,
-                                base::Unretained(this)));
-}
-
-void FileCache::DestroyOnBlockingPool() {
-  AssertOnSequencedWorkerPool();
-  delete this;
-}
-
-bool FileCache::RecoverFilesFromCacheDirectory(
-    const base::FilePath& dest_directory,
-    const ResourceMetadataStorage::RecoveredCacheInfoMap&
-        recovered_cache_info) {
-  int file_number = 1;
-
-  base::FileEnumerator enumerator(cache_file_directory_,
-                                  false,  // not recursive
-                                  base::FileEnumerator::FILES);
-  for (base::FilePath current = enumerator.Next(); !current.empty();
-       current = enumerator.Next()) {
-    const std::string& id = GetIdFromPath(current);
-    ResourceEntry entry;
-    FileError error = storage_->GetEntry(id, &entry);
-    if (error != FILE_ERROR_OK && error != FILE_ERROR_NOT_FOUND)
-      return false;
-    if (error == FILE_ERROR_OK &&
-        entry.file_specific_info().cache_state().is_present()) {
-      // This file is managed by FileCache, no need to recover it.
-      continue;
-    }
-
-    // If a cache entry which is non-dirty and has matching MD5 is found in
-    // |recovered_cache_entries|, it means the current file is already uploaded
-    // to the server. Just delete it instead of recovering it.
-    ResourceMetadataStorage::RecoveredCacheInfoMap::const_iterator it =
-        recovered_cache_info.find(id);
-    if (it != recovered_cache_info.end()) {
-      // Due to the DB corruption, cache info might be recovered from old
-      // revision. Perform MD5 check even when is_dirty is false just in case.
-      if (!it->second.is_dirty &&
-          it->second.md5 == util::GetMd5Digest(current, &in_shutdown_)) {
-        base::DeleteFile(current, false /* recursive */);
-        continue;
-      }
-    }
-
-    // Read file contents to sniff mime type.
-    std::vector<char> content(net::kMaxBytesToSniff);
-    const int read_result =
-        base::ReadFile(current, &content[0], content.size());
-    if (read_result < 0) {
-      LOG(WARNING) << "Cannot read: " << current.value();
-      return false;
-    }
-    if (read_result == 0)  // Skip empty files.
-      continue;
-
-    // Use recovered file name if available, otherwise decide file name with
-    // sniffed mime type.
-    base::FilePath dest_base_name(FILE_PATH_LITERAL("file"));
-    std::string mime_type;
-    if (it != recovered_cache_info.end() && !it->second.title.empty()) {
-      // We can use a file name recovered from the trashed DB.
-      dest_base_name = base::FilePath::FromUTF8Unsafe(it->second.title);
-    } else if (net::SniffMimeType(
-                   &content[0], read_result, net::FilePathToFileURL(current),
-                   std::string(), net::ForceSniffFileUrlsForHtml::kDisabled,
-                   &mime_type) ||
-               net::SniffMimeTypeFromLocalData(&content[0], read_result,
-                                               &mime_type)) {
-      // Change base name for common mime types.
-      if (net::MatchesMimeType("image/*", mime_type)) {
-        dest_base_name = base::FilePath(FILE_PATH_LITERAL("image"));
-      } else if (net::MatchesMimeType("video/*", mime_type)) {
-        dest_base_name = base::FilePath(FILE_PATH_LITERAL("video"));
-      } else if (net::MatchesMimeType("audio/*", mime_type)) {
-        dest_base_name = base::FilePath(FILE_PATH_LITERAL("audio"));
-      }
-
-      // Estimate extension from mime type.
-      std::vector<base::FilePath::StringType> extensions;
-      base::FilePath::StringType extension;
-      if (net::GetPreferredExtensionForMimeType(mime_type, &extension))
-        extensions.push_back(extension);
-      else
-        net::GetExtensionsForMimeType(mime_type, &extensions);
-
-      // Add extension if possible.
-      if (!extensions.empty())
-        dest_base_name = dest_base_name.AddExtension(extensions[0]);
-    }
-
-    // Add file number to the file name and move.
-    const base::FilePath& dest_path = dest_directory.Append(dest_base_name)
-        .InsertBeforeExtensionASCII(base::StringPrintf("%08d", file_number++));
-    if (!base::CreateDirectory(dest_directory) ||
-        !base::Move(current, dest_path)) {
-      LOG(WARNING) << "Failed to move: " << current.value()
-                   << " to " << dest_path.value();
-      return false;
-    }
-  }
-  UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfCacheFilesRecoveredAfterDBCorruption",
-                          file_number - 1);
-  return true;
-}
-
-FileError FileCache::MarkAsUnmounted(const base::FilePath& file_path) {
-  AssertOnSequencedWorkerPool();
-  DCHECK(IsUnderFileCacheDirectory(file_path));
-
-  std::string id = GetIdFromPath(file_path);
-
-  // Get the entry associated with the id.
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  std::set<std::string>::iterator it = mounted_files_.find(id);
-  if (it == mounted_files_.end())
-    return FILE_ERROR_INVALID_OPERATION;
-
-  mounted_files_.erase(it);
-  return FILE_ERROR_OK;
-}
-
-int64_t FileCache::GetAvailableSpace() {
-  int64_t free_space = 0;
-  if (free_disk_space_getter_)
-    free_space = free_disk_space_getter_->AmountOfFreeDiskSpace();
-  else
-    free_space = base::SysInfo::AmountOfFreeDiskSpace(cache_file_directory_);
-
-  // Subtract this as if this portion does not exist.
-  free_space -= drive::internal::kMinFreeSpaceInBytes;
-  return free_space;
-}
-
-bool FileCache::RenameCacheFilesToNewFormat() {
-  base::FileEnumerator enumerator(cache_file_directory_,
-                                  false,  // not recursive
-                                  base::FileEnumerator::FILES);
-  for (base::FilePath current = enumerator.Next(); !current.empty();
-       current = enumerator.Next()) {
-    base::FilePath new_path = current.RemoveExtension();
-    if (!new_path.Extension().empty()) {
-      // Delete files with multiple extensions.
-      if (!base::DeleteFile(current, false /* recursive */))
-        return false;
-      continue;
-    }
-    const std::string& id = GetIdFromPath(new_path);
-    new_path = GetCacheFilePath(util::CanonicalizeResourceId(id));
-    if (new_path != current && !base::Move(current, new_path))
-      return false;
-  }
-  return true;
-}
-
-bool FileCache::FixMetadataAndFileAttributes() {
-  std::unique_ptr<ResourceMetadataStorage::Iterator> it =
-      storage_->GetIterator();
-
-  for (; !it->IsAtEnd(); it->Advance()) {
-    ResourceEntry entry = it->GetValue();
-    FileCacheEntry* file_cache_entry =
-        entry.mutable_file_specific_info()->mutable_cache_state();
-
-    const base::FilePath filepath = GetPathForId(cache_file_directory_,
-        entry.local_id());
-
-    if (base::PathExists(filepath)) {
-      if (file_cache_entry->is_present()) {
-        // Update file attribues for cryptohome.
-        if (file_cache_entry->is_pinned() || file_cache_entry->is_dirty()) {
-          if (!UnsetRemovable(filepath)) return false;
-        } else {
-          if (!SetRemovable(filepath)) return false;
-        }
-      } else {
-        // Delete file if the file is present but metadata says not.
-        // It happens only on abrupt shutdown.
-        LOG(WARNING)
-            << "File is present but metadata's state was inconsistent.";
-
-        if (!base::DeleteFile(filepath, false /* recursive */))
-          return false;
-      }
-    } else {
-      // Update metatadata if there is no file but metadata says there is.
-      // It happens when cryptohome removed the file.
-      // We don't clear is_pinned here, so that file download is restarted on
-      // the following scenario:
-      //  1. The file was pinned but not present.
-      //  2. Then the file was downloaded and became present.
-      //  3. Unclean shutdown happens, metadata update was saved to the disk,
-      //     but the file move was not.
-      if (file_cache_entry->is_present()) {
-        file_cache_entry->set_is_present(false);
-        file_cache_entry->set_is_dirty(false);
-        file_cache_entry->clear_md5();
-        if (storage_->PutEntry(entry) != FILE_ERROR_OK)
-          return false;
-      }
-    }
-  }
-
-  return MarkAsDriveCacheDir(cache_file_directory_);
-}
-
-void FileCache::CloseForWrite(const std::string& id) {
-  AssertOnSequencedWorkerPool();
-
-  std::map<std::string, int>::iterator it = write_opened_files_.find(id);
-  if (it == write_opened_files_.end())
-    return;
-
-  DCHECK_LT(0, it->second);
-  --it->second;
-  if (it->second == 0)
-    write_opened_files_.erase(it);
-
-  // Update last modified date.
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK) {
-    LOG(ERROR) << "Failed to get entry: " << id << ", "
-               << FileErrorToString(error);
-    return;
-  }
-  int64_t now = base::Time::Now().ToInternalValue();
-  entry.mutable_file_info()->set_last_modified(now);
-  entry.set_last_modified_by_me(now);
-  error = storage_->PutEntry(entry);
-  if (error != FILE_ERROR_OK) {
-    LOG(ERROR) << "Failed to put entry: " << id << ", "
-               << FileErrorToString(error);
-  }
-}
-
-bool FileCache::IsEvictable(const std::string& id, const ResourceEntry& entry) {
-  return IsPresent(entry) &&
-         !entry.file_specific_info().cache_state().is_pinned() &&
-         !entry.file_specific_info().cache_state().is_dirty() &&
-         !mounted_files_.count(id);
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/file_cache.h b/components/drive/chromeos/file_cache.h
deleted file mode 100644
index 8269719d..0000000
--- a/components/drive/chromeos/file_cache.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_
-#define COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/atomic_flag.h"
-#include "base/threading/thread_checker.h"
-#include "build/build_config.h"
-#include "components/drive/file_errors.h"
-#include "components/drive/resource_metadata_storage.h"
-#if defined(OS_CHROMEOS)
-#include "third_party/cros_system_api/constants/cryptohome.h"
-#endif
-
-namespace base {
-class ScopedClosureRunner;
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace drive {
-
-namespace internal {
-
-#if defined(OS_CHROMEOS)
-const int64_t kMinFreeSpaceInBytes = cryptohome::kMinFreeSpaceInBytes;
-#else
-const int64_t kMinFreeSpaceInBytes = 512ull * 1024ull * 1024ull;  // 512MB
-#endif
-
-// Interface class used for getting the free disk space. Tests can inject an
-// implementation that reports fake free disk space.
-class FreeDiskSpaceGetterInterface {
- public:
-  virtual ~FreeDiskSpaceGetterInterface() = default;
-  virtual int64_t AmountOfFreeDiskSpace() = 0;
-};
-
-// FileCache is used to maintain cache states of FileSystem.
-//
-// All non-static public member functions, unless mentioned otherwise (see
-// GetCacheFilePath() for example), should be run with |blocking_task_runner|.
-class FileCache {
- public:
-  // The file extended attribute assigned to Drive cache directory.
-  static const char kGCacheFilesAttribute[];
-  // The file extended attribute assigned to files that can be removed.
-  static const char kGCacheRemovableAttribute[];
-
-  // Enum defining type of file operation e.g. copy or move, etc.
-  enum FileOperationType {
-    FILE_OPERATION_MOVE = 0,
-    FILE_OPERATION_COPY,
-  };
-
-  // |cache_file_directory| stores cached files.
-  //
-  // |blocking_task_runner| indicates the blocking worker pool for cache
-  // operations. All operations on this FileCache must be run on this runner.
-  // Must not be null.
-  //
-  // |free_disk_space_getter| is used to inject a custom free disk space
-  // getter for testing. NULL must be passed for production code.
-  //
-  // Must be called on the UI thread.
-  FileCache(ResourceMetadataStorage* storage,
-            const base::FilePath& cache_file_directory,
-            base::SequencedTaskRunner* blocking_task_runner,
-            FreeDiskSpaceGetterInterface* free_disk_space_getter);
-
-  // Sets maximum number of evicted cache files for test.
-  void SetMaxNumOfEvictedCacheFilesForTest(
-      size_t max_num_of_evicted_cache_files);
-
-  // Returns true if the given path is under drive cache directory, i.e.
-  // <user_profile_dir>/GCache/v1
-  //
-  // Can be called on any thread.
-  bool IsUnderFileCacheDirectory(const base::FilePath& path) const;
-
-  // Frees up disk space to store a file with |num_bytes| size content, while
-  // keeping drive::internal::kMinFreeSpaceInBytes bytes on the disk, if needed.
-  // Returns true if we successfully manage to have enough space, otherwise
-  // false.
-  bool FreeDiskSpaceIfNeededFor(int64_t num_bytes);
-
-  // Calculates and returns cache size. In error case, this returns 0.
-  int64_t CalculateCacheSize();
-
-  // Calculates and returns evictable cache size. In error case, this returns 0.
-  int64_t CalculateEvictableCacheSize();
-
-  // Checks if file corresponding to |id| exists in cache, and returns
-  // FILE_ERROR_OK with |cache_file_path| storing the path to the file.
-  // |cache_file_path| must not be null.
-  FileError GetFile(const std::string& id, base::FilePath* cache_file_path);
-
-  // Stores |source_path| as a cache of the remote content of the file
-  // with |id| and |md5|.
-  // Pass an empty string as MD5 to mark the entry as dirty.
-  FileError Store(const std::string& id,
-                  const std::string& md5,
-                  const base::FilePath& source_path,
-                  FileOperationType file_operation_type);
-
-  // Pins the specified entry.
-  FileError Pin(const std::string& id);
-
-  // Unpins the specified entry.
-  FileError Unpin(const std::string& id);
-
-  // Sets the state of the cache entry corresponding to |id| as mounted.
-  FileError MarkAsMounted(const std::string& id,
-                          base::FilePath* cache_file_path);
-
-  // Returns if a file corresponding to |id| is marked as mounted.
-  bool IsMarkedAsMounted(const std::string& id);
-
-  // Sets the state of the cache entry corresponding to file_path as unmounted.
-  FileError MarkAsUnmounted(const base::FilePath& file_path);
-
-  // Opens the cache file corresponding to |id| for write. |file_closer| should
-  // be kept alive until writing finishes.
-  // This method must be called before writing to cache files.
-  FileError OpenForWrite(
-      const std::string& id,
-      std::unique_ptr<base::ScopedClosureRunner>* file_closer);
-
-  // Returns true if the cache file corresponding to |id| is write-opened.
-  bool IsOpenedForWrite(const std::string& id);
-
-  // Calculates MD5 of the cache file and updates the stored value.
-  FileError UpdateMd5(const std::string& id);
-
-  // Clears dirty state of the specified entry.
-  FileError ClearDirty(const std::string& id);
-
-  // Removes the specified cache entry and delete cache files if available.
-  FileError Remove(const std::string& id);
-
-  // Removes all the files in the cache directory.
-  bool ClearAll();
-
-  // Initializes the cache. Returns true on success.
-  bool Initialize();
-
-  // Destroys this cache. This function posts a task to the blocking task
-  // runner to safely delete the object.
-  // Must be called on the UI thread.
-  void Destroy();
-
-  // Moves files in the cache directory which are not managed by FileCache to
-  // |dest_directory|.
-  // |recovered_cache_info| should contain cache info recovered from the trashed
-  // metadata DB. It is used to ignore non-dirty files.
-  bool RecoverFilesFromCacheDirectory(
-      const base::FilePath& dest_directory,
-      const ResourceMetadataStorage::RecoveredCacheInfoMap&
-          recovered_cache_info);
-
- private:
-  friend class FileCacheTest;
-
-  ~FileCache();
-
-  // Returns absolute path of the file if it were cached or to be cached.
-  //
-  // Can be called on any thread.
-  base::FilePath GetCacheFilePath(const std::string& id) const;
-
-  // Checks whether the current thread is on the right sequenced worker pool
-  // with the right sequence ID. If not, DCHECK will fail.
-  void AssertOnSequencedWorkerPool();
-
-  // Destroys the cache on the blocking pool.
-  void DestroyOnBlockingPool();
-
-  // Returns available space, while keeping
-  // drive::internal::kMinFreeSpaceInBytes bytes on the disk.
-  int64_t GetAvailableSpace();
-
-  // Renames cache files from old "prefix:id.md5" format to the new format.
-  // TODO(hashimoto): Remove this method at some point.
-  bool RenameCacheFilesToNewFormat();
-
-  // Adds appropriate file attributes to the Drive cache directory and files in
-  // it for crbug.com/533750. Returns true on success.
-  // This also resolves inconsistency between cache files and metadata which can
-  // be produced when cryptohome removed cache files or on abrupt shutdown.
-  bool FixMetadataAndFileAttributes();
-
-  // This method must be called after writing to a cache file.
-  // Used to implement OpenForWrite().
-  void CloseForWrite(const std::string& id);
-
-  // Returns true if the cache entry can be evicted.
-  bool IsEvictable(const std::string& id, const ResourceEntry& entry);
-
-  const base::FilePath cache_file_directory_;
-
-  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-
-  base::AtomicFlag in_shutdown_;
-
-  ResourceMetadataStorage* storage_;
-
-  FreeDiskSpaceGetterInterface* free_disk_space_getter_;  // Not owned.
-
-  // Maximum number of cache files which can be evicted by a single call of
-  // FreeDiskSpaceIfNeededFor. That method takes O(n) memory space, we need to
-  // set this value not to use up memory.
-  size_t max_num_of_evicted_cache_files_;
-
-  // IDs of files being write-opened.
-  std::map<std::string, int> write_opened_files_;
-
-  // IDs of files marked mounted.
-  std::set<std::string> mounted_files_;
-
-  THREAD_CHECKER(thread_checker_);
-
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  // This object should be accessed only on |blocking_task_runner_|.
-  base::WeakPtrFactory<FileCache> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(FileCache);
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_
diff --git a/components/drive/chromeos/file_cache_unittest.cc b/components/drive/chromeos/file_cache_unittest.cc
deleted file mode 100644
index cbefa22..0000000
--- a/components/drive/chromeos/file_cache_unittest.cc
+++ /dev/null
@@ -1,902 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/file_cache.h"
-
-#include <linux/fs.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <sys/xattr.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback_helpers.h"
-#include "base/files/file.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/hash/md5.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-#include "components/drive/resource_metadata_storage.h"
-#include "content/public/test/browser_task_environment.h"
-#include "google_apis/drive/test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-typedef long FileAttributes;  // NOLINT(runtime/int)
-
-const base::FilePath::CharType kCacheFileDirectory[] =
-    FILE_PATH_LITERAL("files");
-
-const int kTemporaryFileSizeInBytes = 10;
-
-FileAttributes GetFileAttributes(const base::FilePath& file_path) {
-  base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid()) {
-    ADD_FAILURE() << "Failed to open file: " << file_path.value();
-    return -1;
-  }
-  FileAttributes flags = 0;
-  if (ioctl(file.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) < 0) {
-    ADD_FAILURE() << "Failed to get attributes: " << file_path.value();
-    return -1;
-  }
-  return flags;
-}
-
-bool HasRemovableFlag(const base::FilePath& file_path) {
-  return (GetFileAttributes(file_path) & FS_NODUMP_FL) == FS_NODUMP_FL;
-}
-
-bool HasRemovableAttribute(const base::FilePath& file_path) {
-  return getxattr(file_path.value().c_str(),
-                  FileCache::kGCacheRemovableAttribute, nullptr, 0) >= 0;
-}
-
-bool IsMarkedAsRemovable(const base::FilePath& path) {
-  return HasRemovableFlag(path) && HasRemovableAttribute(path);
-}
-
-}  // namespace
-
-// Tests FileCache methods working with the blocking task runner.
-class FileCacheTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta");
-    cache_files_dir_ = temp_dir_.GetPath().Append(kCacheFileDirectory);
-
-    ASSERT_TRUE(base::CreateDirectory(metadata_dir));
-    ASSERT_TRUE(base::CreateDirectory(cache_files_dir_));
-
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        metadata_dir,
-        base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_TRUE(metadata_storage_->Initialize());
-
-    cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_,
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-    ASSERT_TRUE(cache_->Initialize());
-  }
-
-  static bool RenameCacheFilesToNewFormat(FileCache* cache) {
-    return cache->RenameCacheFilesToNewFormat();
-  }
-
-  base::FilePath GetCacheFilePath(const std::string& id) {
-    return cache_->GetCacheFilePath(id);
-  }
-
-  base::FilePath AddTestEntry(const std::string id,
-                              const std::string md5,
-                              const time_t last_accessed,
-                              const base::FilePath& src_file) {
-    ResourceEntry entry;
-    entry.set_local_id(id);
-    entry.mutable_file_info()->set_last_accessed(last_accessed);
-    EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-    EXPECT_EQ(FILE_ERROR_OK,
-              cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
-
-    base::FilePath path;
-    EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &path));
-
-    // Update last modified and accessed time.
-    base::Time time = base::Time::FromTimeT(last_accessed);
-    EXPECT_TRUE(base::TouchFile(path, time, time));
-
-    return path;
-  }
-
-  content::BrowserTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-  base::FilePath cache_files_dir_;
-
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-};
-
-TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) {
-  base::FilePath dir_source_root;
-  EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
-  const base::FilePath src_path =
-      dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png");
-
-  // Store files. This file should not be moved.
-  ResourceEntry entry;
-  entry.set_local_id("id_foo");
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path,
-                                         FileCache::FILE_OPERATION_COPY));
-
-  // Set up files in the cache directory. These files should be moved.
-  const base::FilePath file_directory =
-      temp_dir_.GetPath().Append(kCacheFileDirectory);
-  ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_bar")));
-  ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_baz")));
-
-  // Insert a dirty entry with "id_baz" to |recovered_cache_info|.
-  // This should not prevent the file from being recovered.
-  ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info;
-  recovered_cache_info["id_baz"].is_dirty = true;
-  recovered_cache_info["id_baz"].title = "baz.png";
-
-  // Recover files.
-  const base::FilePath dest_directory = temp_dir_.GetPath().AppendASCII("dest");
-  EXPECT_TRUE(cache_->RecoverFilesFromCacheDirectory(dest_directory,
-                                                     recovered_cache_info));
-
-  // Only two files should be recovered.
-  EXPECT_TRUE(base::PathExists(dest_directory));
-  // base::FileEnumerator does not guarantee the order.
-  if (base::PathExists(dest_directory.AppendASCII("baz00000001.png"))) {
-    EXPECT_TRUE(base::ContentsEqual(
-        src_path,
-        dest_directory.AppendASCII("baz00000001.png")));
-    EXPECT_TRUE(base::ContentsEqual(
-        src_path,
-        dest_directory.AppendASCII("image00000002.png")));
-  } else {
-    EXPECT_TRUE(base::ContentsEqual(
-        src_path,
-        dest_directory.AppendASCII("image00000001.png")));
-    EXPECT_TRUE(base::ContentsEqual(
-        src_path,
-        dest_directory.AppendASCII("baz00000002.png")));
-  }
-  EXPECT_FALSE(base::PathExists(
-      dest_directory.AppendASCII("image00000003.png")));
-}
-
-TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) {
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-
-  // Store a file as a 'temporary' file and remember the path.
-  const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp";
-  const time_t last_accessed_tmp = 1;
-  const base::FilePath& tmp_path =
-      AddTestEntry(id_tmp, md5_tmp, last_accessed_tmp, src_file);
-
-  // Store a file as a pinned file and remember the path.
-  const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned";
-  const time_t last_accessed_pinned = 1;
-  const base::FilePath& pinned_path =
-      AddTestEntry(id_pinned, md5_pinned, last_accessed_pinned, src_file);
-  ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned));
-
-  // Call FreeDiskSpaceIfNeededFor().
-  fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
-  fake_free_disk_space_getter_->PushFakeValue(0);
-  fake_free_disk_space_getter_->PushFakeValue(0);
-  const int64_t kNeededBytes = 1;
-  EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
-
-  // Only 'temporary' file gets removed.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_tmp, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_FALSE(base::PathExists(tmp_path));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_TRUE(base::PathExists(pinned_path));
-
-  // Returns false when disk space cannot be freed.
-  fake_free_disk_space_getter_->set_default_value(0);
-  EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
-}
-
-TEST_F(FileCacheTest, EvictDriveCacheInLRU) {
-  // Create temporary file.
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-  ASSERT_EQ(kTemporaryFileSizeInBytes,
-            base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes));
-
-  // Add entries.
-  const std::string id_a = "id_a", md5_a = "md5_a";
-  const time_t last_accessed_a = 1;
-  const base::FilePath& a_path =
-      AddTestEntry(id_a, md5_a, last_accessed_a, src_file);
-
-  const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned";
-  const time_t last_accessed_pinned = 2;
-  const base::FilePath& pinned_path =
-      AddTestEntry(id_pinned, md5_pinned, last_accessed_pinned, src_file);
-  ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned));
-
-  const std::string id_b = "id_b", md5_b = "md5_b";
-  const time_t last_accessed_b = 3;
-  const base::FilePath& b_path =
-      AddTestEntry(id_b, md5_b, last_accessed_b, src_file);
-
-  const std::string id_c = "id_c", md5_c = "md5_c";
-  const time_t last_accessed_c = 4;
-  const base::FilePath& c_path =
-      AddTestEntry(id_c, md5_c, last_accessed_c, src_file);
-
-  // Call FreeDiskSpaceIfNeededFor.
-  fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
-  fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes);
-  fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes);
-  const int64_t kNeededBytes = kTemporaryFileSizeInBytes * 3 / 2;
-  EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
-
-  // Entry A is evicted.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_FALSE(base::PathExists(a_path));
-
-  // Pinned entry should not be evicted.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_TRUE(base::PathExists(pinned_path));
-
-  // Entry B is evicted.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_b, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_FALSE(base::PathExists(b_path));
-
-  // Entry C should not be evicted.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_c, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_TRUE(base::PathExists(c_path));
-}
-
-// Test case for deleting invalid cache files which don't have corresponding
-// metadata.
-TEST_F(FileCacheTest, EvictInvalidCacheFile) {
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-
-  // Add entries.
-  const std::string id_a = "id_a", md5_a = "md5_a";
-  const time_t last_accessed_a = 1;
-  const base::FilePath& a_path =
-      AddTestEntry(id_a, md5_a, last_accessed_a, src_file);
-
-  const std::string id_b = "id_b", md5_b = "md5_b";
-  const time_t last_accessed_b = 2;
-  const base::FilePath& b_path =
-      AddTestEntry(id_b, md5_b, last_accessed_b, src_file);
-
-  // Remove metadata of entry B.
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->RemoveEntry(id_b));
-
-  // Confirm cache file of entry B exists.
-  ASSERT_TRUE(base::PathExists(b_path));
-
-  // Run FreeDiskSpaceIfNeededFor.
-  fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
-  fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes);
-  const int64_t kNeededBytes = 1;
-  EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
-
-  // Entry A is not evicted.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_TRUE(base::PathExists(a_path));
-
-  // Entry B is evicted.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_storage_->GetEntry(id_b, &entry));
-  EXPECT_FALSE(base::PathExists(b_path));
-}
-
-TEST_F(FileCacheTest, TooManyCacheFiles) {
-  const size_t kMaxNumOfEvictedCacheFiles = 50;
-  cache_->SetMaxNumOfEvictedCacheFilesForTest(kMaxNumOfEvictedCacheFiles);
-
-  // Create temporary file.
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-  ASSERT_EQ(kTemporaryFileSizeInBytes,
-            base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes));
-
-  // Add kNumOfTestFiles=kMaxNumOfEvictedCacheFiles*2 entries.
-  std::vector<base::FilePath> paths;
-  const int32_t kNumOfTestFiles = kMaxNumOfEvictedCacheFiles * 2;
-  for (int i = 0; i < kNumOfTestFiles; ++i) {
-    // Set last accessed in reverse order to the file name. i.e. If you sort
-    // files in name-asc order, they will be last access desc order.
-    paths.push_back(AddTestEntry(
-        base::StringPrintf("id_%02d", i), base::StringPrintf("md5_%02d", i),
-        kNumOfTestFiles - i /* last accessed */, src_file));
-  }
-
-  // Confirm cache files of kNumOfTestFiles actually exist.
-  for (const auto& path : paths) {
-    ASSERT_TRUE(base::PathExists(path)) << path.value();
-  }
-
-  // Try to free kMaxNumOfEvictedCacheFiles * 3 / 2.
-  fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
-  fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes);
-  fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes);
-  fake_free_disk_space_getter_->PushFakeValue(
-      kMinFreeSpaceInBytes +
-      (kMaxNumOfEvictedCacheFiles * kTemporaryFileSizeInBytes));
-  const int64_t kNeededBytes =
-      (kMaxNumOfEvictedCacheFiles * 3 / 2) * kTemporaryFileSizeInBytes;
-  EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
-
-  for (uint32_t i = 0; i < kNumOfTestFiles; ++i) {
-    // Assert that only first kMaxNumOfEvictedCacheFiles exist.
-    ASSERT_EQ(i < kMaxNumOfEvictedCacheFiles, base::PathExists(paths[i]));
-  }
-}
-
-TEST_F(FileCacheTest, GetFile) {
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string src_contents = "test";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        src_contents));
-  std::string id("id1");
-  std::string md5(base::MD5String(src_contents));
-
-  const base::FilePath cache_file_directory =
-      temp_dir_.GetPath().Append(kCacheFileDirectory);
-
-  // Try to get an existing file from cache.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
-                                         FileCache::FILE_OPERATION_COPY));
-  base::FilePath cache_file_path;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
-  EXPECT_EQ(
-      cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
-      cache_file_path.value());
-
-  std::string contents;
-  EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
-  EXPECT_EQ(src_contents, contents);
-
-  // Get file from cache with different id.
-  id = "id2";
-  entry.Clear();
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
-
-  // Pin a non-existent file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
-
-  // Get the non-existent pinned file from cache.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
-
-  // Get a previously pinned and stored file from cache.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
-                                         FileCache::FILE_OPERATION_COPY));
-
-  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
-  EXPECT_EQ(
-      cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
-      cache_file_path.value());
-
-  contents.clear();
-  EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
-  EXPECT_EQ(src_contents, contents);
-}
-
-TEST_F(FileCacheTest, Store) {
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string src_contents = "test";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        src_contents));
-  std::string id("id");
-  std::string md5(base::MD5String(src_contents));
-
-  // Store a file.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-      id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5());
-
-  base::FilePath cache_file_path;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
-  EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path));
-
-  base::FilePath dest_file_path = GetCacheFilePath(id);
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path));
-
-  // Store a non-existent file.
-  EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store(
-      id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"),
-      FileCache::FILE_OPERATION_COPY));
-
-  // Passing empty MD5 marks the entry as dirty.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-      id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-  EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
-  EXPECT_FALSE(IsMarkedAsRemovable(dest_file_path));
-
-  // No free space available.
-  fake_free_disk_space_getter_->set_default_value(0);
-
-  EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store(
-      id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
-}
-
-TEST_F(FileCacheTest, PinAndUnpin) {
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string src_contents = "test";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        src_contents));
-  std::string id("id_present");
-  std::string md5(base::MD5String(src_contents));
-
-  // Store a file.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-      id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
-
-  const base::FilePath dest_file_path = GetCacheFilePath(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path));
-
-  // Pin the existing file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
-  EXPECT_FALSE(IsMarkedAsRemovable(dest_file_path));
-
-  // Unpin the file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path));
-
-  // Pin a non-present file.
-  std::string id_non_present = "id_non_present";
-  entry.Clear();
-  entry.set_local_id(id_non_present);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
-
-  // Unpin the previously pinned non-existent file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry));
-  EXPECT_FALSE(entry.file_specific_info().has_cache_state());
-
-  // Unpin a file that doesn't exist in cache and is not pinned.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent"));
-}
-
-TEST_F(FileCacheTest, MountUnmount) {
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string src_contents = "test";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        src_contents));
-  std::string id("id_present");
-  std::string md5(base::MD5String(src_contents));
-
-  // Store a file.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-      id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
-
-  // Mark the file mounted.
-  base::FilePath cache_file_path;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path));
-
-  EXPECT_TRUE(cache_->IsMarkedAsMounted(id));
-
-  // Try to remove it.
-  EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id));
-
-  // Clear mounted state of the file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path));
-
-  EXPECT_FALSE(cache_->IsMarkedAsMounted(id));
-
-  // Try to remove again.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
-}
-
-TEST_F(FileCacheTest, OpenForWrite) {
-  // Prepare a file.
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-
-  const std::string id = "id";
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
-                                         FileCache::FILE_OPERATION_COPY));
-  EXPECT_EQ(0, entry.file_info().last_modified());
-  EXPECT_EQ(0, entry.last_modified_by_me());
-
-  // Entry is not dirty nor opened.
-  EXPECT_FALSE(cache_->IsOpenedForWrite(id));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
-
-  const base::FilePath dest_file = GetCacheFilePath(id);
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file));
-
-  // Open (1).
-  std::unique_ptr<base::ScopedClosureRunner> file_closer1;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1));
-  EXPECT_TRUE(cache_->IsOpenedForWrite(id));
-
-  // Entry is dirty.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
-  EXPECT_FALSE(IsMarkedAsRemovable((dest_file)));
-
-  // Open (2).
-  std::unique_ptr<base::ScopedClosureRunner> file_closer2;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2));
-  EXPECT_TRUE(cache_->IsOpenedForWrite(id));
-
-  // Close (1).
-  file_closer1.reset();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(cache_->IsOpenedForWrite(id));
-
-  // last_modified and last_modified_by_me are updated.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_NE(0, entry.file_info().last_modified());
-  EXPECT_NE(0, entry.last_modified_by_me());
-  EXPECT_EQ(entry.file_info().last_modified(), entry.last_modified_by_me());
-
-  // Close (2).
-  file_closer2.reset();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(cache_->IsOpenedForWrite(id));
-
-  // Try to open non-existent file.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
-            cache_->OpenForWrite("nonexistent_id", &file_closer1));
-}
-
-TEST_F(FileCacheTest, UpdateMd5) {
-  // Store test data.
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string contents_before = "before";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        contents_before));
-  std::string id("id1");
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before),
-                                         src_file_path,
-                                         FileCache::FILE_OPERATION_COPY));
-
-  // Modify the cache file.
-  std::unique_ptr<base::ScopedClosureRunner> file_closer;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
-  base::FilePath cache_file_path;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
-  const std::string contents_after = "after";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(cache_file_path,
-                                                        contents_after));
-
-  // Cannot update MD5 of an opend file.
-  EXPECT_EQ(FILE_ERROR_IN_USE, cache_->UpdateMd5(id));
-
-  // Close file.
-  file_closer.reset();
-  base::RunLoop().RunUntilIdle();
-
-  // MD5 was cleared by OpenForWrite().
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
-
-  // Update MD5.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_EQ(base::MD5String(contents_after),
-            entry.file_specific_info().cache_state().md5());
-}
-
-TEST_F(FileCacheTest, ClearDirty) {
-  // Prepare a file.
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-
-  const std::string id = "id";
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
-                                         FileCache::FILE_OPERATION_COPY));
-
-  const base::FilePath dest_file = GetCacheFilePath(id);
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file));
-
-  // Open the file.
-  std::unique_ptr<base::ScopedClosureRunner> file_closer;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
-
-  // Entry is dirty.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
-  EXPECT_FALSE(IsMarkedAsRemovable(dest_file));
-
-  // Cannot clear the dirty bit of an opened entry.
-  EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id));
-  EXPECT_FALSE(IsMarkedAsRemovable(dest_file));
-
-  // Close the file and clear the dirty bit.
-  file_closer.reset();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id));
-
-  // Entry is not dirty.
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
-  EXPECT_TRUE(IsMarkedAsRemovable(dest_file));
-}
-
-TEST_F(FileCacheTest, Remove) {
-  const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat");
-  const std::string src_contents = "test";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
-                                                        src_contents));
-  std::string id("id");
-  std::string md5(base::MD5String(src_contents));
-
-  // First store a file to cache.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-      id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
-
-  base::FilePath cache_file_path;
-  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
-
-  // Then try to remove existing file from cache.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
-  EXPECT_FALSE(base::PathExists(cache_file_path));
-}
-
-TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) {
-  const base::FilePath file_directory =
-      temp_dir_.GetPath().Append(kCacheFileDirectory);
-
-  // File with an old style "<prefix>:<ID>.<MD5>" name.
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
-      file_directory.AppendASCII("file:id_koo.md5"), "koo"));
-
-  // File with multiple extensions should be removed.
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
-      file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)"));
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
-      file_directory.AppendASCII("id_kyu.md5"), "kyu"));
-
-  // Rename and verify the result.
-  EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
-  std::string contents;
-  EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
-                                     &contents));
-  EXPECT_EQ("koo", contents);
-  contents.clear();
-  EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
-                                     &contents));
-  EXPECT_EQ("kyu", contents);
-
-  // Rename again.
-  EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
-
-  // Files with new style names are not affected.
-  contents.clear();
-  EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
-                                     &contents));
-  EXPECT_EQ("koo", contents);
-  contents.clear();
-  EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
-                                     &contents));
-  EXPECT_EQ("kyu", contents);
-}
-
-TEST_F(FileCacheTest, FixMetadataAndFileAttributes) {
-  // Create test files and metadata.
-  base::FilePath temp_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file));
-
-  // Entry A: pinned cache file.
-  const std::string id_a = "id_a";
-  ResourceEntry entry_a;
-  entry_a.set_local_id(id_a);
-  FileCacheEntry* file_cache_entry_a =
-      entry_a.mutable_file_specific_info()->mutable_cache_state();
-  file_cache_entry_a->set_is_present(true);
-  file_cache_entry_a->set_is_pinned(true);
-  file_cache_entry_a->set_is_dirty(false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a));
-  const base::FilePath file_path_a = GetCacheFilePath(id_a);
-  ASSERT_TRUE(base::CopyFile(temp_file, file_path_a));
-
-  // Entry B: dirty cache file.
-  const std::string id_b = "id_b";
-  ResourceEntry entry_b;
-  entry_b.set_local_id(id_b);
-  FileCacheEntry* file_cache_entry_b =
-      entry_b.mutable_file_specific_info()->mutable_cache_state();
-  file_cache_entry_b->set_is_present(true);
-  file_cache_entry_b->set_is_pinned(false);
-  file_cache_entry_b->set_is_dirty(true);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_b));
-  const base::FilePath file_path_b = GetCacheFilePath(id_b);
-  ASSERT_TRUE(base::CopyFile(temp_file, file_path_b));
-
-  // Entry C: not pinned nor dirty cache file.
-  const std::string id_c = "id_c";
-  ResourceEntry entry_c;
-  entry_c.set_local_id(id_c);
-  FileCacheEntry* file_cache_entry_c =
-      entry_c.mutable_file_specific_info()->mutable_cache_state();
-  file_cache_entry_c->set_is_present(true);
-  file_cache_entry_c->set_is_pinned(false);
-  file_cache_entry_c->set_is_dirty(false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c));
-  const base::FilePath file_path_c = GetCacheFilePath(id_c);
-  ASSERT_TRUE(base::CopyFile(temp_file, file_path_c));
-
-  // Entry D: pinned cache file somehow having removable flag.
-  const std::string id_d = "id_d";
-  ResourceEntry entry_d;
-  entry_d.set_local_id(id_d);
-  FileCacheEntry* file_cache_entry_d =
-      entry_d.mutable_file_specific_info()->mutable_cache_state();
-  file_cache_entry_d->set_is_present(true);
-  file_cache_entry_d->set_is_pinned(true);
-  file_cache_entry_d->set_is_dirty(false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d));
-  const base::FilePath file_path_d = GetCacheFilePath(id_d);
-  ASSERT_TRUE(base::CopyFile(temp_file, file_path_d));
-
-  // Set removable flag.
-  FileAttributes flags = GetFileAttributes(file_path_d);
-  ASSERT_GE(flags, 0);
-  flags |= FS_NODUMP_FL;
-  base::File file_d(file_path_d, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  ASSERT_EQ(ioctl(file_d.GetPlatformFile(), FS_IOC_SETFLAGS, &flags), 0);
-
-  // Entry E: there is no file; removed by cryptohome.
-  const std::string id_e = "id_e";
-  ResourceEntry entry_e;
-  entry_e.set_local_id(id_e);
-  FileCacheEntry* file_cache_entry_e =
-      entry_e.mutable_file_specific_info()->mutable_cache_state();
-  file_cache_entry_e->set_is_present(true);
-  file_cache_entry_e->set_is_pinned(false);
-  file_cache_entry_e->set_is_dirty(false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e));
-  const base::FilePath file_path_e = GetCacheFilePath(id_e);
-
-  // Entry F: there is a file, but metadata says not.
-  const std::string id_f = "id_f";
-  ResourceEntry entry_f;
-  entry_f.set_local_id(id_f);
-  entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present(
-      false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f));
-  const base::FilePath file_path_f = GetCacheFilePath(id_f);
-  ASSERT_TRUE(base::CopyFile(temp_file, file_path_f));
-
-  // Entry G: no file nor metadata.
-  const std::string id_g = "id_g";
-  ResourceEntry entry_g;
-  entry_g.set_local_id(id_g);
-  entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present(
-      false);
-  ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f));
-
-  // Initialize fixes inconsistency between metadata and cache file attributes
-  // as well as adding specific file attributes to the cache directory.
-  ASSERT_TRUE(cache_->Initialize());
-
-  // Check result.
-  EXPECT_FALSE(IsMarkedAsRemovable(file_path_a));
-  EXPECT_FALSE(IsMarkedAsRemovable(file_path_b));
-  EXPECT_TRUE(IsMarkedAsRemovable(file_path_c));
-  EXPECT_FALSE(IsMarkedAsRemovable(file_path_d));
-  EXPECT_FALSE(base::PathExists(file_path_f));
-
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_e, &entry_e));
-  EXPECT_FALSE(entry_e.file_specific_info().cache_state().is_present());
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_f, &entry_f));
-  EXPECT_FALSE(entry_f.file_specific_info().cache_state().is_present());
-
-  // Check the cache dir has appropriate attributes.
-  EXPECT_TRUE(HasRemovableFlag(cache_files_dir_));
-  EXPECT_GE(getxattr(cache_files_dir_.value().c_str(),
-      FileCache::kGCacheFilesAttribute, nullptr, 0), 0);
-}
-
-TEST_F(FileCacheTest, ClearAll) {
-  const std::string id("1a2b");
-  const std::string md5("abcdef0123456789");
-
-  // Store an existing file.
-  ResourceEntry entry;
-  entry.set_local_id(id);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
-  base::FilePath src_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file));
-  ASSERT_EQ(FILE_ERROR_OK,
-            cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
-
-  // Clear cache.
-  EXPECT_TRUE(cache_->ClearAll());
-
-  // Verify that the cache is removed.
-  EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_));
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/file_system_interface.cc b/components/drive/chromeos/file_system_interface.cc
deleted file mode 100644
index 242538a..0000000
--- a/components/drive/chromeos/file_system_interface.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/file_system_interface.h"
-
-namespace drive {
-
-MetadataSearchResult::MetadataSearchResult(
-    const base::FilePath& path,
-    bool is_directory,
-    const std::string& highlighted_base_name,
-    const std::string& md5)
-    : path(path),
-      is_directory(is_directory),
-      highlighted_base_name(highlighted_base_name),
-      md5(md5) {
-}
-
-MetadataSearchResult::MetadataSearchResult(const MetadataSearchResult& other) =
-    default;
-
-}  // namespace drive
diff --git a/components/drive/chromeos/file_system_interface.h b/components/drive/chromeos/file_system_interface.h
deleted file mode 100644
index 30976c6..0000000
--- a/components/drive/chromeos/file_system_interface.h
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_
-#define COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_metadata.h"
-#include "google_apis/drive/base_requests.h"
-#include "google_apis/drive/drive_api_requests.h"
-
-namespace drive {
-
-class FileSystemObserver;
-
-// Information about search result returned by Search Async callback.
-// This is data needed to create a file system entry that will be used by file
-// browser.
-struct SearchResultInfo {
-  SearchResultInfo(const base::FilePath& path, bool is_directory)
-      : path(path), is_directory(is_directory) {}
-
-  base::FilePath path;
-  bool is_directory;
-};
-
-// File path and its MD5 hash obtained from drive API.
-struct HashAndFilePath {
-  std::string hash;
-  base::FilePath path;
-};
-
-// Specifies the order in which SearchMetadata() results are sorted.
-enum class MetadataSearchOrder {
-  // Most recently accessed file comes first.
-  LAST_ACCESSED = 0,
-
-  // Most recently modified file comes first.
-  LAST_MODIFIED = 1,
-};
-
-// Struct to represent a search result for SearchMetadata().
-struct MetadataSearchResult {
-  MetadataSearchResult(const base::FilePath& path,
-                       bool is_directory,
-                       const std::string& highlighted_base_name,
-                       const std::string& md5);
-  MetadataSearchResult(const MetadataSearchResult& other);
-
-  // The two members are used to create FileEntry object.
-  base::FilePath path;
-  bool is_directory;
-
-  // The base name to be displayed in the UI. The parts matched the search
-  // query are highlighted with <b> tag. Meta characters are escaped like &lt;
-  //
-  // Why HTML? we could instead provide matched ranges using pairs of
-  // integers, but this is fragile as we'll eventually converting strings
-  // from UTF-8 (StringValue in base/values.h uses std::string) to UTF-16
-  // when sending strings from C++ to JavaScript.
-  //
-  // Why <b> instead of <strong>? Because <b> is shorter.
-  std::string highlighted_base_name;
-
-  // MD5 hash of the file.
-  std::string md5;
-};
-
-typedef std::vector<MetadataSearchResult> MetadataSearchResultVector;
-
-// Used to get a resource entry from the file system.
-// If |error| is not FILE_ERROR_OK, |entry_info| is set to NULL.
-typedef base::OnceCallback<void(FileError error,
-                                std::unique_ptr<ResourceEntry> entry)>
-    GetResourceEntryCallback;
-
-// Used to get files from the file system.
-typedef base::OnceCallback<void(FileError error,
-                                const base::FilePath& file_path,
-                                std::unique_ptr<ResourceEntry> entry)>
-    GetFileCallback;
-
-// Used to get file content from the file system.
-// If the file content is available in local cache, |local_file| is filled with
-// the path to the cache file. If the file content starts to be downloaded from
-// the server, |local_file| is empty.
-typedef base::OnceCallback<void(FileError error,
-                                const base::FilePath& local_file,
-                                std::unique_ptr<ResourceEntry> entry)>
-    GetFileContentInitializedCallback;
-
-// Used to get list of entries under a directory.
-typedef base::OnceCallback<void(std::unique_ptr<ResourceEntryVector> entries)>
-    ReadDirectoryEntriesCallback;
-
-// Used to get drive content search results.
-// If |error| is not FILE_ERROR_OK, |result_paths| is empty.
-typedef base::OnceCallback<void(
-    FileError error,
-    const GURL& next_link,
-    std::unique_ptr<std::vector<SearchResultInfo>> result_paths)>
-    SearchCallback;
-
-// Callback for SearchMetadata(). On success, |error| is FILE_ERROR_OK, and
-// |result| contains the search result.
-typedef base::OnceCallback<
-    void(FileError error, std::unique_ptr<MetadataSearchResultVector> result)>
-    SearchMetadataCallback;
-
-// Callback for SearchByHashesCallback. On success, vector contains hash and
-// corresponding files. The vector can include multiple entries for one hash.
-typedef base::OnceCallback<void(FileError, const std::vector<HashAndFilePath>&)>
-    SearchByHashesCallback;
-
-// Used to open files from the file system. |file_path| is the path on the local
-// file system for the opened file.
-// If |close_callback| is not null, it must be called when the
-// modification to the cache is done. Otherwise, Drive file system does not
-// pick up the file for uploading.
-// |close_callback| must not be called more than once.
-typedef base::OnceCallback<void(FileError error,
-                                const base::FilePath& file_path,
-                                const base::RepeatingClosure& close_callback)>
-    OpenFileCallback;
-
-// Used to get available space for the account from Drive.
-typedef base::OnceCallback<
-    void(FileError error, int64_t bytes_total, int64_t bytes_used)>
-    GetAvailableSpaceCallback;
-
-// Used to get filesystem metadata.
-typedef base::OnceCallback<void(
-    const FileSystemMetadata&,
-    const std::map<std::string, FileSystemMetadata>&)>
-    GetFilesystemMetadataCallback;
-
-// Used to mark cached files mounted.
-typedef base::OnceCallback<void(FileError error,
-                                const base::FilePath& file_path)>
-    MarkMountedCallback;
-
-// Used to check if a cached file is mounted.
-typedef base::OnceCallback<void(FileError error, bool is_mounted)>
-    IsMountedCallback;
-
-// Used to get file path.
-typedef base::Callback<void(FileError error, const base::FilePath& file_path)>
-    GetFilePathCallback;
-
-// Used to free space.
-typedef base::Callback<void(bool)> FreeDiskSpaceCallback;
-
-// Used for returning result of calculated cache size.
-typedef base::Callback<void(int64_t)> CacheSizeCallback;
-
-// The mode of opening a file.
-enum OpenMode {
-  // Open the file if exists. If not, failed.
-  OPEN_FILE,
-
-  // Create a new file if not exists, and then open it. If exists, failed.
-  CREATE_FILE,
-
-  // Open the file if exists. If not, create a new file and then open it.
-  OPEN_OR_CREATE_FILE,
-};
-
-// Option enum to control eligible entries for SearchMetadata().
-// SEARCH_METADATA_ALL is the default to investigate all the entries.
-// SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS excludes the hosted documents.
-// SEARCH_METADATA_EXCLUDE_DIRECTORIES excludes the directories from the result.
-// SEARCH_METADATA_SHARED_WITH_ME targets only "shared-with-me" entries.
-// SEARCH_METADATA_OFFLINE targets only "offline" entries. This option can not
-// be used with other options.
-enum SearchMetadataOptions {
-  SEARCH_METADATA_ALL = 0,
-  SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS = 1,
-  SEARCH_METADATA_EXCLUDE_DIRECTORIES = 1 << 1,
-  SEARCH_METADATA_SHARED_WITH_ME = 1 << 2,
-  SEARCH_METADATA_OFFLINE = 1 << 3,
-};
-
-// Drive file system abstraction layer.
-// The interface is defined to make FileSystem mockable.
-class FileSystemInterface {
- public:
-  virtual ~FileSystemInterface() = default;
-
-  // Adds and removes the observer.
-  virtual void AddObserver(FileSystemObserver* observer) = 0;
-  virtual void RemoveObserver(FileSystemObserver* observer) = 0;
-
-  // Checks for updates on the server, in response to a timer expiring - most
-  // likely when we are not connected to push notifications.
-  virtual void CheckForUpdates() = 0;
-
-  // Check for updates on the server, for the given ids. The ids are either
-  // team drive ids, or an empty string for the users default corpus.
-  virtual void CheckForUpdates(const std::set<std::string>& ids) = 0;
-
-  // Initiates transfer of |local_src_file_path| to |remote_dest_file_path|.
-  // |local_src_file_path| must be a file from the local file system.
-  // |remote_dest_file_path| is the virtual destination path within Drive file
-  // system.
-  //
-  // |callback| must not be null.
-  virtual void TransferFileFromLocalToRemote(
-      const base::FilePath& local_src_file_path,
-      const base::FilePath& remote_dest_file_path,
-      const FileOperationCallback& callback) = 0;
-
-  // Retrieves a file at the virtual path |file_path| on the Drive file system
-  // onto the cache, and mark it dirty. The local path to the cache file is
-  // returned to |callback|. After opening the file, both read and write
-  // on the file can be done with normal local file operations.
-  // If |mime_type| is set and the file is newly created, the mime type is
-  // set to the specified value. If |mime_type| is empty, it is guessed from
-  // |file_path|.
-  //
-  // |callback| must not be null.
-  virtual void OpenFile(const base::FilePath& file_path,
-                        OpenMode open_mode,
-                        const std::string& mime_type,
-                        OpenFileCallback callback) = 0;
-
-  // Copies |src_file_path| to |dest_file_path| on the file system.
-  // |src_file_path| can be a hosted document (see limitations below).
-  // |dest_file_path| is expected to be of the same type of |src_file_path|
-  // (i.e. if |src_file_path| is a file, |dest_file_path| will be created as
-  // a file).
-  // If |preserve_last_modified| is set to true, the last modified time will be
-  // preserved. This feature is only supported on Drive API v2 protocol because
-  // GData WAPI doesn't support updating modification time.
-  //
-  // This method also has the following assumptions/limitations that may be
-  // relaxed or addressed later:
-  // - |src_file_path| cannot be a regular file (i.e. non-hosted document)
-  //   or a directory.
-  // - |dest_file_path| must not exist.
-  // - The parent of |dest_file_path| must already exist.
-  //
-  // The file entries represented by |src_file_path| and the parent directory
-  // of |dest_file_path| need to be present in the in-memory representation
-  // of the file system.
-  //
-  // |callback| must not be null.
-  virtual void Copy(const base::FilePath& src_file_path,
-                    const base::FilePath& dest_file_path,
-                    bool preserve_last_modified,
-                    const FileOperationCallback& callback) = 0;
-
-  // Moves |src_file_path| to |dest_file_path| on the file system.
-  // |src_file_path| can be a file (regular or hosted document) or a directory.
-  // |dest_file_path| is expected to be of the same type of |src_file_path|
-  // (i.e. if |src_file_path| is a file, |dest_file_path| will be created as
-  // a file).
-  //
-  // This method also has the following assumptions/limitations that may be
-  // relaxed or addressed later:
-  // - |dest_file_path| must not exist.
-  // - The parent of |dest_file_path| must already exist.
-  //
-  // The file entries represented by |src_file_path| and the parent directory
-  // of |dest_file_path| need to be present in the in-memory representation
-  // of the file system.
-  //
-  // |callback| must not be null.
-  virtual void Move(const base::FilePath& src_file_path,
-                    const base::FilePath& dest_file_path,
-                    const FileOperationCallback& callback) = 0;
-
-  // Removes |file_path| from the file system.  If |is_recursive| is set and
-  // |file_path| represents a directory, we will also delete all of its
-  // contained children elements. The file entry represented by |file_path|
-  // needs to be present in in-memory representation of the file system that
-  // in order to be removed.
-  //
-  // |callback| must not be null.
-  virtual void Remove(const base::FilePath& file_path,
-                      bool is_recursive,
-                      const FileOperationCallback& callback) = 0;
-
-  // Creates new directory under |directory_path|. If |is_exclusive| is true,
-  // an error is raised in case a directory is already present at the
-  // |directory_path|. If |is_recursive| is true, the call creates parent
-  // directories as needed just like mkdir -p does.
-  //
-  // |callback| must not be null.
-  virtual void CreateDirectory(const base::FilePath& directory_path,
-                               bool is_exclusive,
-                               bool is_recursive,
-                               const FileOperationCallback& callback) = 0;
-
-  // Creates a file at |file_path|. If the flag |is_exclusive| is true, an
-  // error is raised when a file already exists at the path. It is
-  // an error if a directory or a hosted document is already present at the
-  // path, or the parent directory of the path is not present yet.
-  // If |mime_type| is set and the file is newly created, the mime type is
-  // set to the specified value. If |mime_type| is empty, it is guessed from
-  // |file_path|.
-  //
-  // |callback| must not be null.
-  virtual void CreateFile(const base::FilePath& file_path,
-                          bool is_exclusive,
-                          const std::string& mime_type,
-                          const FileOperationCallback& callback) = 0;
-
-  // Touches the file at |file_path| by updating the timestamp to
-  // |last_access_time| and |last_modified_time|.
-  // Upon completion, invokes |callback|.
-  // Note that, differently from unix touch command, this doesn't create a file
-  // if the target file doesn't exist.
-  //
-  // |last_access_time|, |last_modified_time| and |callback| must not be null.
-  virtual void TouchFile(const base::FilePath& file_path,
-                         const base::Time& last_access_time,
-                         const base::Time& last_modified_time,
-                         const FileOperationCallback& callback) = 0;
-
-  // Truncates the file content at |file_path| to the |length|.
-  //
-  // |callback| must not be null.
-  virtual void TruncateFile(const base::FilePath& file_path,
-                            int64_t length,
-                            const FileOperationCallback& callback) = 0;
-
-  // Pins a file at |file_path|.
-  //
-  // |callback| must not be null.
-  virtual void Pin(const base::FilePath& file_path,
-                   const FileOperationCallback& callback) = 0;
-
-  // Unpins a file at |file_path|.
-  //
-  // |callback| must not be null.
-  virtual void Unpin(const base::FilePath& file_path,
-                     const FileOperationCallback& callback) = 0;
-
-  // Makes sure that |file_path| in the file system is available in the local
-  // cache. If the file is not cached, the file will be downloaded. The entry
-  // needs to be present in the file system.
-  //
-  // Returns the cache path and entry info to |callback|. It must not be null.
-  virtual void GetFile(const base::FilePath& file_path,
-                       GetFileCallback callback) = 0;
-
-  // Makes sure that |file_path| in the file system is available in the local
-  // cache, and mark it as dirty. The next modification to the cache file is
-  // watched and is automatically uploaded to the server. If the entry is not
-  // present in the file system, it is created.
-  //
-  // Returns the cache path and entry info to |callback|. It must not be null.
-  virtual void GetFileForSaving(const base::FilePath& file_path,
-                                GetFileCallback callback) = 0;
-
-  // Gets a file by the given |file_path| and returns a closure to cancel the
-  // task.
-  // Calls |initialized_callback| when either:
-  //   1) The cached file (or JSON file for hosted file) is found, or
-  //   2) Starting to download the file from drive server.
-  // In case of 2), the given FilePath is empty, and |get_content_callback| is
-  // called repeatedly with downloaded content following the
-  // |initialized_callback| invocation.
-  // |completion_callback| is invoked if an error is found, or the operation
-  // is successfully done.
-  // |initialized_callback|, |get_content_callback| and |completion_callback|
-  // must not be null.
-  virtual base::Closure GetFileContent(
-      const base::FilePath& file_path,
-      GetFileContentInitializedCallback initialized_callback,
-      const google_apis::GetContentCallback& get_content_callback,
-      const FileOperationCallback& completion_callback) = 0;
-
-  // Finds an entry (a file or a directory) by |file_path|. This call will also
-  // retrieve and refresh file system content from server and disk cache.
-  //
-  // |callback| must not be null.
-  virtual void GetResourceEntry(const base::FilePath& file_path,
-                                GetResourceEntryCallback callback) = 0;
-
-  // Finds and reads a directory by |file_path|. This call will also retrieve
-  // and refresh file system content from server and disk cache.
-  // |entries_callback| can be a null callback when not interested in entries.
-  //
-  // |completion_callback| must not be null.
-  virtual void ReadDirectory(
-      const base::FilePath& file_path,
-      ReadDirectoryEntriesCallback entries_callback,
-      const FileOperationCallback& completion_callback) = 0;
-
-  // Does server side content search for |search_query|.
-  // If |next_link| is set, this is the search result url that will be
-  // fetched. Search results will be returned as a list of results'
-  // |SearchResultInfo| structs, which contains file's path and is_directory
-  // flag.
-  //
-  // |callback| must not be null.
-  virtual void Search(const std::string& search_query,
-                      const GURL& next_link,
-                      SearchCallback callback) = 0;
-
-  // Searches the local resource metadata, and returns the entries
-  // |at_most_num_matches| that contain |query| in their base names. Search is
-  // done in a case-insensitive fashion. The eligible entries are selected based
-  // on the given |options|, which is a bit-wise OR of SearchMetadataOptions.
-  // SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS will be automatically added based
-  // on the preference. |callback| must not be null. Must be called on UI
-  // thread. Empty |query| matches any base name. i.e. returns everything.
-  virtual void SearchMetadata(const std::string& query,
-                              int options,
-                              int at_most_num_matches,
-                              MetadataSearchOrder order,
-                              SearchMetadataCallback callback) = 0;
-
-  // Searches the local resource metadata, and returns the entries that have the
-  // given |hashes|. The list of resource entries are passed to |callback|. The
-  // item of the list can be null if the corresponding file is not found.
-  // |callback| must not be null.
-  virtual void SearchByHashes(const std::set<std::string>& hashes,
-                              SearchByHashesCallback callback) = 0;
-
-  // Fetches the user's Account Metadata to find out current quota information
-  // and returns it to the callback.
-  virtual void GetAvailableSpace(GetAvailableSpaceCallback callback) = 0;
-
-  // Returns miscellaneous metadata of the file system like the largest
-  // timestamp. Used in chrome:drive-internals. |callback| must not be null.
-  virtual void GetMetadata(GetFilesystemMetadataCallback callback) = 0;
-
-  // Marks the cached file as mounted, and runs |callback| upon completion.
-  // If succeeded, the cached file path will be passed to the |callback|.
-  // |callback| must not be null.
-  virtual void MarkCacheFileAsMounted(const base::FilePath& drive_file_path,
-                                      MarkMountedCallback callback) = 0;
-
-  // Checks if the cached file is marked as mounted, and passes the result to
-  // |callback| upon completion. If the file was not found in the cache, the
-  // result is false. |callback| must not be null.
-  virtual void IsCacheFileMarkedAsMounted(const base::FilePath& drive_file_path,
-                                          IsMountedCallback callback) = 0;
-
-  // Marks the cached file as unmounted, and runs |callback| upon completion.
-  // Note that this method expects that the |cached_file_path| is the path
-  // returned by MarkCacheFileAsMounted().
-  // |callback| must not be null.
-  virtual void MarkCacheFileAsUnmounted(
-      const base::FilePath& cache_file_path,
-      const FileOperationCallback& callback) = 0;
-
-  // Adds permission as |role| to |email| for the entry at |drive_file_path|.
-  // |callback| must not be null.
-  virtual void AddPermission(const base::FilePath& drive_file_path,
-                             const std::string& email,
-                             google_apis::drive::PermissionRole role,
-                             const FileOperationCallback& callback) = 0;
-
-  // Sets the |key| property on the file or directory at |drive_file_path| with
-  // the specified |visibility|. If already exists, then it will be overwritten.
-  virtual void SetProperty(const base::FilePath& drive_file_path,
-                           google_apis::drive::Property::Visibility visibility,
-                           const std::string& key,
-                           const std::string& value,
-                           const FileOperationCallback& callback) = 0;
-
-  // Resets local data.
-  virtual void Reset(const FileOperationCallback& callback) = 0;
-
-  // Finds a path of an entry (a file or a directory) by |resource_id|.
-  virtual void GetPathFromResourceId(const std::string& resource_id,
-                                     const GetFilePathCallback& callback) = 0;
-
-  // Free drive caches if needed to secure given available spaces. |callback|
-  // takes whether given bytes are available or not.
-  virtual void FreeDiskSpaceIfNeededFor(
-      int64_t num_bytes,
-      const FreeDiskSpaceCallback& callback) = 0;
-
-  // Calculates total cache size.
-  // |callback| must not be null.
-  virtual void CalculateCacheSize(const CacheSizeCallback& callback) = 0;
-
-  // Calculates evictable cache size.
-  // |callback| must not be null.
-  virtual void CalculateEvictableCacheSize(
-      const CacheSizeCallback& callback) = 0;
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_
diff --git a/components/drive/chromeos/file_system_observer.h b/components/drive/chromeos/file_system_observer.h
deleted file mode 100644
index 90a5bfe..0000000
--- a/components/drive/chromeos/file_system_observer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_
-#define COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_
-
-#include <set>
-#include <string>
-
-#include "components/drive/chromeos/file_system/operation_delegate.h"
-#include "components/drive/file_errors.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace drive {
-
-class FileChange;
-
-// Interface for classes that need to observe events from classes implementing
-// FileSystemInterface.
-// All events are notified on UI thread.
-class FileSystemObserver {
- public:
-  // Triggered when a content of a directory has been changed.
-  // |directory_path| is a virtual directory path (/drive/...) representing
-  // changed directory.
-  virtual void OnDirectoryChanged(const base::FilePath& directory_path) {}
-  virtual void OnFileChanged(const FileChange& file_change) {}
-
-  // Triggered when a specific drive error occurred.
-  // |type| is a type of the error. |file_name| is a virtual path of the entry.
-  virtual void OnDriveSyncError(file_system::DriveSyncErrorType type,
-                                const base::FilePath& file_path) {}
-
-  // Triggered when the list of team drives that the user has access to
-  // changes. On first load all team drives will be passed via
-  // |added_team_drive_ids|, subsequent calls will just be the delta additions
-  // and removals.
-  virtual void OnTeamDrivesUpdated(
-      const std::set<std::string>& added_team_drive_ids,
-      const std::set<std::string>& removed_team_drive_ids) {}
-
- protected:
-  virtual ~FileSystemObserver() = default;
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_
diff --git a/components/drive/chromeos/remove_stale_cache_files.cc b/components/drive/chromeos/remove_stale_cache_files.cc
deleted file mode 100644
index 082d7a2..0000000
--- a/components/drive/chromeos/remove_stale_cache_files.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/remove_stale_cache_files.h"
-
-#include "base/logging.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-
-namespace drive {
-namespace internal {
-
-void RemoveStaleCacheFiles(FileCache* cache,
-                           ResourceMetadata* resource_metadata) {
-  std::unique_ptr<ResourceMetadata::Iterator> it =
-      resource_metadata->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    const ResourceEntry& entry = it->GetValue();
-    const FileCacheEntry& cache_state =
-        entry.file_specific_info().cache_state();
-    // Stale = not dirty but the MD5 does not match.
-    if (!cache_state.is_dirty() &&
-        cache_state.md5() != entry.file_specific_info().md5()) {
-      FileError error = cache->Remove(it->GetID());
-      LOG_IF(WARNING, error != FILE_ERROR_OK)
-          << "Failed to remove a stale cache file. resource_id: "
-          << it->GetID();
-    }
-  }
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/remove_stale_cache_files.h b/components/drive/chromeos/remove_stale_cache_files.h
deleted file mode 100644
index c7cf9bb..0000000
--- a/components/drive/chromeos/remove_stale_cache_files.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_
-#define COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_
-
-namespace drive{
-namespace internal {
-
-class FileCache;
-class ResourceMetadata;
-
-// Removes files from |cache| which are not dirty but the MD5 is obsolete.
-// Must be run on the same task runner as |cache| and |resource_metadata| use.
-void RemoveStaleCacheFiles(FileCache* cache,
-                           ResourceMetadata* resource_metadata);
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_
diff --git a/components/drive/chromeos/resource_metadata.cc b/components/drive/chromeos/resource_metadata.cc
deleted file mode 100644
index 1bea02a..0000000
--- a/components/drive/chromeos/resource_metadata.cc
+++ /dev/null
@@ -1,645 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/resource_metadata.h"
-
-#include <limits.h>
-#include <stddef.h>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/guid.h"
-#include "base/location.h"
-#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/system/sys_info.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-#include "components/drive/resource_metadata_storage.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-// Returns true if enough disk space is available for DB operation.
-// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface.
-bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) {
-  const int64_t kRequiredDiskSpaceInMB =
-      128;  // 128 MB seems to be large enough.
-  return base::SysInfo::AmountOfFreeDiskSpace(path) >=
-      kRequiredDiskSpaceInMB * (1 << 20);
-}
-
-// Returns a file name with a uniquifier appended. (e.g. "File (1).txt")
-std::string GetUniquifiedName(const std::string& name, int uniquifier) {
-  base::FilePath name_path = base::FilePath::FromUTF8Unsafe(name);
-  name_path = name_path.InsertBeforeExtensionASCII(
-      base::StringPrintf(" (%d)", uniquifier));
-  return name_path.AsUTF8Unsafe();
-}
-
-// Returns true when there is no entry with the specified name under the parent
-// other than the specified entry.
-FileError EntryCanUseName(ResourceMetadataStorage* storage,
-                          const std::string& parent_local_id,
-                          const std::string& local_id,
-                          const std::string& base_name,
-                          bool* result) {
-  std::string existing_entry_id;
-  FileError error = storage->GetChild(parent_local_id, base_name,
-                                      &existing_entry_id);
-  if (error == FILE_ERROR_OK)
-    *result = existing_entry_id == local_id;
-  else if (error == FILE_ERROR_NOT_FOUND)
-    *result = true;
-  else
-    return error;
-  return FILE_ERROR_OK;
-}
-
-// Returns true when the ID is used by an immutable entry.
-bool IsImmutableEntry(const std::string& id) {
-  return id == util::kDriveGrandRootLocalId ||
-      id == util::kDriveOtherDirLocalId ||
-      id == util::kDriveTrashDirLocalId;
-}
-
-}  // namespace
-
-ResourceMetadata::ResourceMetadata(
-    ResourceMetadataStorage* storage,
-    FileCache* cache,
-    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
-    : blocking_task_runner_(blocking_task_runner),
-      storage_(storage),
-      cache_(cache) {
-}
-
-FileError ResourceMetadata::Initialize() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  return SetUpDefaultEntries();
-}
-
-void ResourceMetadata::Destroy() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  blocking_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&ResourceMetadata::DestroyOnBlockingPool,
-                                base::Unretained(this)));
-}
-
-FileError ResourceMetadata::Reset() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  FileError error = storage_->SetLargestChangestamp(0);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  error = storage_->SetStartPageToken(std::string());
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  // Remove all root entries.
-  std::unique_ptr<Iterator> it = GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (it->GetValue().parent_local_id().empty()) {
-      error = RemoveEntryRecursively(it->GetID());
-      if (error != FILE_ERROR_OK)
-        return error;
-    }
-  }
-  if (it->HasError())
-    return FILE_ERROR_FAILED;
-
-  return SetUpDefaultEntries();
-}
-
-ResourceMetadata::~ResourceMetadata() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-}
-
-FileError ResourceMetadata::SetUpDefaultEntries() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  // Initialize "/drive".
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(util::kDriveGrandRootLocalId, &entry);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry root;
-    root.mutable_file_info()->set_is_directory(true);
-    root.set_local_id(util::kDriveGrandRootLocalId);
-    root.set_title(util::kDriveGrandRootDirName);
-    root.set_base_name(util::kDriveGrandRootDirName);
-    error = storage_->PutEntry(root);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error == FILE_ERROR_OK) {
-    if (!entry.resource_id().empty()) {
-      // Old implementations used kDriveGrandRootLocalId as a resource ID.
-      entry.clear_resource_id();
-      error = storage_->PutEntry(entry);
-      if (error != FILE_ERROR_OK)
-        return error;
-    }
-  } else {
-    return error;
-  }
-
-  // Initialize "/drive/other".
-  error = storage_->GetEntry(util::kDriveOtherDirLocalId, &entry);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry other_dir;
-    other_dir.mutable_file_info()->set_is_directory(true);
-    other_dir.set_local_id(util::kDriveOtherDirLocalId);
-    other_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
-    other_dir.set_title(util::kDriveOtherDirName);
-    error = PutEntryUnderDirectory(other_dir);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error == FILE_ERROR_OK) {
-    if (!entry.resource_id().empty()) {
-      // Old implementations used kDriveOtherDirLocalId as a resource ID.
-      entry.clear_resource_id();
-      error = storage_->PutEntry(entry);
-      if (error != FILE_ERROR_OK)
-        return error;
-    }
-  } else {
-    return error;
-  }
-
-  // Initialize "drive/trash".
-  error = storage_->GetEntry(util::kDriveTrashDirLocalId, &entry);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry trash_dir;
-    trash_dir.mutable_file_info()->set_is_directory(true);
-    trash_dir.set_local_id(util::kDriveTrashDirLocalId);
-    trash_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
-    trash_dir.set_title(util::kDriveTrashDirName);
-    error = PutEntryUnderDirectory(trash_dir);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error != FILE_ERROR_OK) {
-    return error;
-  }
-
-  // Initialize "drive/root".
-  std::string child_id;
-  error = storage_->GetChild(
-      util::kDriveGrandRootLocalId, util::kDriveMyDriveRootDirName, &child_id);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry mydrive;
-    mydrive.mutable_file_info()->set_is_directory(true);
-    mydrive.set_parent_local_id(util::kDriveGrandRootLocalId);
-    mydrive.set_title(util::kDriveMyDriveRootDirName);
-
-    std::string local_id;
-    error = AddEntry(mydrive, &local_id);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error != FILE_ERROR_OK) {
-    return error;
-  }
-
-  // Initialize "/drive/team_drives".
-  error = storage_->GetEntry(util::kDriveTeamDrivesDirLocalId, &entry);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry team_drives_dir;
-    team_drives_dir.mutable_file_info()->set_is_directory(true);
-    team_drives_dir.set_local_id(util::kDriveTeamDrivesDirLocalId);
-    team_drives_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
-    team_drives_dir.set_title(util::kDriveTeamDrivesDirName);
-    error = PutEntryUnderDirectory(team_drives_dir);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error != FILE_ERROR_OK) {
-    return error;
-  }
-
-  // Initialize "/drive/Computers".
-  error = storage_->GetEntry(util::kDriveComputersDirLocalId, &entry);
-  if (error == FILE_ERROR_NOT_FOUND) {
-    ResourceEntry computers_dir;
-    computers_dir.mutable_file_info()->set_is_directory(true);
-    computers_dir.set_local_id(util::kDriveComputersDirLocalId);
-    computers_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
-    computers_dir.set_title(util::kDriveComputersDirName);
-    error = PutEntryUnderDirectory(computers_dir);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (error != FILE_ERROR_OK) {
-    return error;
-  }
-
-  return FILE_ERROR_OK;
-}
-
-void ResourceMetadata::DestroyOnBlockingPool() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  delete this;
-}
-
-FileError ResourceMetadata::GetStartPageToken(std::string* out_value) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  return storage_->GetStartPageToken(out_value);
-}
-
-FileError ResourceMetadata::SetStartPageToken(const std::string& value) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  return storage_->SetStartPageToken(value);
-}
-
-FileError ResourceMetadata::AddEntry(const ResourceEntry& entry,
-                                     std::string* out_id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(entry.local_id().empty());
-
-  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  ResourceEntry parent;
-  FileError error = storage_->GetEntry(entry.parent_local_id(), &parent);
-  if (error != FILE_ERROR_OK)
-    return error;
-  if (!parent.file_info().is_directory())
-    return FILE_ERROR_NOT_A_DIRECTORY;
-
-  // Multiple entries with the same resource ID should not be present.
-  std::string local_id;
-  ResourceEntry existing_entry;
-  if (!entry.resource_id().empty()) {
-    error = storage_->GetIdByResourceId(entry.resource_id(), &local_id);
-    if (error == FILE_ERROR_OK)
-      error = storage_->GetEntry(local_id, &existing_entry);
-
-    if (error == FILE_ERROR_OK)
-      return FILE_ERROR_EXISTS;
-    if (error != FILE_ERROR_NOT_FOUND)
-      return error;
-  }
-
-  // Generate unique local ID when needed.
-  // We don't check for ID collisions as its probability is extremely low.
-  if (local_id.empty())
-    local_id = base::GenerateGUID();
-
-  ResourceEntry new_entry(entry);
-  new_entry.set_local_id(local_id);
-
-  error = PutEntryUnderDirectory(new_entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  *out_id = local_id;
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RemoveEntry(const std::string& id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  // Disallow deletion of default entries.
-  if (IsImmutableEntry(id))
-    return FILE_ERROR_ACCESS_DENIED;
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  return RemoveEntryRecursively(id);
-}
-
-FileError ResourceMetadata::GetResourceEntryById(const std::string& id,
-                                                 ResourceEntry* out_entry) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(!id.empty());
-  DCHECK(out_entry);
-
-  return storage_->GetEntry(id, out_entry);
-}
-
-FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path,
-                                                   ResourceEntry* out_entry) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(out_entry);
-
-  std::string id;
-  FileError error = GetIdByPath(path, &id);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  return GetResourceEntryById(id, out_entry);
-}
-
-FileError ResourceMetadata::ReadDirectoryByPath(
-    const base::FilePath& path,
-    ResourceEntryVector* out_entries) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(out_entries);
-
-  std::string id;
-  FileError error = GetIdByPath(path, &id);
-  if (error != FILE_ERROR_OK)
-    return error;
-  return ReadDirectoryById(id, out_entries);
-}
-
-FileError ResourceMetadata::ReadDirectoryById(
-    const std::string& id,
-    ResourceEntryVector* out_entries) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(out_entries);
-
-  ResourceEntry entry;
-  FileError error = GetResourceEntryById(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  if (!entry.file_info().is_directory())
-    return FILE_ERROR_NOT_A_DIRECTORY;
-
-  std::vector<std::string> children;
-  error = storage_->GetChildren(id, &children);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  ResourceEntryVector entries(children.size());
-  for (size_t i = 0; i < children.size(); ++i) {
-    error = storage_->GetEntry(children[i], &entries[i]);
-    if (error != FILE_ERROR_OK)
-      return error;
-  }
-  out_entries->swap(entries);
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
-    return FILE_ERROR_NO_LOCAL_SPACE;
-
-  ResourceEntry old_entry;
-  FileError error = storage_->GetEntry(entry.local_id(), &old_entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  if (IsImmutableEntry(entry.local_id()) ||
-      old_entry.file_info().is_directory() !=  // Reject incompatible input.
-      entry.file_info().is_directory())
-    return FILE_ERROR_INVALID_OPERATION;
-
-  if (!entry.resource_id().empty()) {
-    // Multiple entries cannot share the same resource ID.
-    std::string local_id;
-    FileError error = GetIdByResourceId(entry.resource_id(), &local_id);
-    switch (error) {
-      case FILE_ERROR_OK:
-        if (local_id != entry.local_id())
-          return FILE_ERROR_INVALID_OPERATION;
-        break;
-
-      case FILE_ERROR_NOT_FOUND:
-        break;
-
-      default:
-        return error;
-    }
-  }
-
-  // Make sure that the new parent exists and it is a directory.
-  ResourceEntry new_parent;
-  error = storage_->GetEntry(entry.parent_local_id(), &new_parent);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  if (!new_parent.file_info().is_directory())
-    return FILE_ERROR_NOT_A_DIRECTORY;
-
-  // Do not overwrite cache states.
-  // Cache state should be changed via FileCache.
-  ResourceEntry updated_entry(entry);
-  if (old_entry.file_specific_info().has_cache_state()) {
-    *updated_entry.mutable_file_specific_info()->mutable_cache_state() =
-        old_entry.file_specific_info().cache_state();
-  } else if (updated_entry.file_specific_info().has_cache_state()) {
-    updated_entry.mutable_file_specific_info()->clear_cache_state();
-  }
-  // Remove from the old parent and add it to the new parent with the new data.
-  return PutEntryUnderDirectory(updated_entry);
-}
-
-FileError ResourceMetadata::GetSubDirectoriesRecursively(
-    const std::string& id,
-    std::set<base::FilePath>* sub_directories) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  std::vector<std::string> children;
-  FileError error = storage_->GetChildren(id, &children);
-  if (error != FILE_ERROR_OK)
-    return error;
-  for (size_t i = 0; i < children.size(); ++i) {
-    ResourceEntry entry;
-    error = storage_->GetEntry(children[i], &entry);
-    if (error != FILE_ERROR_OK)
-      return error;
-    if (entry.file_info().is_directory()) {
-      base::FilePath path;
-      error = GetFilePath(children[i], &path);
-      if (error != FILE_ERROR_OK)
-        return error;
-      sub_directories->insert(path);
-      GetSubDirectoriesRecursively(children[i], sub_directories);
-    }
-  }
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetChildId(const std::string& parent_local_id,
-                                       const std::string& base_name,
-                                       std::string* out_child_id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  return storage_->GetChild(parent_local_id, base_name, out_child_id);
-}
-
-std::unique_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  return storage_->GetIterator();
-}
-
-FileError ResourceMetadata::GetFilePath(const std::string& id,
-                                        base::FilePath* out_file_path) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  base::FilePath path;
-  if (!entry.parent_local_id().empty()) {
-    error = GetFilePath(entry.parent_local_id(), &path);
-    if (error != FILE_ERROR_OK)
-      return error;
-  } else if (entry.local_id() != util::kDriveGrandRootLocalId) {
-    DVLOG(1) << "Entries not under the grand root don't have paths.";
-    return FILE_ERROR_NOT_FOUND;
-  }
-  path = path.Append(base::FilePath::FromUTF8Unsafe(entry.base_name()));
-  *out_file_path = path;
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetIdByPath(const base::FilePath& file_path,
-                                        std::string* out_id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  // Start from the root.
-  std::vector<base::FilePath::StringType> components;
-  file_path.GetComponents(&components);
-  if (components.empty() ||
-      components[0] != util::GetDriveGrandRootPath().value())
-    return FILE_ERROR_NOT_FOUND;
-
-  // Iterate over the remaining components.
-  std::string id = util::kDriveGrandRootLocalId;
-  for (size_t i = 1; i < components.size(); ++i) {
-    const std::string component = base::FilePath(components[i]).AsUTF8Unsafe();
-    std::string child_id;
-    FileError error = storage_->GetChild(id, component, &child_id);
-    if (error != FILE_ERROR_OK)
-      return error;
-    id = child_id;
-  }
-  *out_id = id;
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetIdByResourceId(const std::string& resource_id,
-                                              std::string* out_local_id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  return storage_->GetIdByResourceId(resource_id, out_local_id);
-}
-
-FileError ResourceMetadata::PutEntryUnderDirectory(const ResourceEntry& entry) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(!entry.local_id().empty());
-  DCHECK(!entry.parent_local_id().empty());
-
-  std::string base_name;
-  FileError error = GetDeduplicatedBaseName(entry, &base_name);
-  if (error != FILE_ERROR_OK)
-    return error;
-  ResourceEntry updated_entry(entry);
-  updated_entry.set_base_name(base_name);
-  return storage_->PutEntry(updated_entry);
-}
-
-FileError ResourceMetadata::GetDeduplicatedBaseName(
-    const ResourceEntry& entry,
-    std::string* base_name) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(!entry.parent_local_id().empty());
-  DCHECK(!entry.title().empty());
-
-  // The entry name may have been changed due to prior name de-duplication.
-  // We need to first restore the file name based on the title before going
-  // through name de-duplication again when it is added to another directory.
-  *base_name = entry.title();
-  if (entry.has_file_specific_info() &&
-      entry.file_specific_info().is_hosted_document()) {
-    *base_name += entry.file_specific_info().document_extension();
-  }
-  *base_name = util::NormalizeFileName(*base_name);
-
-  // If |base_name| is not used, just return it.
-  bool can_use_name = false;
-  FileError error = EntryCanUseName(storage_, entry.parent_local_id(),
-                                    entry.local_id(), *base_name,
-                                    &can_use_name);
-  if (error != FILE_ERROR_OK || can_use_name)
-    return error;
-
-  // Find an unused number with binary search.
-  int smallest_known_unused_modifier = 1;
-  while (true) {
-    error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
-                            GetUniquifiedName(*base_name,
-                                              smallest_known_unused_modifier),
-                            &can_use_name);
-    if (error != FILE_ERROR_OK)
-      return error;
-    if (can_use_name)
-      break;
-
-    const int delta = base::RandInt(1, smallest_known_unused_modifier);
-    if (smallest_known_unused_modifier <= INT_MAX - delta) {
-      smallest_known_unused_modifier += delta;
-    } else {  // No luck finding an unused number. Try again.
-      smallest_known_unused_modifier = 1;
-    }
-  }
-
-  int largest_known_used_modifier = 1;
-  while (smallest_known_unused_modifier - largest_known_used_modifier > 1) {
-    const int modifier = largest_known_used_modifier +
-        (smallest_known_unused_modifier - largest_known_used_modifier) / 2;
-
-    error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
-                            GetUniquifiedName(*base_name, modifier),
-                            &can_use_name);
-    if (error != FILE_ERROR_OK)
-      return error;
-    if (can_use_name) {
-      smallest_known_unused_modifier = modifier;
-    } else {
-      largest_known_used_modifier = modifier;
-    }
-  }
-  *base_name = GetUniquifiedName(*base_name, smallest_known_unused_modifier);
-  return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RemoveEntryRecursively(const std::string& id) {
-  DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence());
-
-  ResourceEntry entry;
-  FileError error = storage_->GetEntry(id, &entry);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  if (entry.file_info().is_directory()) {
-    std::vector<std::string> children;
-    error = storage_->GetChildren(id, &children);
-    if (error != FILE_ERROR_OK)
-      return error;
-    for (size_t i = 0; i < children.size(); ++i) {
-      error = RemoveEntryRecursively(children[i]);
-      if (error != FILE_ERROR_OK)
-        return error;
-    }
-  }
-
-  error = cache_->Remove(id);
-  if (error != FILE_ERROR_OK)
-    return error;
-
-  return storage_->RemoveEntry(id);
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/resource_metadata.h b/components/drive/chromeos/resource_metadata.h
deleted file mode 100644
index d4d29de..0000000
--- a/components/drive/chromeos/resource_metadata.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_
-#define COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread_checker.h"
-#include "components/drive/file_errors.h"
-#include "components/drive/resource_metadata_storage.h"
-
-namespace base {
-class SequencedTaskRunner;
-}
-
-namespace drive {
-
-typedef std::vector<ResourceEntry> ResourceEntryVector;
-
-namespace internal {
-
-class FileCache;
-
-// Storage for Drive Metadata.
-// All methods except the constructor and Destroy() function must be run with
-// |blocking_task_runner| unless otherwise noted.
-class ResourceMetadata {
- public:
-  typedef ResourceMetadataStorage::Iterator Iterator;
-
-  ResourceMetadata(
-      ResourceMetadataStorage* storage,
-      FileCache* cache,
-      scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
-
-  // Initializes this object.
-  // This method should be called before any other methods.
-  FileError Initialize() WARN_UNUSED_RESULT;
-
-  // Destroys this object.  This method posts a task to |blocking_task_runner_|
-  // to safely delete this object.
-  // Must be called on the UI thread.
-  void Destroy();
-
-  // Resets this object.
-  FileError Reset();
-
-  // Returns the start page token for the users default corpus.
-  FileError GetStartPageToken(std::string* out_value);
-
-  // Sets the start page token for the users default corpus.
-  FileError SetStartPageToken(const std::string& value);
-
-  // Adds |entry| to the metadata tree based on its parent_local_id.
-  FileError AddEntry(const ResourceEntry& entry, std::string* out_id);
-
-  // Removes entry with |id| from its parent.
-  FileError RemoveEntry(const std::string& id);
-
-  // Finds an entry (a file or a directory) by |id|.
-  FileError GetResourceEntryById(const std::string& id,
-                                 ResourceEntry* out_entry);
-
-  // Synchronous version of GetResourceEntryByPathOnUIThread().
-  FileError GetResourceEntryByPath(const base::FilePath& file_path,
-                                   ResourceEntry* out_entry);
-
-  // Finds and reads a directory by |file_path|.
-  FileError ReadDirectoryByPath(const base::FilePath& file_path,
-                                ResourceEntryVector* out_entries);
-
-  // Finds and reads a directory by |id|.
-  FileError ReadDirectoryById(const std::string& id,
-                              ResourceEntryVector* out_entries);
-
-  // Replaces an existing entry with the same local ID as |entry|.
-  FileError RefreshEntry(const ResourceEntry& entry);
-
-  // Recursively gets directories under the entry pointed to by |id|.
-  FileError GetSubDirectoriesRecursively(
-      const std::string& id,
-      std::set<base::FilePath>* sub_directories);
-
-  // Returns the id of the resource named |base_name| directly under
-  // the directory with |parent_local_id|.
-  // If not found, empty string will be returned.
-  FileError GetChildId(const std::string& parent_local_id,
-                       const std::string& base_name,
-                       std::string* out_child_id);
-
-  // Returns an object to iterate over entries.
-  std::unique_ptr<Iterator> GetIterator();
-
-  // Returns virtual file path of the entry.
-  FileError GetFilePath(const std::string& id, base::FilePath* out_file_path);
-
-  // Returns ID of the entry at the given path.
-  FileError GetIdByPath(const base::FilePath& file_path, std::string* out_id);
-
-  // Returns the local ID associated with the given resource ID.
-  FileError GetIdByResourceId(const std::string& resource_id,
-                              std::string* out_local_id);
-
- private:
-  // Note: Use Destroy() to delete this object.
-  ~ResourceMetadata();
-
-  // Sets up entries which should be present by default.
-  FileError SetUpDefaultEntries();
-
-  // Used to implement Destroy().
-  void DestroyOnBlockingPool();
-
-  // Puts an entry under its parent directory. Removes the child from the old
-  // parent if there is. This method will also do name de-duplication to ensure
-  // that the exposed presentation path does not have naming conflicts. Two
-  // files with the same name "Foo" will be renamed to "Foo (1)" and "Foo (2)".
-  FileError PutEntryUnderDirectory(const ResourceEntry& entry);
-
-  // Returns an unused base name for |entry|.
-  FileError GetDeduplicatedBaseName(const ResourceEntry& entry,
-                                    std::string* base_name);
-
-  // Removes the entry and its descendants.
-  FileError RemoveEntryRecursively(const std::string& id);
-
-  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-
-  ResourceMetadataStorage* storage_;
-  FileCache* cache_;
-
-  THREAD_CHECKER(thread_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceMetadata);
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_
diff --git a/components/drive/chromeos/search_metadata.cc b/components/drive/chromeos/search_metadata.cc
index 99e9b115..c0584d7 100644
--- a/components/drive/chromeos/search_metadata.cc
+++ b/components/drive/chromeos/search_metadata.cc
@@ -5,15 +5,8 @@
 #include "components/drive/chromeos/search_metadata.h"
 
 #include <algorithm>
-#include <map>
-#include <queue>
-#include <utility>
 
-#include "base/bind.h"
 #include "base/i18n/string_search.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -26,240 +19,6 @@
 
 namespace {
 
-struct ResultCandidate {
-  ResultCandidate(const std::string& local_id,
-                  const ResourceEntry& entry,
-                  const std::string& highlighted_base_name)
-      : local_id(local_id),
-        entry(entry),
-        highlighted_base_name(highlighted_base_name) {
-  }
-
-  std::string local_id;
-  ResourceEntry entry;
-  std::string highlighted_base_name;
-};
-
-// Used to sort the result candidates per the last accessed/modified time. The
-// recently accessed/modified files come first.
-bool CompareByTimestamp(const ResourceEntry& a,
-                        const ResourceEntry& b,
-                        MetadataSearchOrder order) {
-  const PlatformFileInfoProto& a_file_info = a.file_info();
-  const PlatformFileInfoProto& b_file_info = b.file_info();
-
-  switch (order) {
-    case MetadataSearchOrder::LAST_ACCESSED:
-      if (a_file_info.last_accessed() != b_file_info.last_accessed())
-        return a_file_info.last_accessed() > b_file_info.last_accessed();
-
-      // When the entries have the same last access time (which happens quite
-      // often because Drive server doesn't set the field until an entry is
-      /// viewed via drive.google.com), we use last modified time as the tie
-      // breaker.
-      return a_file_info.last_modified() > b_file_info.last_modified();
-    case MetadataSearchOrder::LAST_MODIFIED:
-      return a_file_info.last_modified() > b_file_info.last_modified();
-  }
-}
-
-struct ResultCandidateComparator {
-  explicit ResultCandidateComparator(MetadataSearchOrder order)
-      : order_(order) {}
-  bool operator()(const std::unique_ptr<ResultCandidate>& a,
-                  const std::unique_ptr<ResultCandidate>& b) const {
-    return CompareByTimestamp(a->entry, b->entry, order_);
-  }
-
- private:
-  const MetadataSearchOrder order_;
-};
-
-typedef std::priority_queue<std::unique_ptr<ResultCandidate>,
-                            std::vector<std::unique_ptr<ResultCandidate>>,
-                            ResultCandidateComparator>
-    ResultCandidateQueue;
-
-// Classifies the given entry as hidden if it's not under specific directories.
-class HiddenEntryClassifier {
- public:
-  HiddenEntryClassifier(ResourceMetadata* metadata,
-                        const std::string& mydrive_local_id)
-      : metadata_(metadata) {
-    // Only things under My Drive, drive/other and drive/team_drives are not
-    // hidden.
-    is_hiding_child_[mydrive_local_id] = false;
-    is_hiding_child_[util::kDriveOtherDirLocalId] = false;
-    is_hiding_child_[util::kDriveTeamDrivesDirLocalId] = false;
-
-    // Everything else is hidden, including the directories mentioned above
-    // themselves.
-    is_hiding_child_[""] = true;
-  }
-
-  // |result| is set to true if |entry| is hidden.
-  FileError IsHidden(const ResourceEntry& entry, bool* result) {
-    // Look up for parents recursively.
-    std::vector<std::string> undetermined_ids;
-    undetermined_ids.push_back(entry.parent_local_id());
-
-    std::map<std::string, bool>::iterator it =
-        is_hiding_child_.find(undetermined_ids.back());
-    for (; it == is_hiding_child_.end();
-         it = is_hiding_child_.find(undetermined_ids.back())) {
-      ResourceEntry parent;
-      FileError error =
-          metadata_->GetResourceEntryById(undetermined_ids.back(), &parent);
-      if (error != FILE_ERROR_OK)
-        return error;
-      undetermined_ids.push_back(parent.parent_local_id());
-    }
-
-    // Cache the result.
-    undetermined_ids.pop_back();  // The last one is already in the map.
-    for (size_t i = 0; i < undetermined_ids.size(); ++i)
-      is_hiding_child_[undetermined_ids[i]] = it->second;
-
-    *result = it->second;
-    return FILE_ERROR_OK;
-  }
-
- private:
-  ResourceMetadata* metadata_;
-
-  // local ID to is_hidden map.
-  std::map<std::string, bool> is_hiding_child_;
-};
-
-// Used to implement SearchMetadata.
-// Adds entry to the result when appropriate.
-// In particular, if size of |queries| is larger than 0, only adds files with
-// the name matching the query.
-FileError MaybeAddEntryToResult(
-    ResourceMetadata* resource_metadata,
-    ResourceMetadata::Iterator* it,
-    const std::vector<std::unique_ptr<
-        base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>& queries,
-    const SearchMetadataPredicate& predicate,
-    size_t at_most_num_matches,
-    MetadataSearchOrder order,
-    HiddenEntryClassifier* hidden_entry_classifier,
-    ResultCandidateQueue* result_candidates) {
-  DCHECK_GE(at_most_num_matches, result_candidates->size());
-
-  const ResourceEntry& entry = it->GetValue();
-
-  // If the candidate set is already full, and this |entry| is old, do nothing.
-  // We perform this check first in order to avoid the costly find-and-highlight
-  // or FilePath lookup as much as possible.
-  if (result_candidates->size() == at_most_num_matches &&
-      !CompareByTimestamp(entry, result_candidates->top()->entry, order))
-    return FILE_ERROR_OK;
-
-  // Add |entry| to the result if the entry is eligible for the given
-  // |options| and matches the query. The base name of the entry must
-  // contain |query| to match the query.
-  std::string highlighted;
-  if (!predicate.Run(entry) ||
-      !FindAndHighlight(entry.base_name(), queries, &highlighted))
-    return FILE_ERROR_OK;
-
-  // Hidden entry should not be returned.
-  bool hidden = false;
-  FileError error = hidden_entry_classifier->IsHidden(entry, &hidden);
-  if (error != FILE_ERROR_OK || hidden)
-    return error;
-
-  // Make space for |entry| when appropriate.
-  if (result_candidates->size() == at_most_num_matches)
-    result_candidates->pop();
-  result_candidates->push(
-      std::make_unique<ResultCandidate>(it->GetID(), entry, highlighted));
-  return FILE_ERROR_OK;
-}
-
-// Implements SearchMetadata().
-FileError SearchMetadataOnBlockingPool(ResourceMetadata* resource_metadata,
-                                       const std::string& query_text,
-                                       const SearchMetadataPredicate& predicate,
-                                       int at_most_num_matches,
-                                       MetadataSearchOrder order,
-                                       MetadataSearchResultVector* results) {
-  ResultCandidateQueue result_candidates((ResultCandidateComparator(order)));
-
-  // Prepare data structure for searching.
-  std::vector<base::string16> keywords =
-      base::SplitString(base::UTF8ToUTF16(query_text),
-                        base::StringPiece16(base::kWhitespaceUTF16),
-                        base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-
-  std::vector<std::unique_ptr<
-      base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
-      queries;
-  for (const auto& keyword : keywords) {
-    queries.push_back(
-        std::make_unique<
-            base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
-            keyword));
-  }
-
-  // Prepare an object to filter out hidden entries.
-  ResourceEntry mydrive;
-  FileError error = resource_metadata->GetResourceEntryByPath(
-      util::GetDriveMyDriveRootPath(), &mydrive);
-  if (error != FILE_ERROR_OK)
-    return error;
-  HiddenEntryClassifier hidden_entry_classifier(resource_metadata,
-                                                mydrive.local_id());
-
-  // Iterate over entries.
-  std::unique_ptr<ResourceMetadata::Iterator> it =
-      resource_metadata->GetIterator();
-  for (; !it->IsAtEnd(); it->Advance()) {
-    FileError error = MaybeAddEntryToResult(
-        resource_metadata, it.get(), queries, predicate, at_most_num_matches,
-        order, &hidden_entry_classifier, &result_candidates);
-    if (error != FILE_ERROR_OK)
-      return error;
-  }
-
-  // Prepare the result.
-  for (; !result_candidates.empty(); result_candidates.pop()) {
-    const ResultCandidate& candidate = *result_candidates.top();
-    // The path field of entries in result_candidates are empty at this point,
-    // because we don't want to run the expensive metadata DB look up except for
-    // the final results. Hence, here we fill the part.
-    base::FilePath path;
-    error = resource_metadata->GetFilePath(candidate.local_id, &path);
-    if (error != FILE_ERROR_OK)
-      return error;
-    bool is_directory = candidate.entry.file_info().is_directory();
-    results->push_back(MetadataSearchResult(
-        path, is_directory, candidate.highlighted_base_name,
-        candidate.entry.file_specific_info().md5()));
-  }
-
-  // Reverse the order here because |result_candidates| puts the most
-  // uninteresting candidate at the top.
-  std::reverse(results->begin(), results->end());
-
-  return FILE_ERROR_OK;
-}
-
-// Runs the SearchMetadataCallback and updates the histogram.
-void RunSearchMetadataCallback(
-    SearchMetadataCallback callback,
-    const base::TimeTicks& start_time,
-    std::unique_ptr<MetadataSearchResultVector> results,
-    FileError error) {
-  if (error != FILE_ERROR_OK)
-    results.reset();
-  std::move(callback).Run(error, std::move(results));
-
-  UMA_HISTOGRAM_TIMES("Drive.SearchMetadataTime",
-                      base::TimeTicks::Now() - start_time);
-}
-
 // Appends substring of |original_text| to |highlighted_text| with highlight.
 void AppendStringWithHighlight(const base::string16& original_text,
                                size_t start,
@@ -278,57 +37,6 @@
 
 }  // namespace
 
-void SearchMetadata(
-    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
-    ResourceMetadata* resource_metadata,
-    const std::string& query,
-    const SearchMetadataPredicate& predicate,
-    size_t at_most_num_matches,
-    MetadataSearchOrder order,
-    SearchMetadataCallback callback) {
-  DCHECK(callback);
-
-  const base::TimeTicks start_time = base::TimeTicks::Now();
-
-  std::unique_ptr<MetadataSearchResultVector> results(
-      new MetadataSearchResultVector);
-  MetadataSearchResultVector* results_ptr = results.get();
-  base::PostTaskAndReplyWithResult(
-      blocking_task_runner.get(), FROM_HERE,
-      base::BindOnce(&SearchMetadataOnBlockingPool, resource_metadata, query,
-                     predicate, at_most_num_matches, order, results_ptr),
-      base::BindOnce(&RunSearchMetadataCallback, std::move(callback),
-                     start_time, std::move(results)));
-}
-
-bool MatchesType(int options, const ResourceEntry& entry) {
-  if ((options & SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS) &&
-      entry.file_specific_info().is_hosted_document())
-    return false;
-
-  if ((options & SEARCH_METADATA_EXCLUDE_DIRECTORIES) &&
-      entry.file_info().is_directory())
-    return false;
-
-  if (options & SEARCH_METADATA_SHARED_WITH_ME)
-    return entry.shared_with_me();
-
-  if (options & SEARCH_METADATA_OFFLINE) {
-    if (entry.file_specific_info().is_hosted_document()) {
-      // Not all hosted documents are cached by Drive offline app.
-      // https://support.google.com/drive/answer/2375012
-      std::string mime_type = entry.file_specific_info().content_mime_type();
-      return mime_type == drive::util::kGoogleDocumentMimeType ||
-             mime_type == drive::util::kGoogleSpreadsheetMimeType ||
-             mime_type == drive::util::kGooglePresentationMimeType ||
-             mime_type == drive::util::kGoogleDrawingMimeType;
-    }
-    return entry.file_specific_info().cache_state().is_present();
-  }
-
-  return true;
-}
-
 bool FindAndHighlight(
     const std::string& text,
     const std::vector<std::unique_ptr<
diff --git a/components/drive/chromeos/search_metadata.h b/components/drive/chromeos/search_metadata.h
index f515c2d..b0976852 100644
--- a/components/drive/chromeos/search_metadata.h
+++ b/components/drive/chromeos/search_metadata.h
@@ -5,15 +5,9 @@
 #ifndef COMPONENTS_DRIVE_CHROMEOS_SEARCH_METADATA_H_
 #define COMPONENTS_DRIVE_CHROMEOS_SEARCH_METADATA_H_
 
-#include <stddef.h>
-
-#include <memory>
 #include <string>
 #include <vector>
 
-#include "base/sequenced_task_runner.h"
-#include "components/drive/chromeos/file_system_interface.h"
-
 namespace base {
 namespace i18n {
 class FixedPatternStringSearchIgnoringCaseAndAccents;
@@ -23,38 +17,6 @@
 namespace drive {
 namespace internal {
 
-class ResourceMetadata;
-
-typedef base::RepeatingCallback<bool(const ResourceEntry&)>
-    SearchMetadataPredicate;
-
-// Searches the local resource metadata, and returns the entries
-// |at_most_num_matches| that contain |query| in their base names. Search is
-// done in a case-insensitive fashion. |query| is splitted into keywords by
-// whitespace. All keywords are considered as AND condition. The eligible
-// entries are selected based on the given |options|, which is a bit-wise OR of
-// SearchMetadataOptions. |callback| must not be null. Must be called on UI
-// thread. Empty |query| matches any base name. i.e. returns everything.
-// |blocking_task_runner| must be the same one as |resource_metadata| uses.
-void SearchMetadata(
-    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
-    ResourceMetadata* resource_metadata,
-    const std::string& query,
-    const SearchMetadataPredicate& predicate,
-    size_t at_most_num_matches,
-    MetadataSearchOrder order,
-    SearchMetadataCallback callback);
-
-// Returns true if |entry| is eligible for the search |options| and should be
-// tested for the match with the query.  If
-// SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS is requested, the hosted documents
-// are skipped. If SEARCH_METADATA_EXCLUDE_DIRECTORIES is requested, the
-// directories are skipped. If SEARCH_METADATA_SHARED_WITH_ME is requested, only
-// the entries with shared-with-me label will be tested. If
-// SEARCH_METADATA_OFFLINE is requested, only hosted documents and cached files
-// match with the query. This option can not be used with other options.
-bool MatchesType(int options, const ResourceEntry& entry);
-
 // Finds |queries| in |text| while ignoring cases or accents. Cases of non-ASCII
 // characters are also ignored; they are compared in the 'Primary Level' of
 // http://userguide.icu-project.org/collation/concepts.
diff --git a/components/drive/chromeos/team_drive.cc b/components/drive/chromeos/team_drive.cc
deleted file mode 100644
index f162f104..0000000
--- a/components/drive/chromeos/team_drive.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/team_drive.h"
-
-namespace drive {
-namespace internal {
-
-TeamDrive::TeamDrive(const std::string& team_drive_id)
-    : team_drive_id_(team_drive_id) {}
-
-TeamDrive::TeamDrive(const std::string& team_drive_id,
-                     const std::string& team_drive_name,
-                     const base::FilePath& team_drive_path)
-    : team_drive_id_(team_drive_id),
-      team_drive_name_(team_drive_name),
-      team_drive_path_(team_drive_path) {}
-
-TeamDrive::~TeamDrive() = default;
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/chromeos/team_drive.h b/components/drive/chromeos/team_drive.h
deleted file mode 100644
index 7567a6b5..0000000
--- a/components/drive/chromeos/team_drive.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_
-#define COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_
-
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-
-namespace drive {
-namespace internal {
-
-// Represents a team drive object that can be passed to observers of team drive
-// changes, for example when loading the list of team drives, or removing/adding
-// a team drive when processing the users change list.
-class TeamDrive {
- public:
-  TeamDrive(const std::string& team_drive_id);
-
-  TeamDrive(const std::string& team_drive_id,
-            const std::string& team_drive_name,
-            const base::FilePath& team_drive_path);
-  ~TeamDrive();
-
-  // The team drive ID returned from the server.
-  // https://developers.google.com/drive/api/v2/reference/teamdrives#resource
-  const std::string& team_drive_id() const { return team_drive_id_; }
-
-  // The team drive name returned from the server. May be empty when deleting
-  // a team drive, which will be based on the id() and not the name.
-  const std::string& team_drive_name() const { return team_drive_name_; }
-
-  // The path where the team drive is mounted in the file system. May be
-  // empty when deleting the team drive.
-  const base::FilePath& team_drive_path() const { return team_drive_path_; }
-
- private:
-  std::string team_drive_id_;
-  std::string team_drive_name_;
-  base::FilePath team_drive_path_;
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_
diff --git a/components/drive/chromeos/team_drive_list_observer.h b/components/drive/chromeos/team_drive_list_observer.h
deleted file mode 100644
index a6109e2..0000000
--- a/components/drive/chromeos/team_drive_list_observer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_OBSERVER_H_
-#define COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_OBSERVER_H_
-
-#include <vector>
-
-#include "components/drive/chromeos/team_drive.h"
-
-namespace drive {
-namespace internal {
-
-// Interface for classes that need to observe events from the
-// TeamDriveListLoader.
-// TODO(slangley): Consider merging with ChangeListLoaderObserver.
-class TeamDriveListObserver {
- public:
-  // Called every time that the complete list of team drives has been retrieved
-  // from the server.
-  // - |team_drives_list| is the entire list of team drives the user has
-  //   access to.
-  // - |added_team_drives| is the list of team drives that have been added
-  //   as part of loading the team drives.
-  // - |removed_team_drives| will be the list of team drives that have been
-  //   removed as part of loading the team drives.
-  virtual void OnTeamDriveListLoaded(
-      const std::vector<TeamDrive>& team_drives_list,
-      const std::vector<TeamDrive>& added_team_drives,
-      const std::vector<TeamDrive>& removed_team_drives) = 0;
-
- protected:
-  virtual ~TeamDriveListObserver() = default;
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_LOADER_OBSERVER_H_
diff --git a/components/drive/drive_api_util.cc b/components/drive/drive_api_util.cc
index 05376bd1..6c57cf9 100644
--- a/components/drive/drive_api_util.cc
+++ b/components/drive/drive_api_util.cc
@@ -4,25 +4,17 @@
 
 #include "components/drive/drive_api_util.h"
 
-#include <stddef.h>
-#include <stdint.h>
-
 #include <string>
 
 #include "base/files/file.h"
 #include "base/hash/md5.h"
-#include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/atomic_flag.h"
-#include "base/task_runner_util.h"
-#include "base/values.h"
-#include "google_apis/drive/drive_api_parser.h"
 #include "third_party/re2/src/re2/re2.h"
-#include "url/gurl.h"
 
 namespace drive {
 namespace util {
@@ -173,14 +165,6 @@
   return base::MD5DigestToBase16(digest);
 }
 
-std::string GetHostedDocumentExtension(const std::string& mime_type) {
-  for (size_t i = 0; i < base::size(kHostedDocumentKinds); ++i) {
-    if (mime_type == kHostedDocumentKinds[i].mime_type)
-      return kHostedDocumentKinds[i].extension;
-  }
-  return kUnknownHostedDocumentExtension;
-}
-
 bool IsKnownHostedDocumentMimeType(const std::string& mime_type) {
   for (size_t i = 0; i < base::size(kHostedDocumentKinds); ++i) {
     if (mime_type == kHostedDocumentKinds[i].mime_type)
@@ -198,13 +182,6 @@
   return extension == kUnknownHostedDocumentExtension;
 }
 
-void RunAsyncTask(base::TaskRunner* task_runner,
-                  const base::Location& from_here,
-                  base::OnceCallback<FileError()> task,
-                  base::OnceCallback<void(FileError)> reply) {
-  PostTaskAndReplyWithResult(task_runner, from_here, std::move(task),
-                             std::move(reply));
-}
 
 }  // namespace util
 }  // namespace drive
diff --git a/components/drive/drive_api_util.h b/components/drive/drive_api_util.h
index cc94229..39afcf4 100644
--- a/components/drive/drive_api_util.h
+++ b/components/drive/drive_api_util.h
@@ -5,19 +5,11 @@
 #ifndef COMPONENTS_DRIVE_DRIVE_API_UTIL_H_
 #define COMPONENTS_DRIVE_DRIVE_API_UTIL_H_
 
-#include <memory>
 #include <string>
 
-#include "base/callback.h"
-#include "components/drive/file_errors.h"
-#include "google_apis/drive/drive_api_error_codes.h"
-#include "google_apis/drive/drive_common_callbacks.h"
-
 namespace base {
 class AtomicFlag;
-class Location;
 class FilePath;
-class TaskRunner;
 }  // namespace base
 
 namespace drive {
@@ -60,10 +52,6 @@
 std::string GetMd5Digest(const base::FilePath& file_path,
                          const base::AtomicFlag* cancellation_flag);
 
-// Returns preferred file extension for hosted documents which have given mime
-// type.
-std::string GetHostedDocumentExtension(const std::string& mime_type);
-
 // Returns true if the given mime type is corresponding to one of known hosted
 // document types.
 bool IsKnownHostedDocumentMimeType(const std::string& mime_type);
@@ -72,13 +60,6 @@
 // hosted document types.
 bool HasHostedDocumentExtension(const base::FilePath& path);
 
-// Runs |task| on |task_runner|, then runs |reply| on the original thread with
-// the resulting error code.
-void RunAsyncTask(base::TaskRunner* task_runner,
-                  const base::Location& from_here,
-                  base::OnceCallback<FileError()> task,
-                  base::OnceCallback<void(FileError)> reply);
-
 }  // namespace util
 }  // namespace drive
 
diff --git a/components/drive/drive_file_util_unittest.cc b/components/drive/drive_file_util_unittest.cc
deleted file mode 100644
index b7f269c7..0000000
--- a/components/drive/drive_file_util_unittest.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2018 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 <memory>
-#include <string>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_file_util.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-// The start page token of the resource metadata used in DriveFileUtilTest.
-constexpr char kTestStartPageToken[] = "123456";
-
-// Creates a ResourceEntry for a directory with explicitly set resource_id.
-ResourceEntry CreateDirectoryEntryWithResourceId(
-    const std::string& title,
-    const std::string& resource_id,
-    const std::string& parent_local_id) {
-  ResourceEntry entry;
-  entry.set_title(title);
-  entry.set_resource_id(resource_id);
-  entry.set_parent_local_id(parent_local_id);
-  entry.mutable_file_info()->set_is_directory(true);
-  entry.mutable_directory_specific_info()->set_start_page_token(
-      kTestStartPageToken);
-  return entry;
-}
-
-void AddTeamDriveRootEntry(ResourceMetadata* resource_metadata,
-                           const std::string& team_drive_id,
-                           const std::string& team_drive_name) {
-  std::string local_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath(
-                               util::GetDriveTeamDrivesRootPath(), &local_id));
-
-  std::string root_local_id = local_id;
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata->AddEntry(
-                CreateDirectoryEntryWithResourceId(
-                    team_drive_name, team_drive_id, root_local_id),
-                &local_id));
-}
-
-}  // namespace
-
-// Tests for methods running on the blocking task runner.
-class DriveFileUtilTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_TRUE(metadata_storage_->Initialize());
-
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-    ASSERT_TRUE(cache_->Initialize());
-
-    resource_metadata_.reset(
-        new ResourceMetadata(metadata_storage_.get(), cache_.get(),
-                             base::ThreadTaskRunnerHandle::Get()));
-
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
-  }
-
-  base::ScopedTempDir temp_dir_;
-  content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
-      resource_metadata_;
-};
-
-TEST_F(DriveFileUtilTest, TeamDriveStartPageToken) {
-  constexpr char kTeamDriveId[] = "team_drive_id_1";
-  constexpr char kTeamDriveName[] = "My Team Drive";
-  constexpr char kStartPageToken[] = "123456";
-
-  AddTeamDriveRootEntry(resource_metadata_.get(), kTeamDriveId, kTeamDriveName);
-
-  EXPECT_EQ(FILE_ERROR_OK, SetStartPageToken(resource_metadata_.get(),
-                                             kTeamDriveId, kStartPageToken));
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK, GetStartPageToken(resource_metadata_.get(),
-                                             kTeamDriveId, &start_page_token));
-  EXPECT_EQ(kStartPageToken, start_page_token);
-}
-
-TEST_F(DriveFileUtilTest, TeamDriveStartPageToken_NoEntry) {
-  constexpr char kTeamDriveId[] = "team_drive_id_1";
-  constexpr char kStartPageToken[] = "123456";
-
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
-            SetStartPageToken(resource_metadata_.get(), kTeamDriveId,
-                              kStartPageToken));
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
-            GetStartPageToken(resource_metadata_.get(), kTeamDriveId,
-                              &start_page_token));
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/drive_operation_queue_unittest.cc b/components/drive/drive_operation_queue_unittest.cc
deleted file mode 100644
index 68ea39b6..0000000
--- a/components/drive/drive_operation_queue_unittest.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/drive_operation_queue.h"
-#include "base/bind.h"
-#include "base/memory/weak_ptr.h"
-#include "base/test/bind_test_util.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "components/drive/file_errors.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-
-namespace {
-
-constexpr int kDesiredQPS = 5;
-constexpr base::TimeDelta kTokenRefreshRate =
-    base::TimeDelta::FromSeconds(1) / kDesiredQPS;
-
-class FakeDriveOperation {
- public:
-  FakeDriveOperation() {}
-
-  base::WeakPtr<FakeDriveOperation> GetWeakPtr() {
-    return weak_ptr_factory_.GetWeakPtr();
-  }
-
-  void FakeOperation(const FileOperationCallback& callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    CHECK(!task_has_executed);
-
-    task_has_executed = true;
-    callback.Run(FILE_ERROR_OK);
-  }
-
-  bool HasTaskExecuted() const { return task_has_executed; }
-
- private:
-  bool task_has_executed = false;
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  base::WeakPtrFactory<FakeDriveOperation> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDriveOperation);
-};
-
-}  // namespace
-
-class DriveOperationQueueTest : public testing::Test {
- protected:
-  using OperationQueue = DriveBackgroundOperationQueue<FakeDriveOperation>;
-
-  void SetUp() override {
-    task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
-        base::TestMockTimeTaskRunner::Type::kBoundToThread);
-    operation_queue_ =
-        std::make_unique<DriveBackgroundOperationQueue<FakeDriveOperation>>(
-            kDesiredQPS, task_runner_->GetMockTickClock());
-  }
-
-  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
-  std::unique_ptr<OperationQueue> operation_queue_;
-};
-
-// Put up to |kDesiredQPS| entries in queue, all should run without the timer
-// needing to advance.
-TEST_F(DriveOperationQueueTest, BurstMode) {
-  std::vector<std::unique_ptr<FakeDriveOperation>> operations;
-
-  for (int i = 0; i < kDesiredQPS; ++i) {
-    operations.emplace_back(std::make_unique<FakeDriveOperation>());
-  }
-
-  int callbacks_run = 0;
-
-  for (auto& operation : operations) {
-    operation_queue_->AddOperation(
-        operation->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operation->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError error) { ++callbacks_run; }));
-  }
-
-  // Execute all pending tasks without advancing virtual time.
-  task_runner_->RunUntilIdle();
-
-  ASSERT_EQ(callbacks_run, kDesiredQPS);
-
-  for (auto& operation : operations) {
-    ASSERT_TRUE(operation->HasTaskExecuted());
-  }
-}
-
-// Ensure that tokens are refilled as the timer advances.
-TEST_F(DriveOperationQueueTest, RefillTokens) {
-  constexpr int kAdditionalTasks = 5;
-  constexpr int kTasksToQueue = kDesiredQPS + kAdditionalTasks;
-
-  std::vector<std::unique_ptr<FakeDriveOperation>> operations;
-
-  for (int i = 0; i < kTasksToQueue; ++i) {
-    operations.emplace_back(std::make_unique<FakeDriveOperation>());
-  }
-
-  int callbacks_run = 0;
-
-  for (int i = 0; i < kTasksToQueue; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError) { ++callbacks_run; }));
-  }
-
-  // Execute all pending tasks without advancing virtual time.
-  task_runner_->RunUntilIdle();
-
-  // We should only have advanced through the burst mode tasks.
-  ASSERT_EQ(callbacks_run, kDesiredQPS);
-
-  // Move time forward, should cause a token to be refreshed and an operation to
-  // run.
-  int last_callbacks_run = callbacks_run;
-  for (int i = kDesiredQPS; i < kTasksToQueue; ++i) {
-    ASSERT_FALSE(operations[i]->HasTaskExecuted());
-
-    task_runner_->FastForwardBy(kTokenRefreshRate);
-
-    ASSERT_EQ(callbacks_run, last_callbacks_run + 1);
-    ASSERT_TRUE(operations[i]->HasTaskExecuted());
-    last_callbacks_run = callbacks_run;
-  }
-
-  ASSERT_EQ(kTasksToQueue, callbacks_run);
-}
-
-// Ensure that invalidated tasks are not run, but also do not block the queue.
-TEST_F(DriveOperationQueueTest, InvalidateTasks) {
-  constexpr int kTasksToInvalidate = kDesiredQPS * 2;
-  constexpr int kAdditionalTasks = 5;
-  constexpr int kTasksToQueue =
-      kDesiredQPS + kAdditionalTasks + kTasksToInvalidate;
-
-  std::vector<std::unique_ptr<FakeDriveOperation>> operations;
-
-  for (int i = 0; i < kTasksToQueue; ++i) {
-    operations.emplace_back(std::make_unique<FakeDriveOperation>());
-  }
-
-  int callbacks_run = 0;
-
-  for (int i = 0; i < kTasksToQueue; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError) { ++callbacks_run; }));
-  }
-
-  // Execute all pending tasks without advancing virtual time.
-  task_runner_->RunUntilIdle();
-
-  // We should only have advanced through the burst mode tasks.
-  ASSERT_EQ(callbacks_run, kDesiredQPS);
-
-  // Erase tasks from the queue, which will invalidate their weak ptrs and
-  // prevent callbacks from being run.
-  operations.erase(operations.begin(),
-                   operations.begin() + callbacks_run + kTasksToInvalidate);
-
-  // Fast forward until all tasks have been executed.
-  int last_callbacks_run = callbacks_run;
-  task_runner_->FastForwardUntilNoTasksRemain();
-
-  // All expected tasks should now have been run.
-  ASSERT_EQ(last_callbacks_run + kAdditionalTasks, callbacks_run);
-}
-
-// Ensure that tasks added after burst mode has finished are only executed
-// at the desired QPS.
-TEST_F(DriveOperationQueueTest, DoNotRepeatBurstMode) {
-  constexpr int kTasksToCreate = kDesiredQPS * 2;
-
-  std::vector<std::unique_ptr<FakeDriveOperation>> operations;
-
-  for (int i = 0; i < kTasksToCreate; ++i) {
-    operations.emplace_back(std::make_unique<FakeDriveOperation>());
-  }
-
-  int callbacks_run = 0;
-
-  // Only run the burst mode tasks.
-  for (int i = 0; i < kDesiredQPS; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError error) { ++callbacks_run; }));
-  }
-
-  // Execute all pending tasks without advancing virtual time.
-  task_runner_->FastForwardBy(kTokenRefreshRate);
-
-  ASSERT_EQ(callbacks_run, kDesiredQPS);
-
-  // Add the remaining tasks to the queue, only the first should run as we've
-  // only advanced 1 refresh period.
-  for (int i = kDesiredQPS; i < kTasksToCreate; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError error) { ++callbacks_run; }));
-  }
-
-  int last_callbacks_run = callbacks_run;
-  // Just run the tasks that are scheduled now.
-  task_runner_->RunUntilIdle();
-  ASSERT_EQ(last_callbacks_run + 1, callbacks_run);
-
-  // Run the rest of the tasks.
-  task_runner_->FastForwardUntilNoTasksRemain();
-  ASSERT_EQ(kTasksToCreate, callbacks_run);
-}
-
-// Ensure that burst mode is re-enabled if more than 1 second has advanced since
-// the last task finished.
-TEST_F(DriveOperationQueueTest, RepeatBurstMode) {
-  constexpr int kTasksToCreate = kDesiredQPS * 3;
-
-  std::vector<std::unique_ptr<FakeDriveOperation>> operations;
-
-  for (int i = 0; i < kTasksToCreate; ++i) {
-    operations.emplace_back(std::make_unique<FakeDriveOperation>());
-  }
-
-  int callbacks_run = 0;
-
-  // Only run the burst mode tasks.
-  for (int i = 0; i < kDesiredQPS; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError error) { ++callbacks_run; }));
-  }
-
-  // Execute all pending tasks.
-  task_runner_->FastForwardUntilNoTasksRemain();
-  ASSERT_EQ(kDesiredQPS, callbacks_run);
-
-  // Move forward two seconds, so that we should reset burst mode.
-  task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
-
-  // Add the remaining tasks to the queue, all should run in burst mode.
-  for (int i = kDesiredQPS; i < kTasksToCreate; ++i) {
-    operation_queue_->AddOperation(
-        operations[i]->GetWeakPtr(),
-        base::BindOnce(&FakeDriveOperation::FakeOperation,
-                       operations[i]->GetWeakPtr()),
-        base::BindLambdaForTesting(
-            [&callbacks_run](drive::FileError error) { ++callbacks_run; }));
-  }
-
-  callbacks_run = 0;
-
-  // Execute all pending tasks without advancing virtual time.
-  task_runner_->RunUntilIdle();
-
-  // We should only have advanced through the burst mode tasks.
-  ASSERT_EQ(kDesiredQPS, callbacks_run);
-
-  // The last tasks should not have been run yet.
-  for (int i = 2 * kDesiredQPS; i < kTasksToCreate; ++i) {
-    ASSERT_FALSE(operations[i]->HasTaskExecuted());
-  }
-
-  // Run the remaining tasks, which should happen at desired qps
-  base::TimeTicks start_ticks = task_runner_->NowTicks();
-  task_runner_->FastForwardUntilNoTasksRemain();
-
-  ASSERT_LE(base::TimeDelta::FromSeconds(1),
-            task_runner_->NowTicks() - start_ticks);
-
-  // All tasks have been run.
-  for (auto& operation : operations) {
-    ASSERT_TRUE(operation->HasTaskExecuted());
-  }
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/file_change.cc b/components/drive/file_change.cc
deleted file mode 100644
index 456b864..0000000
--- a/components/drive/file_change.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_change.h"
-
-#include <sstream>
-
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "components/drive/drive.pb.h"
-
-namespace drive {
-
-FileChange::Change::Change(ChangeType change, FileType file_type)
-    : change_(change), file_type_(file_type) {
-}
-
-FileChange::Change::Change(ChangeType change,
-                           FileType file_type,
-                           const std::string& team_drive_id)
-    : change_(change), file_type_(file_type), team_drive_id_(team_drive_id) {}
-
-std::string FileChange::Change::DebugString() const {
-  const char* change_string = nullptr;
-  switch (change()) {
-    case CHANGE_TYPE_ADD_OR_UPDATE:
-      change_string = "ADD_OR_UPDATE";
-      break;
-    case CHANGE_TYPE_DELETE:
-      change_string = "DELETE";
-      break;
-  }
-  const char* type_string = "NO_INFO";
-  switch (file_type()) {
-    case FileChange::FILE_TYPE_FILE:
-      type_string = "FILE";
-      break;
-    case FileChange::FILE_TYPE_DIRECTORY:
-      type_string = "DIRECTORY";
-      break;
-    case FILE_TYPE_NO_INFO:
-      // Keeps it as "no_info".
-      break;
-  }
-  return base::StringPrintf("%s:%s", change_string, type_string);
-}
-
-FileChange::ChangeList::ChangeList() = default;
-FileChange::ChangeList::ChangeList(const ChangeList& other) = default;
-FileChange::ChangeList::~ChangeList() = default;
-
-void FileChange::ChangeList::Update(const Change& new_change) {
-  if (list_.empty()) {
-    list_.push_back(new_change);
-    return;
-  }
-
-  Change& last = list_.back();
-  if (last.IsFile() != new_change.IsFile()) {
-    list_.push_back(new_change);
-    return;
-  }
-
-  if (last.team_drive_id() != new_change.team_drive_id()) {
-    list_.push_back(new_change);
-    return;
-  }
-
-  if (last.change() == new_change.change())
-    return;
-
-  // ADD + DELETE on directory -> revert
-  if (!last.IsFile() && last.IsAddOrUpdate() && new_change.IsDelete()) {
-    list_.pop_back();
-    return;
-  }
-
-  // DELETE + ADD/UPDATE -> ADD/UPDATE
-  // ADD/UPDATE + DELETE -> DELETE
-  last = new_change;
-}
-
-FileChange::ChangeList FileChange::ChangeList::PopAndGetNewList() const {
-  ChangeList changes;
-  changes.list_ = this->list_;
-  changes.list_.pop_front();
-  return changes;
-}
-
-std::string FileChange::ChangeList::DebugString() const {
-  std::ostringstream ss;
-  ss << "{ ";
-  for (size_t i = 0; i < list_.size(); ++i)
-    ss << list_[i].DebugString() << ", ";
-  ss << "}";
-  return ss.str();
-}
-
-FileChange::FileChange() = default;
-FileChange::FileChange(const FileChange& other) = default;
-FileChange::~FileChange() = default;
-
-void FileChange::Update(const base::FilePath file_path,
-                        const FileChange::Change& new_change) {
-  map_[file_path].Update(new_change);
-}
-
-void FileChange::Update(const base::FilePath file_path,
-                        const FileChange::ChangeList& new_change) {
-  for (ChangeList::List::const_iterator it = new_change.list().begin();
-       it != new_change.list().end();
-       it++) {
-    map_[file_path].Update(*it);
-  }
-}
-
-void FileChange::Update(const base::FilePath file_path,
-                        FileType file_type,
-                        FileChange::ChangeType change) {
-  Update(file_path, FileChange::Change(change, file_type));
-}
-
-void FileChange::Update(const base::FilePath file_path,
-                        const ResourceEntry& entry,
-                        FileChange::ChangeType change) {
-  FileType type = FILE_TYPE_NO_INFO;
-  std::string team_drive_id;
-  if (entry.has_file_info()) {
-    type =
-        entry.file_info().is_directory() ? FILE_TYPE_DIRECTORY : FILE_TYPE_FILE;
-    if (entry.file_info().is_team_drive_root()) {
-      team_drive_id = entry.resource_id();
-    }
-  }
-  Update(file_path, FileChange::Change(change, type, team_drive_id));
-}
-
-void FileChange::Apply(const FileChange& new_changed_files) {
-  for (auto it = new_changed_files.map().begin();
-       it != new_changed_files.map().end(); it++) {
-    Update(it->first, it->second);
-  }
-}
-
-size_t FileChange::CountDirectory(const base::FilePath& directory_path) const {
-  size_t count = 0;
-  for (auto it = map_.begin(); it != map_.end(); it++) {
-    if (it->first.DirName() == directory_path)
-      count++;
-  }
-  return count;
-}
-
-std::string FileChange::DebugString() const {
-  std::ostringstream ss;
-  ss << "{ ";
-  for (auto it = map_.begin(); it != map_.end(); it++) {
-    ss << it->first.value() << ": " << it->second.DebugString() << ", ";
-  }
-  ss << "}";
-  return ss.str();
-}
-
-}  // namespace drive
diff --git a/components/drive/file_change.h b/components/drive/file_change.h
deleted file mode 100644
index a7ec41b..0000000
--- a/components/drive/file_change.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_FILE_CHANGE_H_
-#define COMPONENTS_DRIVE_FILE_CHANGE_H_
-
-#include <stddef.h>
-
-#include <map>
-#include <string>
-
-#include "base/containers/circular_deque.h"
-#include "base/files/file_path.h"
-
-namespace drive {
-class ResourceEntry;
-
-class FileChange {
- public:
-  enum FileType {
-    FILE_TYPE_NO_INFO,
-    FILE_TYPE_FILE,
-    FILE_TYPE_DIRECTORY,
-  };
-
-  enum ChangeType {
-    CHANGE_TYPE_ADD_OR_UPDATE,
-    CHANGE_TYPE_DELETE,
-  };
-
-  class Change {
-   public:
-    Change(ChangeType change, FileType file_type);
-    Change(ChangeType change,
-           FileType file_type,
-           const std::string& team_drive_id);
-
-    bool IsAddOrUpdate() const { return change_ == CHANGE_TYPE_ADD_OR_UPDATE; }
-    bool IsDelete() const { return change_ == CHANGE_TYPE_DELETE; }
-
-    bool IsFile() const { return file_type_ == FILE_TYPE_FILE; }
-    bool IsDirectory() const { return file_type_ == FILE_TYPE_DIRECTORY; }
-    bool IsTypeUnknown() const { return !IsFile() && !IsDirectory(); }
-
-    ChangeType change() const { return change_; }
-    FileType file_type() const { return file_type_; }
-    const std::string& team_drive_id() const { return team_drive_id_; }
-
-    std::string DebugString() const;
-
-    bool operator==(const Change& that) const {
-      return change() == that.change() && file_type() == that.file_type() &&
-             team_drive_id() == that.team_drive_id();
-    }
-
-   private:
-    ChangeType change_;
-    FileType file_type_;
-    // The team drive id, will be empty if the change is not a team drive root.
-    std::string team_drive_id_;
-  };
-
-  class ChangeList {
-   public:
-    typedef base::circular_deque<Change> List;
-
-    ChangeList();
-    ChangeList(const ChangeList& other);
-    ~ChangeList();
-
-    // Updates the list with the |new_change|.
-    void Update(const Change& new_change);
-
-    size_t size() const { return list_.size(); }
-    bool empty() const { return list_.empty(); }
-    void clear() { list_.clear(); }
-    const List& list() const { return list_; }
-    const Change& front() const { return list_.front(); }
-    const Change& back() const { return list_.back(); }
-
-    ChangeList PopAndGetNewList() const;
-
-    std::string DebugString() const;
-
-   private:
-    List list_;
-  };
-
- public:
-  typedef std::map<base::FilePath, FileChange::ChangeList> Map;
-
-  FileChange();
-  FileChange(const FileChange& other);
-  ~FileChange();
-
-  void Update(const base::FilePath file_path,
-              const FileChange::Change& new_change);
-  void Update(const base::FilePath file_path,
-              const FileChange::ChangeList& list);
-  void Update(const base::FilePath file_path,
-              FileType type,
-              FileChange::ChangeType change);
-  void Update(const base::FilePath file_path,
-              const ResourceEntry& entry,
-              FileChange::ChangeType change);
-  void Apply(const FileChange& new_changed_files);
-
-  const Map& map() const { return map_; }
-
-  size_t size() const { return map_.size(); }
-  bool empty() const { return map_.empty(); }
-  void ClearForTest() { map_.clear(); }
-  size_t CountDirectory(const base::FilePath& directory_path) const;
-  size_t count(const base::FilePath& file_path) const {
-    return map_.count(file_path);
-  }
-
-  std::string DebugString() const;
-
- private:
-  Map map_;
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_FILE_CHANGE_H_
diff --git a/components/drive/file_change_unittest.cc b/components/drive/file_change_unittest.cc
deleted file mode 100644
index f934d1c..0000000
--- a/components/drive/file_change_unittest.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_change.h"
-
-#include "components/drive/drive.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-
-TEST(ChangeListTest, FileChange_Change) {
-  FileChange::ChangeType change_type = FileChange::CHANGE_TYPE_ADD_OR_UPDATE;
-  FileChange::FileType file_type = FileChange::FILE_TYPE_FILE;
-
-  FileChange::Change change1(change_type, file_type);
-  EXPECT_EQ(change_type, change1.change());
-  EXPECT_EQ(file_type, change1.file_type());
-
-  FileChange::Change change2(change_type, file_type);
-  EXPECT_EQ(change_type, change1.change());
-  EXPECT_EQ(file_type, change1.file_type());
-  EXPECT_EQ(change1, change2);
-
-  FileChange::Change change3(change_type, FileChange::FILE_TYPE_DIRECTORY);
-  EXPECT_EQ(change_type, change3.change());
-  EXPECT_EQ(FileChange::FILE_TYPE_DIRECTORY, change3.file_type());
-  EXPECT_TRUE(!(change1 == change3));
-}
-
-TEST(ChangeListTest, FileChangeChangeList) {
-  FileChange::ChangeList changes;
-  EXPECT_TRUE(changes.empty());
-  EXPECT_EQ(0u, changes.size());
-
-  changes.Update(FileChange::Change(FileChange::CHANGE_TYPE_ADD_OR_UPDATE,
-                                    FileChange::FILE_TYPE_FILE));
-  EXPECT_EQ(1u, changes.size());
-}
-
-TEST(ChangeListTest, FileChange) {
-  base::FilePath change_path1(FILE_PATH_LITERAL("test"));
-  base::FilePath change_path2(FILE_PATH_LITERAL("a/b/c/d"));
-  base::FilePath change_path3(FILE_PATH_LITERAL("a/b/c/e"));
-  base::FilePath change_dir(FILE_PATH_LITERAL("a/b/c"));
-
-  FileChange changed_files;
-  changed_files.Update(change_path1, FileChange::FILE_TYPE_FILE,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-  changed_files.Update(change_path2, FileChange::FILE_TYPE_FILE,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-  changed_files.Update(change_path2, FileChange::FILE_TYPE_FILE,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-  changed_files.Update(change_path3, FileChange::FILE_TYPE_FILE,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-
-  ASSERT_EQ(3u, changed_files.size());
-  ASSERT_EQ(2u, changed_files.CountDirectory(change_dir));
-}
-
-TEST(ChangeListTest, TeamDriveRootChange) {
-  base::FilePath team_drive1(FILE_PATH_LITERAL("a/b/c"));
-  base::FilePath team_drive2(FILE_PATH_LITERAL("a/b/d"));
-
-  ResourceEntry resource;
-  resource.mutable_file_info()->set_is_directory(true);
-  resource.mutable_file_info()->set_is_team_drive_root(true);
-
-  FileChange changed_files;
-  resource.set_resource_id("team_drive_id_1");
-  changed_files.Update(team_drive1, resource,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-
-  resource.set_resource_id("team_drive_id_2");
-  changed_files.Update(team_drive2, resource,
-                       FileChange::CHANGE_TYPE_ADD_OR_UPDATE);
-
-  ASSERT_EQ(2UL, changed_files.size());
-
-  const FileChange::Map& change_map = changed_files.map();
-  ASSERT_EQ("team_drive_id_1",
-            change_map.at(team_drive1).front().team_drive_id());
-  ASSERT_EQ("team_drive_id_2",
-            change_map.at(team_drive2).front().team_drive_id());
-}
-
-}  // namespace drive
diff --git a/components/drive/file_system_core_util.cc b/components/drive/file_system_core_util.cc
index 41854a5..ad48bfed 100644
--- a/components/drive/file_system_core_util.cc
+++ b/components/drive/file_system_core_util.cc
@@ -11,22 +11,13 @@
 #include <string>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/bind_helpers.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/i18n/icu_string_conversions.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_pref_names.h"
-#include "components/drive/job_list.h"
-#include "components/prefs/pref_service.h"
+#include "base/values.h"
 
 namespace drive {
 namespace util {
@@ -72,92 +63,11 @@
   return *grand_root_path;
 }
 
-const base::FilePath& GetDriveMyDriveRootPath() {
-  static base::NoDestructor<base::FilePath> drive_root_path(
-      GetDriveGrandRootPath().AppendASCII(kDriveMyDriveRootDirName));
-  return *drive_root_path;
-}
-
-const base::FilePath& GetDriveTeamDrivesRootPath() {
-  static base::NoDestructor<base::FilePath> team_drives_root_path(
-      GetDriveGrandRootPath().AppendASCII(kDriveTeamDrivesDirName));
-  return *team_drives_root_path;
-}
-
-bool IsTeamDrivesPath(const base::FilePath& file_path) {
-  return GetDriveTeamDrivesRootPath().IsParent(file_path);
-}
-
-std::string EscapeCacheFileName(const std::string& filename) {
-  // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape
-  std::string escaped;
-  for (size_t i = 0; i < filename.size(); ++i) {
-    char c = filename[i];
-    if (c == '%' || c == '.' || c == '/') {
-      base::StringAppendF(&escaped, "%%%02X", c);
-    } else {
-      escaped.push_back(c);
-    }
-  }
-  return escaped;
-}
-
-std::string UnescapeCacheFileName(const std::string& filename) {
-  std::string unescaped;
-  for (size_t i = 0; i < filename.size(); ++i) {
-    char c = filename[i];
-    if (c == '%' && i + 2 < filename.length()) {
-      c = (base::HexDigitToInt(filename[i + 1]) << 4) +
-          base::HexDigitToInt(filename[i + 2]);
-      i += 2;
-    }
-    unescaped.push_back(c);
-  }
-  return unescaped;
-}
-
 std::string ConvertChangestampToStartPageToken(int64_t changestamp) {
   DCHECK_LE(0, changestamp);
   return base::NumberToString(changestamp + 1);
 }
 
-// Convers a start page token to a numerical changestamp
-bool ConvertStartPageTokenToChangestamp(const std::string& start_page_token,
-                                        int64_t* changestamp) {
-  DCHECK(changestamp);
-  int64_t result;
-  if (base::StringToInt64(start_page_token, &result)) {
-    // The minimum valid start_page_token is 1.
-    if (result > 0) {
-      *changestamp = result - 1;
-      return true;
-    }
-  }
-  return false;
-}
-
-std::string NormalizeFileName(const std::string& input) {
-  DCHECK(base::IsStringUTF8(input));
-
-  std::string output;
-  if (!base::ConvertToUtf8AndNormalize(input, base::kCodepageUTF8, &output))
-    output = input;
-  base::ReplaceChars(output, "/", "_", &output);
-  if (!output.empty() && output.find_first_not_of('.', 0) == std::string::npos)
-    output = "_";
-  return output;
-}
-
-bool CreateGDocFile(const base::FilePath& file_path,
-                    const GURL& url,
-                    const std::string& resource_id) {
-  std::string content =
-      base::StringPrintf(R"({"url": "%s", "resource_id": "%s"})",
-                         url.spec().c_str(), resource_id.c_str());
-  return base::WriteFile(file_path, content.data(), content.size()) ==
-         static_cast<int>(content.size());
-}
-
 GURL ReadUrlFromGDocFile(const base::FilePath& file_path) {
   return GURL(ReadStringFromGDocFile(file_path, "url"));
 }
diff --git a/components/drive/file_system_core_util.h b/components/drive/file_system_core_util.h
index b83742f..a76671d 100644
--- a/components/drive/file_system_core_util.h
+++ b/components/drive/file_system_core_util.h
@@ -46,37 +46,9 @@
 // Returns the path of the top root of the pseudo tree.
 const base::FilePath& GetDriveGrandRootPath();
 
-// Returns the path of the directory representing "My Drive".
-const base::FilePath& GetDriveMyDriveRootPath();
-
-// Returns the path of the directory representing "Team Drives".
-const base::FilePath& GetDriveTeamDrivesRootPath();
-
-// Returns true if |file_path| is a child directory of the team drives root.
-bool IsTeamDrivesPath(const base::FilePath& file_path);
-
-// Escapes a file name in Drive cache.
-// Replaces percent ('%'), period ('.') and slash ('/') with %XX (hex)
-std::string EscapeCacheFileName(const std::string& filename);
-
-// Unescapes a file path in Drive cache.
-// This is the inverse of EscapeCacheFileName.
-std::string UnescapeCacheFileName(const std::string& filename);
-
 // Converts a numerical changestamp value to a start page token.
 std::string ConvertChangestampToStartPageToken(int64_t changestamp);
 
-// Convers a start page token to a numerical changestamp
-bool ConvertStartPageTokenToChangestamp(const std::string& stat_page_token,
-                                        int64_t* changestamp);
-
-// Converts the given string to a form suitable as a file name. Specifically,
-// - Normalizes in Unicode Normalization Form C.
-// - Replaces slashes '/' with '_'.
-// - Replaces the whole input with "_" if the all input characters are '.'.
-// |input| must be a valid UTF-8 encoded string.
-std::string NormalizeFileName(const std::string& input);
-
 // Helper to destroy objects which needs Destroy() to be called on destruction.
 struct DestroyHelper {
   template <typename T>
@@ -86,15 +58,6 @@
   }
 };
 
-// Creates a GDoc file with given values.
-//
-// GDoc files are used to represent hosted documents on local filesystems.
-// A GDoc file contains a JSON whose content is a URL to view the document and
-// a resource ID of the entry.
-bool CreateGDocFile(const base::FilePath& file_path,
-                    const GURL& url,
-                    const std::string& resource_id);
-
 // Reads URL from a GDoc file.
 GURL ReadUrlFromGDocFile(const base::FilePath& file_path);
 
diff --git a/components/drive/file_system_core_util_unittest.cc b/components/drive/file_system_core_util_unittest.cc
deleted file mode 100644
index 29e7d09..0000000
--- a/components/drive/file_system_core_util_unittest.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_system_core_util.h"
-
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/test/browser_task_environment.h"
-#include "google_apis/drive/test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace util {
-
-class FileSystemUtilTest : public testing::Test {
-  content::BrowserTaskEnvironment task_environment_;
-};
-
-TEST_F(FileSystemUtilTest, EscapeUnescapeCacheFileName) {
-  const std::string kUnescapedFileName(
-      R"(tmp:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?)");
-  const std::string kEscapedFileName(
-      R"(tmp:`~!@#$%25^&*()-_=+[{|]}\\;',<%2E>%2F?)");
-  EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName));
-  EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName));
-}
-
-TEST_F(FileSystemUtilTest, NormalizeFileName) {
-  EXPECT_EQ("", NormalizeFileName(""));
-  EXPECT_EQ("foo", NormalizeFileName("foo"));
-  // Slash
-  EXPECT_EQ("foo_zzz", NormalizeFileName("foo/zzz"));
-  EXPECT_EQ("___", NormalizeFileName("///"));
-  // Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi".
-  EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A"));
-  // Dot
-  EXPECT_EQ("_", NormalizeFileName("."));
-  EXPECT_EQ("_", NormalizeFileName(".."));
-  EXPECT_EQ("_", NormalizeFileName("..."));
-  EXPECT_EQ(".bashrc", NormalizeFileName(".bashrc"));
-  EXPECT_EQ("._", NormalizeFileName("./"));
-}
-
-TEST_F(FileSystemUtilTest, GDocFile) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  GURL url(
-      "https://docs.google.com/document/d/"
-      "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
-  std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
-
-  // Read and write gdoc.
-  base::FilePath file = temp_dir.GetPath().AppendASCII("test.gdoc");
-  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
-  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
-  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
-
-  // Read and write gsheet.
-  file = temp_dir.GetPath().AppendASCII("test.gsheet");
-  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
-  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
-  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
-
-  // Read and write gslides.
-  file = temp_dir.GetPath().AppendASCII("test.gslides");
-  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
-  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
-  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
-
-  // Read and write gdraw.
-  file = temp_dir.GetPath().AppendASCII("test.gdraw");
-  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
-  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
-  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
-
-  // Read and write gtable.
-  file = temp_dir.GetPath().AppendASCII("test.gtable");
-  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
-  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
-  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
-
-  // Non GDoc file.
-  file = temp_dir.GetPath().AppendASCII("test.txt");
-  std::string data = "Hello world!";
-  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
-  EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
-  EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
-}
-
-}  // namespace util
-}  // namespace drive
diff --git a/components/drive/file_system_metadata.cc b/components/drive/file_system_metadata.cc
deleted file mode 100644
index 67cb98f8..0000000
--- a/components/drive/file_system_metadata.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_system_metadata.h"
-
-namespace drive {
-
-FileSystemMetadata::FileSystemMetadata()
-    : refreshing(false), last_update_check_error(FILE_ERROR_OK) {}
-
-FileSystemMetadata::~FileSystemMetadata() = default;
-
-}  // namespace drive
diff --git a/components/drive/file_system_metadata.h b/components/drive/file_system_metadata.h
deleted file mode 100644
index 54156d2..0000000
--- a/components/drive/file_system_metadata.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_
-#define COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_
-
-#include <stdint.h>
-#include <string>
-
-#include "base/time/time.h"
-#include "components/drive/file_errors.h"
-
-namespace drive {
-
-// Metadata of FileSystem. Used by FileSystem::GetMetadata().
-struct FileSystemMetadata {
-  FileSystemMetadata();
-  ~FileSystemMetadata();
-
-  // The start_page_token that the file system holds (may be different
-  // from the one on the server)
-  std::string start_page_token = "";
-
-  // True if the resource metadata is now being fetched from the server.
-  bool refreshing;
-
-  // Time of the last update check.
-  base::Time last_update_check_time;
-
-  // Error code of the last update check.
-  FileError last_update_check_error;
-
-  // For team drives, this is the virtual path that the team drive is mounted
-  // at.
-  std::string path;
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_
diff --git a/components/drive/file_write_watcher.cc b/components/drive/file_write_watcher.cc
deleted file mode 100644
index 21ecee9..0000000
--- a/components/drive/file_write_watcher.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_write_watcher.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/files/file_path_watcher.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-#include "base/timer/timer.h"
-#include "google_apis/drive/task_util.h"
-
-namespace drive {
-namespace internal {
-
-namespace {
-const int64_t kWriteEventDelayInSeconds = 5;
-}  // namespace
-
-// base::FileWatcher needs to live in a thread that is allowed to do File IO
-// and has a TYPE_IO message loop: that is, FILE thread. This class bridges the
-// UI thread and FILE thread, and does all the main tasks in the FILE thread.
-class FileWriteWatcher::FileWriteWatcherImpl {
- public:
-  explicit FileWriteWatcherImpl(
-      base::SequencedTaskRunner* blocking_task_runner);
-
-  // Forwards the call to DestoryOnBlockingThread(). This method must be used
-  // to destruct the instance.
-  void Destroy();
-
-  // Forwards the call to StartWatchOnBlockingThread(). |on_start_callback| is
-  // called back on the caller (UI) thread when the watch has started.
-  // |on_write_callback| is called when a write has happened to the path.
-  void StartWatch(const base::FilePath& path,
-                  const StartWatchCallback& on_start_callback,
-                  const base::Closure& on_write_callback);
-
-  void set_delay(base::TimeDelta delay) { delay_ = delay; }
-
- private:
-  ~FileWriteWatcherImpl();
-
-  void DestroyOnBlockingThread();
-
-  void StartWatchOnBlockingThread(const base::FilePath& path,
-                                  const StartWatchCallback& on_start_callback,
-                                  const base::Closure& on_write_callback);
-
-  void OnWriteEvent(const base::FilePath& path, bool error);
-
-  void InvokeCallback(const base::FilePath& path);
-
-  struct PathWatchInfo {
-    std::vector<base::Closure> on_write_callbacks;
-    base::FilePathWatcher watcher;
-    base::OneShotTimer timer;
-
-    explicit PathWatchInfo(const base::Closure& on_write_callback)
-        : on_write_callbacks(1, on_write_callback) {}
-  };
-
-  base::TimeDelta delay_;
-  std::map<base::FilePath, std::unique_ptr<PathWatchInfo>> watchers_;
-  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-
-  base::ThreadChecker thread_checker_;
-
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<FileWriteWatcherImpl> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(FileWriteWatcherImpl);
-};
-
-FileWriteWatcher::FileWriteWatcherImpl::FileWriteWatcherImpl(
-    base::SequencedTaskRunner* blocking_task_runner)
-    : delay_(base::TimeDelta::FromSeconds(kWriteEventDelayInSeconds)),
-      blocking_task_runner_(blocking_task_runner) {}
-
-void FileWriteWatcher::FileWriteWatcherImpl::Destroy() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // Just forwarding the call to FILE thread.
-  blocking_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&FileWriteWatcherImpl::DestroyOnBlockingThread,
-                                base::Unretained(this)));
-}
-
-void FileWriteWatcher::FileWriteWatcherImpl::StartWatch(
-    const base::FilePath& path,
-    const StartWatchCallback& on_start_callback,
-    const base::Closure& on_write_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // Forwarding the call to FILE thread and relaying the |callback|.
-  blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FileWriteWatcherImpl::StartWatchOnBlockingThread,
-                     base::Unretained(this), path,
-                     google_apis::CreateRelayCallback(on_start_callback),
-                     google_apis::CreateRelayCallback(on_write_callback)));
-}
-
-FileWriteWatcher::FileWriteWatcherImpl::~FileWriteWatcherImpl() = default;
-
-void FileWriteWatcher::FileWriteWatcherImpl::DestroyOnBlockingThread() {
-  delete this;
-}
-
-void FileWriteWatcher::FileWriteWatcherImpl::StartWatchOnBlockingThread(
-    const base::FilePath& path,
-    const StartWatchCallback& on_start_callback,
-    const base::Closure& on_write_callback) {
-  auto it = watchers_.find(path);
-  if (it != watchers_.end()) {
-    // We are already watching the path.
-    on_start_callback.Run(true);
-    it->second->on_write_callbacks.push_back(on_write_callback);
-    return;
-  }
-
-  // Start watching |path|.
-  std::unique_ptr<PathWatchInfo> info =
-      std::make_unique<PathWatchInfo>(on_write_callback);
-  bool ok = info->watcher.Watch(
-      path,
-      false,  // recursive
-      base::Bind(&FileWriteWatcherImpl::OnWriteEvent,
-                 weak_ptr_factory_.GetWeakPtr()));
-  watchers_[path] = std::move(info);
-  on_start_callback.Run(ok);
-}
-
-void FileWriteWatcher::FileWriteWatcherImpl::OnWriteEvent(
-    const base::FilePath& path,
-    bool error) {
-  if (error)
-    return;
-
-  auto it = watchers_.find(path);
-  DCHECK(it != watchers_.end());
-
-  // Heuristics for detecting the end of successive write operations.
-  // Delay running on_write_event_callback by |delay_| time, and if OnWriteEvent
-  // is called again in the period, the timer is reset. In other words, we
-  // invoke callback when |delay_| has passed after the last OnWriteEvent().
-  it->second->timer.Start(FROM_HERE, delay_,
-                          base::BindOnce(&FileWriteWatcherImpl::InvokeCallback,
-                                         weak_ptr_factory_.GetWeakPtr(), path));
-}
-
-void FileWriteWatcher::FileWriteWatcherImpl::InvokeCallback(
-    const base::FilePath& path) {
-  auto it = watchers_.find(path);
-  DCHECK(it != watchers_.end());
-
-  std::vector<base::Closure> callbacks;
-  callbacks.swap(it->second->on_write_callbacks);
-  watchers_.erase(it);
-
-  for (const auto& callback : callbacks)
-    callback.Run();
-}
-
-FileWriteWatcher::FileWriteWatcher(
-    base::SequencedTaskRunner* blocking_task_runner)
-    : watcher_impl_(new FileWriteWatcherImpl(blocking_task_runner)) {}
-
-FileWriteWatcher::~FileWriteWatcher() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void FileWriteWatcher::StartWatch(const base::FilePath& file_path,
-                                  const StartWatchCallback& on_start_callback,
-                                  const base::Closure& on_write_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  watcher_impl_->StartWatch(file_path, on_start_callback, on_write_callback);
-}
-
-void FileWriteWatcher::DisableDelayForTesting() {
-  watcher_impl_->set_delay(base::TimeDelta());
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/file_write_watcher.h b/components/drive/file_write_watcher.h
deleted file mode 100644
index 1b3a5c7..0000000
--- a/components/drive/file_write_watcher.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_
-#define COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_
-
-#include <memory>
-
-#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "components/drive/file_system_core_util.h"
-
-namespace base {
-class FilePath;
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace drive {
-
-namespace internal {
-
-typedef base::Callback<void(bool)> StartWatchCallback;
-
-// The class watches modification to Drive files in the cache directory.
-// This is used for returning a local writable snapshot of Drive files from the
-// Save-As file dialog, so that the callers of the dialog can save to Drive
-// without any special handling about Drive.
-class FileWriteWatcher {
- public:
-  explicit FileWriteWatcher(base::SequencedTaskRunner* blocking_task_runner);
-  ~FileWriteWatcher();
-
-  // Starts watching the modification to |path|. When it successfully started
-  // watching, it runs |on_start_callback| by passing true as the argument.
-  // Or if it failed, the callback is run with false.
-  // Detected modification is notified by calling |on_write_callback|.
-  //
-  // Currently, the modification is watched in "one-shot" manner. That is, once
-  // a modification is notified, the watch is deactivated for freeing system
-  // resources. As a heuristic to capture the real end of write operations that
-  // might be done by several chunked writes, the notification is fired after
-  // 5 seconds has passed after the last write operation is detected.
-  //
-  // TODO(kinaba): investigate the possibility to continuously watch the whole
-  // cache directory. http://crbug.com/269424
-  void StartWatch(const base::FilePath& path,
-                  const StartWatchCallback& on_start_callback,
-                  const base::Closure& on_write_callback);
-
-  // For testing purpose, stops inserting delay between the write detection and
-  // notification to the |on_write_callback|.
-  void DisableDelayForTesting();
-
- private:
-  class FileWriteWatcherImpl;
-  std::unique_ptr<FileWriteWatcherImpl, util::DestroyHelper> watcher_impl_;
-
-  base::ThreadChecker thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileWriteWatcher);
-};
-
-}  // namespace internal
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_
diff --git a/components/drive/file_write_watcher_unittest.cc b/components/drive/file_write_watcher_unittest.cc
deleted file mode 100644
index 43f4619..0000000
--- a/components/drive/file_write_watcher_unittest.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/file_write_watcher.h"
-
-#include <set>
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/stl_util.h"
-#include "base/task/post_task.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-
-namespace {
-
-class TestObserver {
- public:
-  // After all the resource_ids in |expected_upload| are notified for the
-  // need of uploading, runs |quit_closure|. Also checks that each id is
-  // notified only once.
-  TestObserver(const std::set<std::string>& expected_upload,
-               const base::Closure& quit_closure)
-      : expected_upload_(expected_upload),
-        quit_closure_(quit_closure) {
-  }
-
-  void OnWrite(const std::string& id) {
-    EXPECT_EQ(1U, expected_upload_.count(id)) << id;
-    expected_upload_.erase(id);
-    if (expected_upload_.empty())
-      quit_closure_.Run();
-  }
-
- private:
-  std::set<std::string> expected_upload_;
-  base::Closure quit_closure_;
-};
-
-// Writes something on the file at |path|.
-void WriteSomethingAfterStartWatch(const base::FilePath& path,
-                                   bool watch_success) {
-  EXPECT_TRUE(watch_success) << path.value();
-
-  const char kDummy[] = "hello";
-  ASSERT_EQ(static_cast<int>(base::size(kDummy)),
-            base::WriteFile(path, kDummy, base::size(kDummy)));
-}
-
-class FileWriteWatcherTest : public testing::Test {
- protected:
-  // The test requires UI thread (FileWriteWatcher DCHECKs that its public
-  // interface is running on UI thread) and FILE thread (Linux version of
-  // base::FilePathWatcher needs to live on an IOAllowed thread with TYPE_IO,
-  // which is FILE thread in the production environment).
-  //
-  // By using the IO_MAINLOOP test thread bundle, the main thread is used
-  // both as UI and FILE thread, with TYPE_IO message loop.
-  FileWriteWatcherTest()
-      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
-
-  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
-
-  base::FilePath GetTempPath(const std::string& name) {
-    return temp_dir_.GetPath().Append(name);
-  }
-
- private:
-  content::BrowserTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-};
-
-}  // namespace
-
-TEST_F(FileWriteWatcherTest, WatchThreeFiles) {
-  std::set<std::string> expected;
-  expected.insert("1");
-  expected.insert("2");
-  expected.insert("3");
-
-  base::RunLoop loop;
-  TestObserver observer(expected, loop.QuitClosure());
-
-  // Set up the watcher.
-  scoped_refptr<base::SequencedTaskRunner> task_runner =
-      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()});
-  FileWriteWatcher watcher(task_runner.get());
-  watcher.DisableDelayForTesting();
-
-  // Start watching and running.
-  base::FilePath path1 = GetTempPath("foo.txt");
-  base::FilePath path2 = GetTempPath("bar.png");
-  base::FilePath path3 = GetTempPath("buz.doc");
-  base::FilePath path4 = GetTempPath("mya.mp3");
-  watcher.StartWatch(
-      path1,
-      base::Bind(&WriteSomethingAfterStartWatch, path1),
-      base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "1"));
-  watcher.StartWatch(
-      path2,
-      base::Bind(&WriteSomethingAfterStartWatch, path2),
-      base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "2"));
-  watcher.StartWatch(
-      path3,
-      base::Bind(&WriteSomethingAfterStartWatch, path3),
-      base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "3"));
-
-  // Unwatched write. It shouldn't be notified.
-  WriteSomethingAfterStartWatch(path4, true);
-
-  // The loop should quit if all the three paths are notified to be written.
-  loop.Run();
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/job_list.cc b/components/drive/job_list.cc
deleted file mode 100644
index 91aaf42..0000000
--- a/components/drive/job_list.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/job_list.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-
-namespace drive {
-
-std::string JobTypeToString(JobType type) {
-  switch (type){
-    case TYPE_GET_ABOUT_RESOURCE:
-      return "TYPE_GET_ABOUT_RESOURCE";
-    case TYPE_GET_APP_LIST:
-      return "TYPE_GET_APP_LIST";
-    case TYPE_GET_ALL_TEAM_DRIVE_LIST:
-      return "TYPE_GET_ALL_TEAM_DRIVE_LIST";
-    case TYPE_GET_ALL_RESOURCE_LIST:
-      return "TYPE_GET_ALL_RESOURCE_LIST";
-    case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY:
-      return "TYPE_GET_RESOURCE_LIST_IN_DIRECTORY";
-    case TYPE_SEARCH:
-      return "TYPE_SEARCH";
-    case TYPE_GET_CHANGE_LIST:
-      return "TYPE_GET_CHANGE_LIST";
-    case TYPE_GET_START_PAGE_TOKEN:
-      return "TYPE_GET_START_PAGE_TOKEN";
-    case TYPE_GET_REMAINING_CHANGE_LIST:
-      return "TYPE_GET_REMAINING_CHANGE_LIST";
-    case TYPE_GET_REMAINING_TEAM_DRIVE_LIST:
-      return "TYPE_GET_REMAINING_TEAM_DRIVE_LIST";
-    case TYPE_GET_REMAINING_FILE_LIST:
-      return "TYPE_GET_REMAINING_FILE_LIST";
-    case TYPE_GET_RESOURCE_ENTRY:
-      return "TYPE_GET_RESOURCE_ENTRY";
-    case TYPE_GET_SHARE_URL:
-      return "TYPE_GET_SHARE_URL";
-    case TYPE_TRASH_RESOURCE:
-      return "TYPE_TRASH_RESOURCE";
-    case TYPE_COPY_RESOURCE:
-      return "TYPE_COPY_RESOURCE";
-    case TYPE_UPDATE_RESOURCE:
-      return "TYPE_UPDATE_RESOURCE";
-    case TYPE_ADD_RESOURCE_TO_DIRECTORY:
-      return "TYPE_ADD_RESOURCE_TO_DIRECTORY";
-    case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY:
-      return "TYPE_REMOVE_RESOURCE_FROM_DIRECTORY";
-    case TYPE_ADD_NEW_DIRECTORY:
-      return "TYPE_ADD_NEW_DIRECTORY";
-    case TYPE_DOWNLOAD_FILE:
-      return "TYPE_DOWNLOAD_FILE";
-    case TYPE_UPLOAD_NEW_FILE:
-      return "TYPE_UPLOAD_NEW_FILE";
-    case TYPE_UPLOAD_EXISTING_FILE:
-      return "TYPE_UPLOAD_EXISTING_FILE";
-    case TYPE_ADD_PERMISSION:
-      return "TYPE_ADD_PERMISSION";
-  }
-  NOTREACHED();
-  return "(unknown job type)";
-}
-
-std::string JobStateToString(JobState state) {
-  switch (state) {
-    case STATE_NONE:
-      return "STATE_NONE";
-    case STATE_RUNNING:
-      return "STATE_RUNNING";
-    case STATE_RETRY:
-      return "STATE_RETRY";
-  }
-  NOTREACHED();
-  return "(unknown job state)";
-}
-
-JobInfo::JobInfo(JobType in_job_type)
-    : job_type(in_job_type),
-      job_id(-1),
-      state(STATE_NONE),
-      num_completed_bytes(0),
-      num_total_bytes(0) {
-}
-
-std::string JobInfo::ToString() const {
-  std::string output = base::StringPrintf(
-      "%s %s [%d]",
-      JobTypeToString(job_type).c_str(),
-      JobStateToString(state).c_str(),
-      job_id);
-  if (job_type == TYPE_DOWNLOAD_FILE ||
-      job_type == TYPE_UPLOAD_NEW_FILE ||
-      job_type == TYPE_UPLOAD_EXISTING_FILE) {
-    base::StringAppendF(&output, " bytes: %s/%s",
-                        base::NumberToString(num_completed_bytes).c_str(),
-                        base::NumberToString(num_total_bytes).c_str());
-  }
-  return output;
-}
-
-bool IsActiveFileTransferJobInfo(const JobInfo& job_info) {
-  // Using switch statement so that compiler can warn when new states or types
-  // are added.
-  switch (job_info.job_type) {
-    case TYPE_GET_ABOUT_RESOURCE:
-    case TYPE_GET_START_PAGE_TOKEN:
-    case TYPE_GET_APP_LIST:
-    case TYPE_GET_ALL_TEAM_DRIVE_LIST:
-    case TYPE_GET_ALL_RESOURCE_LIST:
-    case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY:
-    case TYPE_SEARCH:
-    case TYPE_GET_CHANGE_LIST:
-    case TYPE_GET_REMAINING_CHANGE_LIST:
-    case TYPE_GET_REMAINING_TEAM_DRIVE_LIST:
-    case TYPE_GET_REMAINING_FILE_LIST:
-    case TYPE_GET_RESOURCE_ENTRY:
-    case TYPE_GET_SHARE_URL:
-    case TYPE_TRASH_RESOURCE:
-    case TYPE_COPY_RESOURCE:
-    case TYPE_UPDATE_RESOURCE:
-    case TYPE_ADD_RESOURCE_TO_DIRECTORY:
-    case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY:
-    case TYPE_ADD_NEW_DIRECTORY:
-    case TYPE_ADD_PERMISSION:
-      return false;
-    case TYPE_DOWNLOAD_FILE:
-    case TYPE_UPLOAD_NEW_FILE:
-    case TYPE_UPLOAD_EXISTING_FILE:
-      break;
-  }
-
-  return true;
-}
-
-}  // namespace drive
diff --git a/components/drive/job_list.h b/components/drive/job_list.h
deleted file mode 100644
index ce178448..0000000
--- a/components/drive/job_list.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_JOB_LIST_H_
-#define COMPONENTS_DRIVE_JOB_LIST_H_
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "components/drive/file_errors.h"
-
-namespace drive {
-
-// Enum representing the type of job.
-enum JobType {
-  TYPE_GET_ABOUT_RESOURCE,
-  TYPE_GET_APP_LIST,
-  TYPE_GET_ALL_TEAM_DRIVE_LIST,
-  TYPE_GET_ALL_RESOURCE_LIST,
-  TYPE_GET_RESOURCE_LIST_IN_DIRECTORY,
-  TYPE_SEARCH,
-  TYPE_GET_CHANGE_LIST,
-  TYPE_GET_START_PAGE_TOKEN,
-  TYPE_GET_REMAINING_CHANGE_LIST,
-  TYPE_GET_REMAINING_TEAM_DRIVE_LIST,
-  TYPE_GET_REMAINING_FILE_LIST,
-  TYPE_GET_RESOURCE_ENTRY,
-  TYPE_GET_SHARE_URL,
-  TYPE_TRASH_RESOURCE,
-  TYPE_COPY_RESOURCE,
-  TYPE_UPDATE_RESOURCE,
-  TYPE_ADD_RESOURCE_TO_DIRECTORY,
-  TYPE_REMOVE_RESOURCE_FROM_DIRECTORY,
-  TYPE_ADD_NEW_DIRECTORY,
-  TYPE_DOWNLOAD_FILE,
-  TYPE_UPLOAD_NEW_FILE,
-  TYPE_UPLOAD_EXISTING_FILE,
-  TYPE_ADD_PERMISSION,
-};
-
-// Returns the string representation of |type|.
-std::string JobTypeToString(JobType type);
-
-// Current state of the job.
-enum JobState {
-  // The job is queued, but not yet executed.
-  STATE_NONE,
-
-  // The job is in the process of being handled.
-  STATE_RUNNING,
-
-  // The job failed, but has been re-added to the queue.
-  STATE_RETRY,
-};
-
-// Returns the string representation of |state|.
-std::string JobStateToString(JobState state);
-
-// Unique ID assigned to each job.
-typedef int32_t JobID;
-
-// Information about a specific job that is visible to other systems.
-struct JobInfo {
-  explicit JobInfo(JobType job_type);
-
-  // Type of the job.
-  JobType job_type;
-
-  // Id of the job, which can be used to query or modify it.
-  JobID job_id;
-
-  // Current state of the operation.
-  JobState state;
-
-  // The fields below are available only for jobs with job_type:
-  // TYPE_DOWNLOAD_FILE, TYPE_UPLOAD_NEW_FILE, or TYPE_UPLOAD_EXISTING_FILE.
-
-  // Number of bytes completed.
-  int64_t num_completed_bytes;
-
-  // Total bytes of this operation.
-  int64_t num_total_bytes;
-
-  // Drive path of the file that this job acts on.
-  base::FilePath file_path;
-
-  // Time when the job is started (i.e. the request is sent to the server).
-  base::Time start_time;
-
-  // Returns the string representation of the job info.
-  std::string ToString() const;
-};
-
-// Checks if |job_info| represents a job for currently active file transfer.
-bool IsActiveFileTransferJobInfo(const JobInfo& job_info);
-
-// The interface for observing JobListInterface.
-// All events are notified in the UI thread.
-class JobListObserver {
- public:
-  // Called when a new job id added.
-  virtual void OnJobAdded(const JobInfo& job_info) {}
-
-  // Called when a job id finished.
-  // |error| is FILE_ERROR_OK when the job successfully finished, and a value
-  // telling the reason of failure when the jobs is failed.
-  virtual void OnJobDone(const JobInfo& job_info,
-                         FileError error) {}
-
-  // Called when a job status is updated.
-  virtual void OnJobUpdated(const JobInfo& job_info) {}
-
- protected:
-  virtual ~JobListObserver() = default;
-};
-
-// The interface to expose the list of issued Drive jobs.
-class JobListInterface {
- public:
-  virtual ~JobListInterface() = default;
-
-  // Returns the list of jobs currently managed by the scheduler.
-  virtual std::vector<JobInfo> GetJobInfoList() = 0;
-
-  // Adds an observer.
-  virtual void AddObserver(JobListObserver* observer) = 0;
-
-  // Removes an observer.
-  virtual void RemoveObserver(JobListObserver* observer) = 0;
-
-  // Cancels the job.
-  virtual void CancelJob(JobID job_id) = 0;
-
-  // Cancels all the jobs.
-  virtual void CancelAllJobs() = 0;
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_JOB_LIST_H_
diff --git a/components/drive/job_queue.cc b/components/drive/job_queue.cc
deleted file mode 100644
index 5a5aa8b..0000000
--- a/components/drive/job_queue.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/job_queue.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-
-namespace drive {
-
-JobQueue::Item::Item() : batchable(false), size(0) {
-}
-
-JobQueue::Item::Item(JobID id, bool batchable, uint64_t size)
-    : id(id), batchable(batchable), size(size) {}
-
-JobQueue::Item::~Item() = default;
-
-JobQueue::JobQueue(size_t num_max_concurrent_jobs,
-                   size_t num_priority_levels,
-                   size_t num_max_batch_jobs,
-                   size_t max_batch_size)
-    : num_max_concurrent_jobs_(num_max_concurrent_jobs),
-      queue_(num_priority_levels),
-      num_max_batch_jobs_(num_max_batch_jobs),
-      max_batch_size_(max_batch_size) {
-}
-
-JobQueue::~JobQueue() = default;
-
-void JobQueue::PopForRun(int accepted_priority, std::vector<JobID>* jobs) {
-  DCHECK_LT(accepted_priority, static_cast<int>(queue_.size()));
-  jobs->clear();
-
-  // Too many jobs are running already.
-  if (running_.size() >= num_max_concurrent_jobs_)
-    return;
-
-  // Looks up the queue in the order of priority upto |accepted_priority|.
-  uint64_t total_size = 0;
-  bool batchable = true;
-  for (int priority = 0; priority <= accepted_priority; ++priority) {
-    while (!queue_[priority].empty()) {
-      const auto& item = queue_[priority].front();
-      total_size += item.size;
-      batchable = batchable && item.batchable &&
-                  jobs->size() < num_max_batch_jobs_ &&
-                  total_size <= max_batch_size_;
-      if (!(jobs->empty() || batchable))
-        return;
-      jobs->push_back(item.id);
-      running_.insert(item.id);
-      queue_[priority].pop_front();
-    }
-  }
-}
-
-void JobQueue::GetQueuedJobs(int priority, std::vector<JobID>* jobs) const {
-  DCHECK_LT(priority, static_cast<int>(queue_.size()));
-  jobs->clear();
-  for (const Item& item : queue_[priority]) {
-    jobs->push_back(item.id);
-  }
-}
-
-void JobQueue::Push(JobID id, int priority, bool batchable, uint64_t size) {
-  DCHECK_LT(priority, static_cast<int>(queue_.size()));
-  queue_[priority].push_back(Item(id, batchable, size));
-}
-
-void JobQueue::MarkFinished(JobID id) {
-  size_t num_erased = running_.erase(id);
-  DCHECK_EQ(1U, num_erased);
-}
-
-std::string JobQueue::ToString() const {
-  size_t pending = 0;
-  for (size_t i = 0; i < queue_.size(); ++i)
-    pending += queue_[i].size();
-  return base::StringPrintf("pending: %d, running: %d",
-                            static_cast<int>(pending),
-                            static_cast<int>(running_.size()));
-}
-
-size_t JobQueue::GetNumberOfJobs() const {
-  size_t count = running_.size();
-  for (size_t i = 0; i < queue_.size(); ++i)
-    count += queue_[i].size();
-  return count;
-}
-
-void JobQueue::Remove(JobID id) {
-  for (size_t i = 0; i < queue_.size(); ++i) {
-    for (auto it = queue_[i].begin(); it != queue_[i].end(); ++it) {
-      if (it->id == id) {
-        queue_[i].erase(it);
-        break;
-      }
-    }
-  }
-}
-
-}  // namespace drive
diff --git a/components/drive/job_queue.h b/components/drive/job_queue.h
deleted file mode 100644
index 341527b..0000000
--- a/components/drive/job_queue.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_JOB_QUEUE_H_
-#define COMPONENTS_DRIVE_JOB_QUEUE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <set>
-#include <vector>
-
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "components/drive/job_list.h"
-
-namespace drive {
-
-// Priority queue for managing jobs in JobScheduler.
-class JobQueue {
- public:
-  // Creates a queue that allows |num_max_concurrent_jobs| concurrent job
-  // execution and has |num_priority_levels| levels of priority.
-  JobQueue(size_t num_max_concurrent_jobs,
-           size_t num_priority_levels,
-           size_t num_max_batch_jobs,
-           size_t max_batch_size);
-  ~JobQueue();
-
-  // Pushes a job |id| of |priority|. The job with the smallest priority value
-  // is popped first (lower values are higher priority). In the same priority,
-  // the queue is "first-in first-out". If multiple jobs with |batchable| = true
-  // are pushed continuously, there will be popped at the same time unless the
-  // number of jobs exceeds |num_max_batch_jobs_| or the sum of |job_size|
-  // exceeds or |max_batch_size_|.
-  void Push(JobID id, int priority, bool batchable, uint64_t job_size);
-
-  // Pops the first job which meets |accepted_priority| (i.e. the first job in
-  // the queue with equal or higher priority (lower value)), and the limit of
-  // concurrent job count is satisfied.
-  //
-  // For instance, if |accepted_priority| is 1, the first job with priority 0
-  // (higher priority) in the queue is picked even if a job with priority 1 was
-  // pushed earlier. If there is no job with priority 0, the first job with
-  // priority 1 in the queue is picked.
-  //
-  // If the first found job and following jobs are batchable, these jobs are
-  // popped out at the same time unless the total size of jobs exceeds
-  // |max_batch_size_|.
-  void PopForRun(int accepted_priority, std::vector<JobID>* jobs);
-
-  // Gets queued jobs with the given priority.
-  void GetQueuedJobs(int priority, std::vector<JobID>* jobs) const;
-
-  // Marks a running job |id| as finished running. This decreases the count
-  // of running parallel jobs and makes room for other jobs to be popped.
-  void MarkFinished(JobID id);
-
-  // Generates a string representing the internal state for logging.
-  std::string ToString() const;
-
-  // Gets the total number of jobs in the queue.
-  size_t GetNumberOfJobs() const;
-
-  // Removes the job from the queue.
-  void Remove(JobID id);
-
- private:
-  // JobID and additional properties that are needed to determine which tasks it
-  // runs next.
-  struct Item {
-    Item();
-    Item(JobID id, bool batchable, uint64_t size);
-    ~Item();
-    JobID id;
-    bool batchable;
-    uint64_t size;
-  };
-
-  const size_t num_max_concurrent_jobs_;
-  std::vector<base::circular_deque<Item>> queue_;
-  const size_t num_max_batch_jobs_;
-  const size_t max_batch_size_;
-  std::set<JobID> running_;
-
-  DISALLOW_COPY_AND_ASSIGN(JobQueue);
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_JOB_QUEUE_H_
diff --git a/components/drive/job_queue_unittest.cc b/components/drive/job_queue_unittest.cc
deleted file mode 100644
index 1390b1f..0000000
--- a/components/drive/job_queue_unittest.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/job_queue.h"
-
-#include <stddef.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-
-TEST(JobQueueTest, BasicJobQueueOperations) {
-  const size_t kNumMaxConcurrentJobs = 3;
-  const size_t kNumPriorityLevels = 2;
-  const size_t kNumMaxBatchJob = 0;
-  const size_t kMaxBatchSize = 0;
-  enum {HIGH_PRIORITY, LOW_PRIORITY};
-
-  // Create a queue. Number of jobs are initially zero.
-  JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
-                 kMaxBatchSize);
-  EXPECT_EQ(0U, queue.GetNumberOfJobs());
-
-  // Push 4 jobs.
-  queue.Push(101, LOW_PRIORITY, false, 0);
-  queue.Push(102, HIGH_PRIORITY, false, 0);
-  queue.Push(103, LOW_PRIORITY, false, 0);
-  queue.Push(104, HIGH_PRIORITY, false, 0);
-
-  // High priority jobs should be popped first.
-  std::vector<JobID> ids;
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(102, ids[0]);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(104, ids[0]);
-
-  // Then low priority jobs follow.
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(101, ids[0]);
-
-  // The queue allows at most 3 parallel runs. So returns false here.
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(0u, ids.size());
-
-  // No jobs finished yet, so the job count is four.
-  EXPECT_EQ(4U, queue.GetNumberOfJobs());
-
-  // Mark one job as finished.
-  queue.MarkFinished(104);
-  EXPECT_EQ(3U, queue.GetNumberOfJobs());
-
-  // Then the next jobs can be popped.
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(103, ids[0]);
-
-  // Push 1 more job.
-  queue.Push(105, LOW_PRIORITY, false, 0);
-
-  // Finish all 3 running jobs.
-  queue.MarkFinished(101);
-  queue.MarkFinished(102);
-  queue.MarkFinished(103);
-  EXPECT_EQ(1U, queue.GetNumberOfJobs());
-
-  // The remaining jobs is of low priority, so under HIGH_PRIORITY context, it
-  // cannot be popped for running.
-  queue.PopForRun(HIGH_PRIORITY, &ids);
-  ASSERT_EQ(0u, ids.size());
-
-  // Under the low priority context, it is fine.
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(105, ids[0]);
-}
-
-TEST(JobQueueTest, JobQueueRemove) {
-  const size_t kNumMaxConcurrentJobs = 3;
-  const size_t kNumPriorityLevels = 2;
-  const size_t kNumMaxBatchJob = 0;
-  const size_t kMaxBatchSize = 0;
-  enum {HIGH_PRIORITY, LOW_PRIORITY};
-
-  // Create a queue. Number of jobs are initially zero.
-  JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
-                 kMaxBatchSize);
-  EXPECT_EQ(0U, queue.GetNumberOfJobs());
-
-  // Push 4 jobs.
-  queue.Push(101, LOW_PRIORITY, false, 0);
-  queue.Push(102, HIGH_PRIORITY, false, 0);
-  queue.Push(103, LOW_PRIORITY, false, 0);
-  queue.Push(104, HIGH_PRIORITY, false, 0);
-  EXPECT_EQ(4U, queue.GetNumberOfJobs());
-
-  // Remove 2.
-  queue.Remove(101);
-  queue.Remove(104);
-  EXPECT_EQ(2U, queue.GetNumberOfJobs());
-
-  // Pop the 2 jobs.
-  std::vector<JobID> ids;
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(102, ids[0]);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(103, ids[0]);
-  queue.MarkFinished(102);
-  queue.MarkFinished(103);
-
-  // 0 job left.
-  EXPECT_EQ(0U, queue.GetNumberOfJobs());
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(0u, ids.size());
-}
-
-TEST(JobQueueTest, BatchRequest) {
-  const size_t kNumMaxConcurrentJobs = 1;
-  const size_t kNumPriorityLevels = 2;
-  const size_t kNumMaxBatchJob = 100;
-  const size_t kMaxBatchSize = 5;
-  enum { HIGH_PRIORITY, LOW_PRIORITY };
-
-  // Create a queue. Number of jobs are initially zero.
-  JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
-                 kMaxBatchSize);
-  EXPECT_EQ(0U, queue.GetNumberOfJobs());
-
-  // Push 6 jobs.
-  queue.Push(101, LOW_PRIORITY, true, 1);
-  queue.Push(102, HIGH_PRIORITY, true, 1);
-  queue.Push(103, LOW_PRIORITY, false, 1);
-  queue.Push(104, HIGH_PRIORITY, true, 1);
-  queue.Push(105, LOW_PRIORITY, true, 1);
-  queue.Push(106, HIGH_PRIORITY, true, 10);
-
-  EXPECT_EQ(6U, queue.GetNumberOfJobs());
-
-  // Pop the 6 jobs.
-  std::vector<JobID> ids;
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(2u, ids.size());
-  EXPECT_EQ(102, ids[0]);
-  EXPECT_EQ(104, ids[1]);
-  queue.MarkFinished(102);
-  queue.MarkFinished(104);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(106, ids[0]);
-  queue.MarkFinished(106);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(101, ids[0]);
-  queue.MarkFinished(101);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(103, ids[0]);
-  queue.MarkFinished(103);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  ASSERT_EQ(1u, ids.size());
-  EXPECT_EQ(105, ids[0]);
-  queue.MarkFinished(105);
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  EXPECT_EQ(0u, ids.size());
-}
-
-TEST(JobQueueTest, BatchRequstNumMaxJobs) {
-  const size_t kNumMaxConcurrentJobs = 1;
-  const size_t kNumPriorityLevels = 2;
-  const size_t kNumMaxBatchJob = 5;
-  const size_t kMaxBatchSize = 100;
-  enum { HIGH_PRIORITY, LOW_PRIORITY };
-
-  // Create a queue. Number of jobs are initially zero.
-  JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
-                 kMaxBatchSize);
-  EXPECT_EQ(0U, queue.GetNumberOfJobs());
-
-  // Push 6 jobs.
-  queue.Push(101, LOW_PRIORITY, true, 1);
-  queue.Push(102, LOW_PRIORITY, true, 1);
-  queue.Push(103, LOW_PRIORITY, true, 1);
-  queue.Push(104, LOW_PRIORITY, true, 1);
-  queue.Push(105, LOW_PRIORITY, true, 1);
-  queue.Push(106, LOW_PRIORITY, true, 1);
-
-  EXPECT_EQ(6U, queue.GetNumberOfJobs());
-
-  // Pop the 5 of 6 jobs.
-  std::vector<JobID> ids;
-  queue.PopForRun(LOW_PRIORITY, &ids);
-  EXPECT_EQ(5u, ids.size());
-}
-
-}  // namespace drive
diff --git a/components/drive/job_scheduler.cc b/components/drive/job_scheduler.cc
deleted file mode 100644
index e0cb534..0000000
--- a/components/drive/job_scheduler.cc
+++ /dev/null
@@ -1,1202 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/job_scheduler.h"
-
-#include <stddef.h>
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/drive_pref_names.h"
-#include "components/drive/event_logger.h"
-#include "components/prefs/pref_service.h"
-#include "google_apis/drive/drive_api_parser.h"
-
-namespace drive {
-
-namespace {
-
-// All jobs are retried at maximum of kMaxRetryCount when they fail due to
-// throttling or server error.  The delay before retrying a job is shared among
-// jobs. It doubles in length on each failure, upto 2^kMaxThrottleCount seconds.
-//
-// According to the API documentation, kMaxRetryCount should be the same as
-// kMaxThrottleCount (https://developers.google.com/drive/handle-errors).
-// But currently multiplied by 2 to ensure upload related jobs retried for a
-// sufficient number of times. crbug.com/269918
-const int kMaxThrottleCount = 4;
-const int kMaxRetryCount = 2 * kMaxThrottleCount;
-const size_t kMaxBatchCount = 20;
-const size_t kMaxBatchSize = 1024 * 1024 * 10;
-
-// GetDefaultValue returns a value constructed by the default constructor.
-template<typename T> struct DefaultValueCreator {
-  static T GetDefaultValue() { return T(); }
-};
-template<typename T> struct DefaultValueCreator<const T&> {
-  static T GetDefaultValue() { return T(); }
-};
-
-// Helper of CreateErrorRunCallback implementation.
-// Provides:
-// - ResultType; the type of the Callback which should be returned by
-//     CreateErrorRunCallback.
-// - Run(): a static function which takes the original |callback| and |error|,
-//     and runs the |callback|.Run() with the error code and default values
-//     for remaining arguments.
-template<typename CallbackType> struct CreateErrorRunCallbackHelper;
-
-// CreateErrorRunCallback with two arguments.
-template<typename P1>
-struct CreateErrorRunCallbackHelper<void(google_apis::DriveApiErrorCode, P1)> {
-  static void Run(
-      const base::Callback<void(google_apis::DriveApiErrorCode, P1)>& callback,
-      google_apis::DriveApiErrorCode error) {
-    callback.Run(error, DefaultValueCreator<P1>::GetDefaultValue());
-  }
-};
-
-// Returns a callback with the tail parameter bound to its default value.
-// In other words, returned_callback.Run(error) runs callback.Run(error, T()).
-template<typename CallbackType>
-base::Callback<void(google_apis::DriveApiErrorCode)>
-CreateErrorRunCallback(const base::Callback<CallbackType>& callback) {
-  return base::Bind(&CreateErrorRunCallbackHelper<CallbackType>::Run, callback);
-}
-
-// Parameter struct for RunUploadNewFile.
-struct UploadNewFileParams {
-  std::string parent_resource_id;
-  base::FilePath local_file_path;
-  std::string title;
-  std::string content_type;
-  UploadNewFileOptions options;
-  UploadCompletionCallback callback;
-  google_apis::ProgressCallback progress_callback;
-};
-
-// Helper function to work around the arity limitation of base::Bind.
-google_apis::CancelCallback RunUploadNewFile(
-    DriveUploaderInterface* uploader,
-    const UploadNewFileParams& params) {
-  return uploader->UploadNewFile(params.parent_resource_id,
-                                 params.local_file_path,
-                                 params.title,
-                                 params.content_type,
-                                 params.options,
-                                 params.callback,
-                                 params.progress_callback);
-}
-
-// Parameter struct for RunUploadExistingFile.
-struct UploadExistingFileParams {
-  std::string resource_id;
-  base::FilePath local_file_path;
-  std::string content_type;
-  UploadExistingFileOptions options;
-  std::string etag;
-  UploadCompletionCallback callback;
-  google_apis::ProgressCallback progress_callback;
-};
-
-// Helper function to work around the arity limitation of base::Bind.
-google_apis::CancelCallback RunUploadExistingFile(
-    DriveUploaderInterface* uploader,
-    const UploadExistingFileParams& params) {
-  return uploader->UploadExistingFile(params.resource_id,
-                                      params.local_file_path,
-                                      params.content_type,
-                                      params.options,
-                                      params.callback,
-                                      params.progress_callback);
-}
-
-// Parameter struct for RunResumeUploadFile.
-struct ResumeUploadFileParams {
-  GURL upload_location;
-  base::FilePath local_file_path;
-  std::string content_type;
-  UploadCompletionCallback callback;
-  google_apis::ProgressCallback progress_callback;
-};
-
-// Helper function to adjust the return type.
-google_apis::CancelCallback RunResumeUploadFile(
-    DriveUploaderInterface* uploader,
-    const ResumeUploadFileParams& params) {
-  return uploader->ResumeUploadFile(params.upload_location,
-                                    params.local_file_path,
-                                    params.content_type,
-                                    params.callback,
-                                    params.progress_callback);
-}
-
-}  // namespace
-
-// Metadata jobs are cheap, so we run them concurrently. File jobs run serially.
-const int JobScheduler::kMaxJobCount[] = {
-    20,  // METADATA_QUEUE
-    1,   // FILE_QUEUE
-};
-
-JobScheduler::JobEntry::JobEntry(JobType type)
-    : job_info(type),
-      context(ClientContext(USER_INITIATED)),
-      retry_count(0) {
-}
-
-JobScheduler::JobEntry::~JobEntry() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-struct JobScheduler::ResumeUploadParams {
-  base::FilePath drive_file_path;
-  base::FilePath local_file_path;
-  std::string content_type;
-};
-
-JobScheduler::JobScheduler(
-    PrefService* pref_service,
-    EventLogger* logger,
-    DriveServiceInterface* drive_service,
-    network::NetworkConnectionTracker* network_connection_tracker,
-    base::SequencedTaskRunner* blocking_task_runner,
-    mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider)
-    : throttle_count_(0),
-      wait_until_(base::Time::Now()),
-      disable_throttling_(false),
-      logger_(logger),
-      drive_service_(drive_service),
-      network_connection_tracker_(network_connection_tracker),
-      blocking_task_runner_(blocking_task_runner),
-      uploader_(new DriveUploader(drive_service,
-                                  blocking_task_runner,
-                                  std::move(wake_lock_provider))),
-      pref_service_(pref_service) {
-  for (int i = 0; i < NUM_QUEUES; ++i)
-    queue_[i] = std::make_unique<JobQueue>(kMaxJobCount[i], NUM_CONTEXT_TYPES,
-                                           kMaxBatchCount, kMaxBatchSize);
-
-  network_connection_tracker_->AddNetworkConnectionObserver(this);
-}
-
-JobScheduler::~JobScheduler() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  size_t num_queued_jobs = 0;
-  for (int i = 0; i < NUM_QUEUES; ++i)
-    num_queued_jobs += queue_[i]->GetNumberOfJobs();
-  DCHECK_EQ(num_queued_jobs, job_map_.size());
-
-  network_connection_tracker_->RemoveNetworkConnectionObserver(this);
-}
-
-std::vector<JobInfo> JobScheduler::GetJobInfoList() {
-  std::vector<JobInfo> job_info_list;
-  for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance())
-    job_info_list.push_back(iter.GetCurrentValue()->job_info);
-  return job_info_list;
-}
-
-void JobScheduler::AddObserver(JobListObserver* observer) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  observer_list_.AddObserver(observer);
-}
-
-void JobScheduler::RemoveObserver(JobListObserver* observer) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  observer_list_.RemoveObserver(observer);
-}
-
-void JobScheduler::CancelJob(JobID job_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* job = job_map_.Lookup(job_id);
-  if (job) {
-    if (job->job_info.state == STATE_RUNNING) {
-      // If the job is running an HTTP request, cancel it via |cancel_callback|
-      // returned from the request, and wait for termination in the normal
-      // callback handler, OnJobDone.
-      if (!job->cancel_callback.is_null())
-        job->cancel_callback.Run();
-    } else {
-      AbortNotRunningJob(job, google_apis::DRIVE_CANCELLED);
-    }
-  }
-}
-
-void JobScheduler::CancelAllJobs() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // CancelJob may remove the entry from |job_map_|. That's OK. IDMap supports
-  // removable during iteration.
-  for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance())
-    CancelJob(iter.GetCurrentKey());
-}
-
-void JobScheduler::GetAboutResource(
-    const google_apis::AboutResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_ABOUT_RESOURCE);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetAboutResource,
-      base::Unretained(drive_service_),
-      base::Bind(&JobScheduler::OnGetAboutResourceJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetStartPageToken(
-    const std::string& team_drive_id,
-    const google_apis::StartPageTokenCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_START_PAGE_TOKEN);
-  new_job->task = base::BindRepeating(
-      &DriveServiceInterface::GetStartPageToken,
-      base::Unretained(drive_service_), team_drive_id,
-      base::BindRepeating(&JobScheduler::OnGetStartPageTokenDone,
-                          weak_ptr_factory_.GetWeakPtr(),
-                          new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetAllTeamDriveList(
-    const google_apis::TeamDriveListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-  JobEntry* new_job = CreateNewJob(TYPE_GET_ALL_TEAM_DRIVE_LIST);
-  new_job->task =
-      base::Bind(&DriveServiceInterface::GetAllTeamDriveList,
-                 base::Unretained(drive_service_),
-                 base::Bind(&JobScheduler::OnGetTeamDriveListJobDone,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetAllFileList(
-    const std::string& team_drive_id,
-    const google_apis::FileListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_ALL_RESOURCE_LIST);
-  new_job->task = base::Bind(&DriveServiceInterface::GetAllFileList,
-                             base::Unretained(drive_service_), team_drive_id,
-                             base::Bind(&JobScheduler::OnGetFileListJobDone,
-                                        weak_ptr_factory_.GetWeakPtr(),
-                                        new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetFileListInDirectory(
-    const std::string& directory_resource_id,
-    const google_apis::FileListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(
-      TYPE_GET_RESOURCE_LIST_IN_DIRECTORY);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetFileListInDirectory,
-      base::Unretained(drive_service_),
-      directory_resource_id,
-      base::Bind(&JobScheduler::OnGetFileListJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::Search(const std::string& search_query,
-                          const google_apis::FileListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_SEARCH);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::Search,
-      base::Unretained(drive_service_),
-      search_query,
-      base::Bind(&JobScheduler::OnGetFileListJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetChangeList(
-    int64_t start_changestamp,
-    const google_apis::ChangeListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_CHANGE_LIST);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetChangeList,
-      base::Unretained(drive_service_),
-      start_changestamp,
-      base::Bind(&JobScheduler::OnGetChangeListJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetChangeList(
-    const std::string& team_drive_id,
-    const std::string& start_page_token,
-    const google_apis::ChangeListCallback& callback) {
-  JobEntry* new_job = CreateNewJob(TYPE_GET_CHANGE_LIST);
-  new_job->task = base::BindRepeating(
-      &DriveServiceInterface::GetChangeListByToken,
-      base::Unretained(drive_service_), team_drive_id, start_page_token,
-      base::BindRepeating(&JobScheduler::OnGetChangeListJobDone,
-                          weak_ptr_factory_.GetWeakPtr(),
-                          new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetRemainingChangeList(
-    const GURL& next_link,
-    const google_apis::ChangeListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_CHANGE_LIST);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetRemainingChangeList,
-      base::Unretained(drive_service_),
-      next_link,
-      base::Bind(&JobScheduler::OnGetChangeListJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetRemainingTeamDriveList(
-    const std::string& page_token,
-    const google_apis::TeamDriveListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-  JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_TEAM_DRIVE_LIST);
-  new_job->task =
-      base::Bind(&DriveServiceInterface::GetRemainingTeamDriveList,
-                 base::Unretained(drive_service_), page_token,
-                 base::Bind(&JobScheduler::OnGetTeamDriveListJobDone,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetRemainingFileList(
-    const GURL& next_link,
-    const google_apis::FileListCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_FILE_LIST);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetRemainingFileList,
-      base::Unretained(drive_service_),
-      next_link,
-      base::Bind(&JobScheduler::OnGetFileListJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::GetFileResource(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_GET_RESOURCE_ENTRY);
-  new_job->context = context;
-  new_job->task = base::Bind(
-      &DriveServiceInterface::GetFileResource,
-      base::Unretained(drive_service_),
-      resource_id,
-      base::Bind(&JobScheduler::OnGetFileResourceJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::TrashResource(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const google_apis::EntryActionCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_TRASH_RESOURCE);
-  new_job->context = context;
-  new_job->task = base::Bind(
-      &DriveServiceInterface::TrashResource,
-      base::Unretained(drive_service_),
-      resource_id,
-      base::Bind(&JobScheduler::OnEntryActionJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = callback;
-  StartJob(new_job);
-}
-
-void JobScheduler::CopyResource(
-    const std::string& resource_id,
-    const std::string& parent_resource_id,
-    const std::string& new_title,
-    const base::Time& last_modified,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_COPY_RESOURCE);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::CopyResource,
-      base::Unretained(drive_service_),
-      resource_id,
-      parent_resource_id,
-      new_title,
-      last_modified,
-      base::Bind(&JobScheduler::OnGetFileResourceJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::UpdateResource(
-    const std::string& resource_id,
-    const std::string& parent_resource_id,
-    const std::string& new_title,
-    const base::Time& last_modified,
-    const base::Time& last_viewed_by_me,
-    const google_apis::drive::Properties& properties,
-    const ClientContext& context,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_UPDATE_RESOURCE);
-  new_job->context = context;
-  new_job->task = base::Bind(&DriveServiceInterface::UpdateResource,
-                             base::Unretained(drive_service_), resource_id,
-                             parent_resource_id, new_title, last_modified,
-                             last_viewed_by_me, properties,
-                             base::Bind(&JobScheduler::OnGetFileResourceJobDone,
-                                        weak_ptr_factory_.GetWeakPtr(),
-                                        new_job->job_info.job_id, callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::AddResourceToDirectory(
-    const std::string& parent_resource_id,
-    const std::string& resource_id,
-    const google_apis::EntryActionCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_ADD_RESOURCE_TO_DIRECTORY);
-  new_job->task = base::Bind(
-      &DriveServiceInterface::AddResourceToDirectory,
-      base::Unretained(drive_service_),
-      parent_resource_id,
-      resource_id,
-      base::Bind(&JobScheduler::OnEntryActionJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = callback;
-  StartJob(new_job);
-}
-
-void JobScheduler::RemoveResourceFromDirectory(
-    const std::string& parent_resource_id,
-    const std::string& resource_id,
-    const ClientContext& context,
-    const google_apis::EntryActionCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* new_job = CreateNewJob(TYPE_REMOVE_RESOURCE_FROM_DIRECTORY);
-  new_job->context = context;
-  new_job->task = base::Bind(
-      &DriveServiceInterface::RemoveResourceFromDirectory,
-      base::Unretained(drive_service_),
-      parent_resource_id,
-      resource_id,
-      base::Bind(&JobScheduler::OnEntryActionJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = callback;
-  StartJob(new_job);
-}
-
-void JobScheduler::AddNewDirectory(
-    const std::string& parent_resource_id,
-    const std::string& directory_title,
-    const AddNewDirectoryOptions& options,
-    const ClientContext& context,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* new_job = CreateNewJob(TYPE_ADD_NEW_DIRECTORY);
-  new_job->context = context;
-  new_job->task = base::Bind(
-      &DriveServiceInterface::AddNewDirectory,
-      base::Unretained(drive_service_),
-      parent_resource_id,
-      directory_title,
-      options,
-      base::Bind(&JobScheduler::OnGetFileResourceJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-JobID JobScheduler::DownloadFile(
-    const base::FilePath& virtual_path,
-    int64_t expected_file_size,
-    const base::FilePath& local_cache_path,
-    const std::string& resource_id,
-    const ClientContext& context,
-    const google_apis::DownloadActionCallback& download_action_callback,
-    const google_apis::GetContentCallback& get_content_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* new_job = CreateNewJob(TYPE_DOWNLOAD_FILE);
-  new_job->job_info.file_path = virtual_path;
-  new_job->job_info.num_total_bytes = expected_file_size;
-  new_job->context = context;
-  new_job->task = base::Bind(
-      &DriveServiceInterface::DownloadFile,
-      base::Unretained(drive_service_),
-      local_cache_path,
-      resource_id,
-      base::Bind(&JobScheduler::OnDownloadActionJobDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id,
-                 download_action_callback),
-      get_content_callback,
-      base::Bind(&JobScheduler::UpdateProgress,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 new_job->job_info.job_id));
-  new_job->abort_callback = CreateErrorRunCallback(download_action_callback);
-  StartJob(new_job);
-  return new_job->job_info.job_id;
-}
-
-void JobScheduler::UploadNewFile(
-    const std::string& parent_resource_id,
-    int64_t expected_file_size,
-    const base::FilePath& drive_file_path,
-    const base::FilePath& local_file_path,
-    const std::string& title,
-    const std::string& content_type,
-    const UploadNewFileOptions& options,
-    const ClientContext& context,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_NEW_FILE);
-  new_job->job_info.file_path = drive_file_path;
-  new_job->job_info.num_total_bytes = expected_file_size;
-  new_job->context = context;
-
-  UploadNewFileParams params;
-  params.parent_resource_id = parent_resource_id;
-  params.local_file_path = local_file_path;
-  params.title = title;
-  params.content_type = content_type;
-  params.options = options;
-
-  ResumeUploadParams resume_params;
-  resume_params.local_file_path = params.local_file_path;
-  resume_params.content_type = params.content_type;
-
-  params.callback = base::Bind(&JobScheduler::OnUploadCompletionJobDone,
-                               weak_ptr_factory_.GetWeakPtr(),
-                               new_job->job_info.job_id,
-                               resume_params,
-                               callback);
-  params.progress_callback = base::Bind(&JobScheduler::UpdateProgress,
-                                        weak_ptr_factory_.GetWeakPtr(),
-                                        new_job->job_info.job_id);
-  new_job->task = base::Bind(&RunUploadNewFile, uploader_.get(), params);
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::UploadExistingFile(
-    const std::string& resource_id,
-    int64_t expected_file_size,
-    const base::FilePath& drive_file_path,
-    const base::FilePath& local_file_path,
-    const std::string& content_type,
-    const UploadExistingFileOptions& options,
-    const ClientContext& context,
-    const google_apis::FileResourceCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_EXISTING_FILE);
-  new_job->job_info.file_path = drive_file_path;
-  new_job->job_info.num_total_bytes = expected_file_size;
-  new_job->context = context;
-
-  UploadExistingFileParams params;
-  params.resource_id = resource_id;
-  params.local_file_path = local_file_path;
-  params.content_type = content_type;
-  params.options = options;
-
-  ResumeUploadParams resume_params;
-  resume_params.local_file_path = params.local_file_path;
-  resume_params.content_type = params.content_type;
-
-  params.callback = base::Bind(&JobScheduler::OnUploadCompletionJobDone,
-                               weak_ptr_factory_.GetWeakPtr(),
-                               new_job->job_info.job_id,
-                               resume_params,
-                               callback);
-  params.progress_callback = base::Bind(&JobScheduler::UpdateProgress,
-                                        weak_ptr_factory_.GetWeakPtr(),
-                                        new_job->job_info.job_id);
-  new_job->task = base::Bind(&RunUploadExistingFile, uploader_.get(), params);
-  new_job->abort_callback = CreateErrorRunCallback(callback);
-  StartJob(new_job);
-}
-
-void JobScheduler::AddPermission(
-    const std::string& resource_id,
-    const std::string& email,
-    google_apis::drive::PermissionRole role,
-    const google_apis::EntryActionCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  JobEntry* new_job = CreateNewJob(TYPE_ADD_PERMISSION);
-  new_job->task = base::Bind(&DriveServiceInterface::AddPermission,
-                             base::Unretained(drive_service_),
-                             resource_id,
-                             email,
-                             role,
-                             base::Bind(&JobScheduler::OnEntryActionJobDone,
-                                        weak_ptr_factory_.GetWeakPtr(),
-                                        new_job->job_info.job_id,
-                                        callback));
-  new_job->abort_callback = callback;
-  StartJob(new_job);
-}
-
-JobScheduler::JobEntry* JobScheduler::CreateNewJob(JobType type) {
-  auto job = std::make_unique<JobEntry>(type);
-  JobEntry* job_raw = job.get();
-  int32_t job_key = job_map_.Add(std::move(job));
-  job_raw->job_info.job_id = job_key;
-  return job_raw;
-}
-
-void JobScheduler::StartJob(JobEntry* job) {
-  DCHECK(!job->task.is_null());
-
-  QueueJob(job->job_info.job_id);
-  NotifyJobAdded(job->job_info);
-  DoJobLoop(GetJobQueueType(job->job_info.job_type));
-}
-
-void JobScheduler::QueueJob(JobID job_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* job_entry = job_map_.Lookup(job_id);
-  DCHECK(job_entry);
-  const JobInfo& job_info = job_entry->job_info;
-
-  const QueueType queue_type = GetJobQueueType(job_info.job_type);
-  const bool batchable = job_info.job_type == TYPE_UPLOAD_EXISTING_FILE ||
-                         job_info.job_type == TYPE_UPLOAD_NEW_FILE;
-  queue_[queue_type]->Push(job_id, job_entry->context.type, batchable,
-                           job_info.num_total_bytes);
-
-  const std::string retry_prefix = job_entry->retry_count > 0 ?
-      base::StringPrintf(" (retry %d)", job_entry->retry_count) : "";
-  logger_->Log(logging::LOG_INFO,
-               "Job queued%s: %s - %s",
-               retry_prefix.c_str(),
-               job_info.ToString().c_str(),
-               GetQueueInfo(queue_type).c_str());
-}
-
-void JobScheduler::DoJobLoop(QueueType queue_type) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  const int accepted_priority = GetCurrentAcceptedPriority(queue_type);
-
-  // Abort all USER_INITAITED jobs when not accepted.
-  if (accepted_priority < USER_INITIATED) {
-    std::vector<JobID> jobs;
-    queue_[queue_type]->GetQueuedJobs(USER_INITIATED, &jobs);
-    for (size_t i = 0; i < jobs.size(); ++i) {
-      JobEntry* job = job_map_.Lookup(jobs[i]);
-      DCHECK(job);
-      AbortNotRunningJob(job, google_apis::DRIVE_NO_CONNECTION);
-    }
-  }
-
-  // Wait when throttled.
-  const base::Time now = base::Time::Now();
-  if (now < wait_until_) {
-    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE,
-        base::BindOnce(&JobScheduler::DoJobLoop, weak_ptr_factory_.GetWeakPtr(),
-                       queue_type),
-        wait_until_ - now);
-    return;
-  }
-
-  // Run the job with the highest priority in the queue.
-  std::vector<JobID> job_ids;
-  queue_[queue_type]->PopForRun(accepted_priority, &job_ids);
-  if (job_ids.empty())
-    return;
-
-  if (job_ids.size() > 1)
-    uploader_->StartBatchProcessing();
-
-  for (JobID job_id : job_ids) {
-    JobEntry* entry = job_map_.Lookup(job_id);
-    DCHECK(entry);
-
-    JobInfo* job_info = &entry->job_info;
-    job_info->state = STATE_RUNNING;
-    job_info->start_time = now;
-    NotifyJobUpdated(*job_info);
-
-    entry->cancel_callback = entry->task.Run();
-    logger_->Log(logging::LOG_INFO, "Job started: %s - %s",
-                 job_info->ToString().c_str(),
-                 GetQueueInfo(queue_type).c_str());
-  }
-
-  if (job_ids.size() > 1)
-    uploader_->StopBatchProcessing();
-
-  UpdateWait();
-}
-
-int JobScheduler::GetCurrentAcceptedPriority(QueueType queue_type) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  const int kNoJobShouldRun = -1;
-
-  // Should stop if Drive was disabled while running the fetch loop.
-  if (pref_service_->GetBoolean(prefs::kDisableDrive))
-    return kNoJobShouldRun;
-
-  // Should stop if the network is not online.
-  auto connection_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN;
-  network_connection_tracker_->GetConnectionType(
-      &connection_type, base::BindOnce(&JobScheduler::OnConnectionChanged,
-                                       weak_ptr_factory_.GetWeakPtr()));
-  if (connection_type == network::mojom::ConnectionType::CONNECTION_NONE)
-    return kNoJobShouldRun;
-
-  // For the file queue, if it is on cellular network, only user initiated
-  // operations are allowed to start.
-  if (queue_type == FILE_QUEUE &&
-      pref_service_->GetBoolean(prefs::kDisableDriveOverCellular) &&
-      network::NetworkConnectionTracker::IsConnectionCellular(connection_type))
-    return USER_INITIATED;
-
-  // Otherwise, every operations including background tasks are allowed.
-  return BACKGROUND;
-}
-
-void JobScheduler::UpdateWait() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (disable_throttling_ || throttle_count_ == 0)
-    return;
-
-  // Exponential backoff: https://developers.google.com/drive/handle-errors.
-  base::TimeDelta delay =
-      base::TimeDelta::FromSeconds(static_cast<int64_t>(1)
-                                   << (throttle_count_ - 1)) +
-      base::TimeDelta::FromMilliseconds(base::RandInt(0, 1000));
-  VLOG(1) << "Throttling for " << delay.InMillisecondsF();
-
-  wait_until_ = std::max(wait_until_, base::Time::Now() + delay);
-}
-
-bool JobScheduler::OnJobDone(JobID job_id,
-                             google_apis::DriveApiErrorCode error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  JobEntry* job_entry = job_map_.Lookup(job_id);
-  DCHECK(job_entry);
-  JobInfo* job_info = &job_entry->job_info;
-  QueueType queue_type = GetJobQueueType(job_info->job_type);
-  queue_[queue_type]->MarkFinished(job_id);
-
-  const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time;
-  bool success = (GDataToFileError(error) == FILE_ERROR_OK);
-  logger_->Log(success ? logging::LOG_INFO : logging::LOG_WARNING,
-               "Job done: %s => %s (elapsed time: %sms) - %s",
-               job_info->ToString().c_str(),
-               DriveApiErrorCodeToString(error).c_str(),
-               base::NumberToString(elapsed.InMilliseconds()).c_str(),
-               GetQueueInfo(queue_type).c_str());
-
-  // Retry, depending on the error.
-  const bool is_server_error =
-      error == google_apis::HTTP_SERVICE_UNAVAILABLE ||
-      error == google_apis::HTTP_INTERNAL_SERVER_ERROR;
-  if (is_server_error) {
-    if (throttle_count_ < kMaxThrottleCount)
-      ++throttle_count_;
-    UpdateWait();
-  } else {
-    throttle_count_ = 0;
-  }
-
-  const bool should_retry =
-      is_server_error && job_entry->retry_count < kMaxRetryCount;
-  if (should_retry) {
-    job_entry->cancel_callback.Reset();
-    job_info->state = STATE_RETRY;
-    NotifyJobUpdated(*job_info);
-
-    ++job_entry->retry_count;
-
-    // Requeue the job.
-    QueueJob(job_id);
-  } else {
-    NotifyJobDone(*job_info, error);
-    // The job has finished, no retry will happen in the scheduler. Now we can
-    // remove the job info from the map.
-    job_map_.Remove(job_id);
-  }
-
-  // Post a task to continue the job loop.  This allows us to finish handling
-  // the current job before starting the next one.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&JobScheduler::DoJobLoop,
-                                weak_ptr_factory_.GetWeakPtr(), queue_type));
-  return !should_retry;
-}
-
-void JobScheduler::OnGetTeamDriveListJobDone(
-    JobID job_id,
-    const google_apis::TeamDriveListCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::TeamDriveList> team_drive_list) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(team_drive_list));
-}
-
-void JobScheduler::OnGetFileListJobDone(
-    JobID job_id,
-    const google_apis::FileListCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::FileList> file_list) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(file_list));
-}
-
-void JobScheduler::OnGetChangeListJobDone(
-    JobID job_id,
-    const google_apis::ChangeListCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::ChangeList> change_list) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(change_list));
-}
-
-void JobScheduler::OnGetFileResourceJobDone(
-    JobID job_id,
-    const google_apis::FileResourceCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::FileResource> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(entry));
-}
-
-void JobScheduler::OnGetAboutResourceJobDone(
-    JobID job_id,
-    const google_apis::AboutResourceCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::AboutResource> about_resource) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(about_resource));
-}
-
-void JobScheduler::OnGetStartPageTokenDone(
-    JobID job_id,
-    const google_apis::StartPageTokenCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::StartPageToken> start_page_token) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(start_page_token));
-}
-
-void JobScheduler::OnEntryActionJobDone(
-    JobID job_id,
-    const google_apis::EntryActionCallback& callback,
-    google_apis::DriveApiErrorCode error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error);
-}
-
-void JobScheduler::OnDownloadActionJobDone(
-    JobID job_id,
-    const google_apis::DownloadActionCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    const base::FilePath& temp_file) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, temp_file);
-}
-
-void JobScheduler::OnUploadCompletionJobDone(
-    JobID job_id,
-    const ResumeUploadParams& resume_params,
-    const google_apis::FileResourceCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    const GURL& upload_location,
-    std::unique_ptr<google_apis::FileResource> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
-
-  if (!upload_location.is_empty()) {
-    // If upload_location is available, update the task to resume the
-    // upload process from the terminated point.
-    // When we need to retry, the error code should be HTTP_SERVICE_UNAVAILABLE
-    // so OnJobDone called below will be in charge to re-queue the job.
-    JobEntry* job_entry = job_map_.Lookup(job_id);
-    DCHECK(job_entry);
-
-    ResumeUploadFileParams params;
-    params.upload_location = upload_location;
-    params.local_file_path = resume_params.local_file_path;
-    params.content_type = resume_params.content_type;
-    params.callback = base::Bind(&JobScheduler::OnResumeUploadFileDone,
-                                 weak_ptr_factory_.GetWeakPtr(),
-                                 job_id,
-                                 job_entry->task,
-                                 callback);
-    params.progress_callback = base::Bind(&JobScheduler::UpdateProgress,
-                                          weak_ptr_factory_.GetWeakPtr(),
-                                          job_id);
-    job_entry->task = base::Bind(&RunResumeUploadFile, uploader_.get(), params);
-  }
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(entry));
-}
-
-void JobScheduler::OnResumeUploadFileDone(
-    JobID job_id,
-    const base::Callback<google_apis::CancelCallback()>& original_task,
-    const google_apis::FileResourceCallback& callback,
-    google_apis::DriveApiErrorCode error,
-    const GURL& upload_location,
-    std::unique_ptr<google_apis::FileResource> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!original_task.is_null());
-  DCHECK(!callback.is_null());
-
-  if (upload_location.is_empty()) {
-    // If upload_location is not available, we should discard it and stop trying
-    // to resume. Restore the original task.
-    JobEntry* job_entry = job_map_.Lookup(job_id);
-    DCHECK(job_entry);
-    job_entry->task = original_task;
-  }
-
-  if (OnJobDone(job_id, error))
-    callback.Run(error, std::move(entry));
-}
-
-void JobScheduler::UpdateProgress(JobID job_id,
-                                  int64_t progress,
-                                  int64_t total) {
-  JobEntry* job_entry = job_map_.Lookup(job_id);
-  DCHECK(job_entry);
-
-  job_entry->job_info.num_completed_bytes = progress;
-  if (total != -1)
-    job_entry->job_info.num_total_bytes = total;
-  NotifyJobUpdated(job_entry->job_info);
-}
-
-void JobScheduler::OnConnectionChanged(network::mojom::ConnectionType type) {
-  // When connection type switches from one connection to another,
-  // CONNECTION_NONE signal comes right before the changed connection signal.
-  // Ignore such signals to avoid aborting jobs.
-  if (type == network::mojom::ConnectionType::CONNECTION_NONE &&
-      !network_connection_tracker_->IsOffline())
-    return;
-
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // Resume the job loop.
-  // The network connection status will be checked
-  // in GetCurrentAcceptedPriority().
-  for (int i = METADATA_QUEUE; i < NUM_QUEUES; ++i)
-    DoJobLoop(static_cast<QueueType>(i));
-}
-
-JobScheduler::QueueType JobScheduler::GetJobQueueType(JobType type) {
-  switch (type) {
-    case TYPE_GET_ABOUT_RESOURCE:
-    case TYPE_GET_APP_LIST:
-    case TYPE_GET_ALL_TEAM_DRIVE_LIST:
-    case TYPE_GET_ALL_RESOURCE_LIST:
-    case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY:
-    case TYPE_SEARCH:
-    case TYPE_GET_CHANGE_LIST:
-    case TYPE_GET_REMAINING_CHANGE_LIST:
-    case TYPE_GET_REMAINING_TEAM_DRIVE_LIST:
-    case TYPE_GET_REMAINING_FILE_LIST:
-    case TYPE_GET_RESOURCE_ENTRY:
-    case TYPE_GET_SHARE_URL:
-    case TYPE_GET_START_PAGE_TOKEN:
-    case TYPE_TRASH_RESOURCE:
-    case TYPE_COPY_RESOURCE:
-    case TYPE_UPDATE_RESOURCE:
-    case TYPE_ADD_RESOURCE_TO_DIRECTORY:
-    case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY:
-    case TYPE_ADD_NEW_DIRECTORY:
-    case TYPE_ADD_PERMISSION:
-      return METADATA_QUEUE;
-
-    case TYPE_DOWNLOAD_FILE:
-    case TYPE_UPLOAD_NEW_FILE:
-    case TYPE_UPLOAD_EXISTING_FILE:
-      return FILE_QUEUE;
-  }
-  NOTREACHED();
-  return FILE_QUEUE;
-}
-
-void JobScheduler::AbortNotRunningJob(JobEntry* job,
-                                      google_apis::DriveApiErrorCode error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  const base::TimeDelta elapsed = base::Time::Now() - job->job_info.start_time;
-  const QueueType queue_type = GetJobQueueType(job->job_info.job_type);
-  logger_->Log(logging::LOG_INFO,
-               "Job aborted: %s => %s (elapsed time: %sms) - %s",
-               job->job_info.ToString().c_str(),
-               DriveApiErrorCodeToString(error).c_str(),
-               base::NumberToString(elapsed.InMilliseconds()).c_str(),
-               GetQueueInfo(queue_type).c_str());
-
-  base::Callback<void(google_apis::DriveApiErrorCode)> callback =
-      job->abort_callback;
-  queue_[GetJobQueueType(job->job_info.job_type)]->Remove(job->job_info.job_id);
-  NotifyJobDone(job->job_info, error);
-  job_map_.Remove(job->job_info.job_id);
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(callback, error));
-}
-
-void JobScheduler::NotifyJobAdded(const JobInfo& job_info) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (auto& observer : observer_list_)
-    observer.OnJobAdded(job_info);
-}
-
-void JobScheduler::NotifyJobDone(const JobInfo& job_info,
-                                 google_apis::DriveApiErrorCode error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (auto& observer : observer_list_)
-    observer.OnJobDone(job_info, GDataToFileError(error));
-}
-
-void JobScheduler::NotifyJobUpdated(const JobInfo& job_info) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (auto& observer : observer_list_)
-    observer.OnJobUpdated(job_info);
-}
-
-std::string JobScheduler::GetQueueInfo(QueueType type) const {
-  return QueueTypeToString(type) + " " + queue_[type]->ToString();
-}
-
-// static
-std::string JobScheduler::QueueTypeToString(QueueType type) {
-  switch (type) {
-    case METADATA_QUEUE:
-      return "METADATA_QUEUE";
-    case FILE_QUEUE:
-      return "FILE_QUEUE";
-    case NUM_QUEUES:
-      break;  // This value is just a sentinel. Should never be used.
-  }
-  NOTREACHED();
-  return "";
-}
-
-}  // namespace drive
diff --git a/components/drive/job_scheduler.h b/components/drive/job_scheduler.h
deleted file mode 100644
index 403cee2..0000000
--- a/components/drive/job_scheduler.h
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_JOB_SCHEDULER_H_
-#define COMPONENTS_DRIVE_JOB_SCHEDULER_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/containers/id_map.h"
-#include "base/macros.h"
-#include "base/observer_list.h"
-#include "base/threading/thread_checker.h"
-#include "components/drive/drive_uploader.h"
-#include "components/drive/job_list.h"
-#include "components/drive/job_queue.h"
-#include "components/drive/service/drive_service_interface.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
-#include "services/network/public/cpp/network_connection_tracker.h"
-
-class PrefService;
-
-namespace drive {
-
-class EventLogger;
-
-// Priority of a job.  Higher values are lower priority.
-enum ContextType {
-  USER_INITIATED,
-  BACKGROUND,
-  // Indicates the number of values of this enum.
-  NUM_CONTEXT_TYPES,
-};
-
-struct ClientContext {
-  explicit ClientContext(ContextType in_type) : type(in_type) {}
-  ContextType type;
-};
-
-// The JobScheduler is responsible for queuing and scheduling drive jobs.
-// Because jobs are executed concurrently by priority and retried for network
-// failures, there is no guarantee of orderings.
-//
-// Jobs are grouped into two priority levels:
-//   - USER_INITIATED jobs are those occur as a result of direct user actions.
-//   - BACKGROUND jobs runs in response to state changes, server actions, etc.
-// USER_INITIATED jobs must be handled immediately, thus have higher priority.
-// BACKGROUND jobs run only after all USER_INITIATED jobs have run.
-//
-// Orthogonally, jobs are grouped into two types:
-//   - "File jobs" transfer the contents of files.
-//   - "Metadata jobs" operates on file metadata or the directory structure.
-// On WiFi or Ethernet connections, all types of jobs just run.
-// On mobile connections (2G/3G/4G), we don't want large background traffic.
-// USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait
-// in the queue until the network type changes.
-// On offline case, no jobs run. USER_INITIATED jobs fail immediately.
-// BACKGROUND jobs stay in the queue and wait for network connection.
-class JobScheduler
-    : public network::NetworkConnectionTracker::NetworkConnectionObserver,
-      public JobListInterface {
- public:
-  JobScheduler(
-      PrefService* pref_service,
-      EventLogger* logger,
-      DriveServiceInterface* drive_service,
-      network::NetworkConnectionTracker* network_connection_tracker,
-      base::SequencedTaskRunner* blocking_task_runner,
-      mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider);
-
-  ~JobScheduler() override;
-
-  // JobListInterface overrides.
-  std::vector<JobInfo> GetJobInfoList() override;
-  void AddObserver(JobListObserver* observer) override;
-  void RemoveObserver(JobListObserver* observer) override;
-  void CancelJob(JobID job_id) override;
-  void CancelAllJobs() override;
-
-  // Adds a GetAboutResource operation to the queue.
-  // |callback| must not be null.
-  void GetAboutResource(const google_apis::AboutResourceCallback& callback);
-
-  // Adds a GetStartPageToken operation to the queue.
-  // If |team_drive_id| is empty then it will return the start token for the
-  // users changelog.
-  // |callback| must not be null.
-  void GetStartPageToken(const std::string& team_drive_id,
-                         const google_apis::StartPageTokenCallback& callback);
-
-  // Adds a GetAllTeamDriveList operation to the queue.
-  // |callback| must not be null.
-  void GetAllTeamDriveList(const google_apis::TeamDriveListCallback& callback);
-
-  // Adds a GetAllFileList operation to the queue.
-  // If |team_drive_id| is empty then it will return the file list for the
-  // users default corpus, otherwise will return the file list for the
-  // specified team drive.
-  // |callback| must not be null.
-  void GetAllFileList(const std::string& team_drive_id,
-                      const google_apis::FileListCallback& callback);
-
-  // Adds a GetFileListInDirectory operation to the queue.
-  // |callback| must not be null.
-  void GetFileListInDirectory(const std::string& directory_resource_id,
-                              const google_apis::FileListCallback& callback);
-
-  // Adds a Search operation to the queue.
-  // |callback| must not be null.
-  void Search(const std::string& search_query,
-              const google_apis::FileListCallback& callback);
-
-  // Adds a GetChangeList operation to the queue.
-  // |callback| must not be null.
-  void GetChangeList(int64_t start_changestamp,
-                     const google_apis::ChangeListCallback& callback);
-
-  // Adds a GetChangeList operation to the queue, where |start_page_token|
-  // is used to specify where to start retrieving the change list from.
-  // If |team_drive_id| is empty then it will return the change list for the
-  // users changelog.
-  // |callback| must not be null.
-  void GetChangeList(const std::string& team_drive_id,
-                     const std::string& start_page_token,
-                     const google_apis::ChangeListCallback& callback);
-
-  // Adds GetRemainingChangeList operation to the queue.
-  // |callback| must not be null.
-  void GetRemainingChangeList(const GURL& next_link,
-                              const google_apis::ChangeListCallback& callback);
-
-  // Adds GetRemainingTeamDriveList operation to the queue.
-  // |callback| must not be null.
-  void GetRemainingTeamDriveList(
-      const std::string& page_token,
-      const google_apis::TeamDriveListCallback& callback);
-
-  // Adds GetRemainingFileList operation to the queue.
-  // |callback| must not be null.
-  void GetRemainingFileList(const GURL& next_link,
-                            const google_apis::FileListCallback& callback);
-
-  // Adds a GetFileResource operation to the queue.
-  void GetFileResource(const std::string& resource_id,
-                       const ClientContext& context,
-                       const google_apis::FileResourceCallback& callback);
-
-  // Adds a TrashResource operation to the queue.
-  void TrashResource(const std::string& resource_id,
-                     const ClientContext& context,
-                     const google_apis::EntryActionCallback& callback);
-
-  // Adds a CopyResource operation to the queue.
-  void CopyResource(const std::string& resource_id,
-                    const std::string& parent_resource_id,
-                    const std::string& new_title,
-                    const base::Time& last_modified,
-                    const google_apis::FileResourceCallback& callback);
-
-  // Adds a UpdateResource operation to the queue.
-  void UpdateResource(const std::string& resource_id,
-                      const std::string& parent_resource_id,
-                      const std::string& new_title,
-                      const base::Time& last_modified,
-                      const base::Time& last_viewed_by_me,
-                      const google_apis::drive::Properties& properties,
-                      const ClientContext& context,
-                      const google_apis::FileResourceCallback& callback);
-
-  // Adds a AddResourceToDirectory operation to the queue.
-  void AddResourceToDirectory(const std::string& parent_resource_id,
-                              const std::string& resource_id,
-                              const google_apis::EntryActionCallback& callback);
-
-  // Adds a RemoveResourceFromDirectory operation to the queue.
-  void RemoveResourceFromDirectory(
-      const std::string& parent_resource_id,
-      const std::string& resource_id,
-      const ClientContext& context,
-      const google_apis::EntryActionCallback& callback);
-
-  // Adds a AddNewDirectory operation to the queue.
-  void AddNewDirectory(const std::string& parent_resource_id,
-                       const std::string& directory_title,
-                       const AddNewDirectoryOptions& options,
-                       const ClientContext& context,
-                       const google_apis::FileResourceCallback& callback);
-
-  // Adds a DownloadFile operation to the queue.
-  // The first two arguments |virtual_path| and |expected_file_size| are used
-  // only for filling JobInfo for the operation so that observers can get the
-  // detail. The actual operation never refers these values.
-  JobID DownloadFile(
-      const base::FilePath& virtual_path,
-      int64_t expected_file_size,
-      const base::FilePath& local_cache_path,
-      const std::string& resource_id,
-      const ClientContext& context,
-      const google_apis::DownloadActionCallback& download_action_callback,
-      const google_apis::GetContentCallback& get_content_callback);
-
-  // Adds an UploadNewFile operation to the queue.
-  void UploadNewFile(const std::string& parent_resource_id,
-                     int64_t expected_file_size,
-                     const base::FilePath& drive_file_path,
-                     const base::FilePath& local_file_path,
-                     const std::string& title,
-                     const std::string& content_type,
-                     const UploadNewFileOptions& options,
-                     const ClientContext& context,
-                     const google_apis::FileResourceCallback& callback);
-
-  // Adds an UploadExistingFile operation to the queue.
-  void UploadExistingFile(const std::string& resource_id,
-                          int64_t expected_file_size,
-                          const base::FilePath& drive_file_path,
-                          const base::FilePath& local_file_path,
-                          const std::string& content_type,
-                          const UploadExistingFileOptions& options,
-                          const ClientContext& context,
-                          const google_apis::FileResourceCallback& callback);
-
-  // Adds AddPermission operation to the queue. |callback| must not be null.
-  void AddPermission(const std::string& resource_id,
-                     const std::string& email,
-                     google_apis::drive::PermissionRole role,
-                     const google_apis::EntryActionCallback& callback);
-
- private:
-  friend class JobSchedulerTest;
-
-  enum QueueType {
-    METADATA_QUEUE,
-    FILE_QUEUE,
-    NUM_QUEUES
-  };
-
-  static const int kMaxJobCount[NUM_QUEUES];
-
-  // Represents a single entry in the job map.
-  struct JobEntry {
-    explicit JobEntry(JobType type);
-    ~JobEntry();
-
-    // General user-visible information on the job.
-    JobInfo job_info;
-
-    // Context of the job.
-    ClientContext context;
-
-    // The number of times the jobs is retried due to server errors.
-    int retry_count;
-
-    // The callback to start the job. Called each time it is retry.
-    base::Callback<google_apis::CancelCallback()> task;
-
-    // The callback to cancel the running job. It is returned from task.Run().
-    google_apis::CancelCallback cancel_callback;
-
-    // The callback to notify an error to the client of JobScheduler.
-    // This is used to notify cancel of a job that is not running yet.
-    base::Callback<void(google_apis::DriveApiErrorCode)> abort_callback;
-
-    base::ThreadChecker thread_checker_;
-  };
-
-  // Parameters for DriveUploader::ResumeUploadFile.
-  struct ResumeUploadParams;
-
-  // Creates a new job and add it to the job map.
-  JobEntry* CreateNewJob(JobType type);
-
-  // Adds the specified job to the queue and starts the job loop for the queue
-  // if needed.
-  void StartJob(JobEntry* job);
-
-  // Adds the specified job to the queue.
-  void QueueJob(JobID job_id);
-
-  // Determines the next job that should run, and starts it.
-  void DoJobLoop(QueueType queue_type);
-
-  // Returns the lowest acceptable priority level of the operations that is
-  // currently allowed to start for the |queue_type|.
-  int GetCurrentAcceptedPriority(QueueType queue_type);
-
-  // Updates |wait_until_| to throttle requests.
-  void UpdateWait();
-
-  // Retries the job if needed and returns false. Otherwise returns true.
-  bool OnJobDone(JobID job_id, google_apis::DriveApiErrorCode error);
-
-  // Callback for job finishing with a FileListCallback.
-  void OnGetTeamDriveListJobDone(
-      JobID job_id,
-      const google_apis::TeamDriveListCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::TeamDriveList> team_drive_list);
-
-  // Callback for job finishing with a FileListCallback.
-  void OnGetFileListJobDone(JobID job_id,
-                            const google_apis::FileListCallback& callback,
-                            google_apis::DriveApiErrorCode error,
-                            std::unique_ptr<google_apis::FileList> file_list);
-
-  // Callback for job finishing with a ChangeListCallback.
-  void OnGetChangeListJobDone(
-      JobID job_id,
-      const google_apis::ChangeListCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::ChangeList> change_list);
-
-  // Callback for job finishing with a FileResourceCallback.
-  void OnGetFileResourceJobDone(
-      JobID job_id,
-      const google_apis::FileResourceCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::FileResource> entry);
-
-  // Callback for job finishing with a AboutResourceCallback.
-  void OnGetAboutResourceJobDone(
-      JobID job_id,
-      const google_apis::AboutResourceCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::AboutResource> about_resource);
-
-  // Callback for job finishing with a GetStartPageTokenCallback.
-  void OnGetStartPageTokenDone(
-      JobID job_id,
-      const google_apis::StartPageTokenCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::StartPageToken> start_page_token);
-
-  // Callback for job finishing with a EntryActionCallback.
-  void OnEntryActionJobDone(JobID job_id,
-                            const google_apis::EntryActionCallback& callback,
-                            google_apis::DriveApiErrorCode error);
-
-  // Callback for job finishing with a DownloadActionCallback.
-  void OnDownloadActionJobDone(
-      JobID job_id,
-      const google_apis::DownloadActionCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      const base::FilePath& temp_file);
-
-  // Callback for job finishing with a UploadCompletionCallback.
-  void OnUploadCompletionJobDone(
-      JobID job_id,
-      const ResumeUploadParams& resume_params,
-      const google_apis::FileResourceCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      const GURL& upload_location,
-      std::unique_ptr<google_apis::FileResource> entry);
-
-  // Callback for DriveUploader::ResumeUploadFile().
-  void OnResumeUploadFileDone(
-      JobID job_id,
-      const base::Callback<google_apis::CancelCallback()>& original_task,
-      const google_apis::FileResourceCallback& callback,
-      google_apis::DriveApiErrorCode error,
-      const GURL& upload_location,
-      std::unique_ptr<google_apis::FileResource> entry);
-
-  // Updates the progress status of the specified job.
-  void UpdateProgress(JobID job_id, int64_t progress, int64_t total);
-
-  // network::NetworkConnectionTracker::NetworkConnectionObserver override.
-  void OnConnectionChanged(network::mojom::ConnectionType type) override;
-
-  // Get the type of queue the specified job should be put in.
-  QueueType GetJobQueueType(JobType type);
-
-  // For testing only.  Disables throttling so that testing is faster.
-  void SetDisableThrottling(bool disable) { disable_throttling_ = disable; }
-
-  // Aborts a job which is not in STATE_RUNNING.
-  void AbortNotRunningJob(JobEntry* job, google_apis::DriveApiErrorCode error);
-
-  // Notifies updates to observers.
-  void NotifyJobAdded(const JobInfo& job_info);
-  void NotifyJobDone(const JobInfo& job_info,
-                     google_apis::DriveApiErrorCode error);
-  void NotifyJobUpdated(const JobInfo& job_info);
-
-  // Gets information of the queue of the given type as string.
-  std::string GetQueueInfo(QueueType type) const;
-
-  // Returns a string representation of QueueType.
-  static std::string QueueTypeToString(QueueType type);
-
-  // The number of times operations have failed in a row, capped at
-  // kMaxThrottleCount.  This is used to calculate the delay before running the
-  // next task.
-  int throttle_count_;
-
-  // Jobs should not start running until this time. Used for throttling.
-  base::Time wait_until_;
-
-  // Disables throttling for testing.
-  bool disable_throttling_;
-
-  // The queues of jobs.
-  std::unique_ptr<JobQueue> queue_[NUM_QUEUES];
-
-  // The list of queued job info indexed by job IDs.
-  using JobIDMap = base::IDMap<std::unique_ptr<JobEntry>>;
-  JobIDMap job_map_;
-
-  // The list of observers for the scheduler.
-  base::ObserverList<JobListObserver>::Unchecked observer_list_;
-
-  EventLogger* logger_;
-  DriveServiceInterface* drive_service_;
-  network::NetworkConnectionTracker* network_connection_tracker_;
-  base::SequencedTaskRunner* blocking_task_runner_;
-  std::unique_ptr<DriveUploaderInterface> uploader_;
-
-  PrefService* pref_service_;
-
-  base::ThreadChecker thread_checker_;
-
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<JobScheduler> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(JobScheduler);
-};
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_JOB_SCHEDULER_H_
diff --git a/components/drive/job_scheduler_unittest.cc b/components/drive/job_scheduler_unittest.cc
deleted file mode 100644
index 237bdc3..0000000
--- a/components/drive/job_scheduler_unittest.cc
+++ /dev/null
@@ -1,1105 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/job_scheduler.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/drive_pref_names.h"
-#include "components/drive/event_logger.h"
-#include "components/drive/file_system_core_util.h"
-#include "components/drive/service/fake_drive_service.h"
-#include "components/drive/service/test_util.h"
-#include "components/prefs/testing_pref_service.h"
-#include "content/public/test/browser_task_environment.h"
-#include "google_apis/drive/drive_api_parser.h"
-#include "google_apis/drive/test_util.h"
-#include "services/network/test/test_network_connection_tracker.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-
-namespace {
-
-// Dummy value passed for the |expected_file_size| parameter of DownloadFile().
-const int64_t kDummyDownloadFileSize = 0;
-
-void CopyTitleFromFileResourceCallback(
-    std::vector<std::string>* title_list_out,
-    google_apis::DriveApiErrorCode error_in,
-    std::unique_ptr<google_apis::FileResource> entry_in) {
-  title_list_out->push_back(entry_in->title());
-}
-
-class JobListLogger : public JobListObserver {
- public:
-  enum EventType {
-    ADDED,
-    UPDATED,
-    DONE,
-  };
-
-  struct EventLog {
-    EventType type;
-    JobInfo info;
-
-    EventLog(EventType type, const JobInfo& info) : type(type), info(info) {
-    }
-  };
-
-  // Checks whether the specified type of event has occurred.
-  bool Has(EventType type, JobType job_type) {
-    for (size_t i = 0; i < events.size(); ++i) {
-      if (events[i].type == type && events[i].info.job_type == job_type)
-        return true;
-    }
-    return false;
-  }
-
-  // Gets the progress event information of the specified type.
-  void GetProgressInfo(JobType job_type, std::vector<int64_t>* progress) {
-    for (size_t i = 0; i < events.size(); ++i) {
-      if (events[i].type == UPDATED && events[i].info.job_type == job_type)
-        progress->push_back(events[i].info.num_completed_bytes);
-    }
-  }
-
-  // JobListObserver overrides.
-  void OnJobAdded(const JobInfo& info) override {
-    events.push_back(EventLog(ADDED, info));
-  }
-
-  void OnJobUpdated(const JobInfo& info) override {
-    events.push_back(EventLog(UPDATED, info));
-  }
-
-  void OnJobDone(const JobInfo& info, FileError error) override {
-    events.push_back(EventLog(DONE, info));
-  }
-
- private:
-  std::vector<EventLog> events;
-};
-
-// Fake drive service extended for testing cancellation.
-// When upload_new_file_cancelable is set, this Drive service starts
-// returning a closure to cancel from InitiateUploadNewFile(). The task will
-// finish only when the cancel closure is called.
-class CancelTestableFakeDriveService : public FakeDriveService {
- public:
-  CancelTestableFakeDriveService()
-      : upload_new_file_cancelable_(false) {
-  }
-
-  void set_upload_new_file_cancelable(bool cancelable) {
-    upload_new_file_cancelable_ = cancelable;
-  }
-
-  google_apis::CancelCallback InitiateUploadNewFile(
-      const std::string& content_type,
-      int64_t content_length,
-      const std::string& parent_resource_id,
-      const std::string& title,
-      const UploadNewFileOptions& options,
-      const google_apis::InitiateUploadCallback& callback) override {
-    if (upload_new_file_cancelable_)
-      return base::Bind(callback, google_apis::DRIVE_CANCELLED, GURL());
-
-    return FakeDriveService::InitiateUploadNewFile(content_type,
-                                                   content_length,
-                                                   parent_resource_id,
-                                                   title,
-                                                   options,
-                                                   callback);
-  }
-
- private:
-  bool upload_new_file_cancelable_;
-};
-
-const char kHello[] = "Hello";
-const size_t kHelloLen = sizeof(kHello) - 1;
-
-}  // namespace
-
-class JobSchedulerTest : public testing::Test {
- public:
-  JobSchedulerTest()
-      : pref_service_(new TestingPrefServiceSimple) {
-    test_util::RegisterDrivePrefs(pref_service_->registry());
-  }
-
-  void SetUp() override {
-    logger_ = std::make_unique<EventLogger>();
-
-    fake_drive_service_ = std::make_unique<CancelTestableFakeDriveService>();
-    test_util::SetUpTestEntries(fake_drive_service_.get());
-
-    ConnectToWifi();
-    scheduler_ = std::make_unique<JobScheduler>(
-        pref_service_.get(), logger_.get(), fake_drive_service_.get(),
-        network::TestNetworkConnectionTracker::GetInstance(),
-        base::ThreadTaskRunnerHandle::Get().get(), mojo::NullRemote());
-    scheduler_->SetDisableThrottling(true);
-  }
-
- protected:
-  // Sets up TestNetworkConnectionTracker as if it's connected to a network with
-  // the specified connection type.
-  void ChangeConnectionType(network::mojom::ConnectionType type) {
-    network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType(
-        type);
-  }
-
-  // Sets up TestNetworkConnectionTracker as if it's connected to wifi network.
-  void ConnectToWifi() {
-    ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_WIFI);
-  }
-
-  // Sets up TestNetworkConnectionTracker as if it's connected to cellular
-  // network.
-  void ConnectToCellular() {
-    ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_2G);
-  }
-
-  // Sets up TestNetworkConnectionTracker as if it's connected to wimax network.
-  void ConnectToWimax() {
-    ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_4G);
-  }
-
-  // Sets up TestNetworkConnectionTracker as if it's disconnected.
-  void ConnectToNone() {
-    ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_NONE);
-  }
-
-  static int GetMetadataQueueMaxJobCount() {
-    return JobScheduler::kMaxJobCount[JobScheduler::METADATA_QUEUE];
-  }
-
-  content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<TestingPrefServiceSimple> pref_service_;
-  std::unique_ptr<EventLogger> logger_;
-  std::unique_ptr<CancelTestableFakeDriveService> fake_drive_service_;
-  std::unique_ptr<JobScheduler> scheduler_;
-};
-
-TEST_F(JobSchedulerTest, GetAboutResource) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &error, &about_resource));
-  base::RunLoop().RunUntilIdle();
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(about_resource);
-}
-
-TEST_F(JobSchedulerTest, GetStartPageToken) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::StartPageToken> start_page_token;
-  scheduler_->GetStartPageToken(
-      util::kTeamDriveIdDefaultCorpus,
-      google_apis::test_util::CreateCopyResultCallback(&error,
-                                                       &start_page_token));
-  base::RunLoop().RunUntilIdle();
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(start_page_token);
-}
-
-TEST_F(JobSchedulerTest, GetAllTeamDriveList) {
-  ConnectToWifi();
-
-  fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID", "TEAM_DRIVE_NAME");
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::TeamDriveList> team_drive_list;
-
-  scheduler_->GetAllTeamDriveList(
-      google_apis::test_util::CreateCopyResultCallback(&error,
-                                                       &team_drive_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(team_drive_list);
-}
-
-TEST_F(JobSchedulerTest, GetAllFileList) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileList> file_list;
-
-  scheduler_->GetAllFileList(
-      util::kTeamDriveIdDefaultCorpus,
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(file_list);
-}
-
-TEST_F(JobSchedulerTest, GetFileListInDirectory) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileList> file_list;
-
-  scheduler_->GetFileListInDirectory(
-      fake_drive_service_->GetRootResourceId(),
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(file_list);
-}
-
-TEST_F(JobSchedulerTest, Search) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileList> file_list;
-
-  scheduler_->Search(
-      "File",  // search query
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(file_list);
-}
-
-TEST_F(JobSchedulerTest, GetChangeList) {
-  ConnectToWifi();
-
-  int64_t old_largest_change_id =
-      fake_drive_service_->about_resource().largest_change_id();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-
-  // Create a new directory.
-  {
-    std::unique_ptr<google_apis::FileResource> entry;
-    fake_drive_service_->AddNewDirectory(
-        fake_drive_service_->GetRootResourceId(), "new directory",
-        AddNewDirectoryOptions(),
-        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-    base::RunLoop().RunUntilIdle();
-    ASSERT_EQ(google_apis::HTTP_CREATED, error);
-  }
-
-  error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::ChangeList> change_list;
-  scheduler_->GetChangeList(
-      old_largest_change_id + 1,
-      google_apis::test_util::CreateCopyResultCallback(&error, &change_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(change_list);
-}
-
-TEST_F(JobSchedulerTest, GetChangeListWithStartToken) {
-  ConnectToWifi();
-
-  // TODO(slangley): Find the start page token from the fake drive service
-  const std::string& start_page_token =
-      fake_drive_service_->start_page_token().start_page_token();
-
-  const std::string team_drive_id;  // Empty means users default corpus
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-
-  // Create a new directory.
-  {
-    std::unique_ptr<google_apis::FileResource> entry;
-    fake_drive_service_->AddNewDirectory(
-        fake_drive_service_->GetRootResourceId(), "new directory",
-        AddNewDirectoryOptions(),
-        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-    base::RunLoop().RunUntilIdle();
-    ASSERT_EQ(google_apis::HTTP_CREATED, error);
-  }
-
-  error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::ChangeList> change_list;
-  scheduler_->GetChangeList(
-      team_drive_id, start_page_token,
-      google_apis::test_util::CreateCopyResultCallback(&error, &change_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(change_list);
-}
-
-TEST_F(JobSchedulerTest, GetRemainingChangeList) {
-  ConnectToWifi();
-  fake_drive_service_->set_default_max_results(2);
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::ChangeList> change_list;
-
-  scheduler_->GetChangeList(
-      0,
-      google_apis::test_util::CreateCopyResultCallback(&error, &change_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(change_list);
-
-  // Keep the next url before releasing the |change_list|.
-  GURL next_url(change_list->next_link());
-
-  error = google_apis::DRIVE_OTHER_ERROR;
-  change_list.reset();
-
-  scheduler_->GetRemainingChangeList(
-      next_url,
-      google_apis::test_util::CreateCopyResultCallback(&error, &change_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(change_list);
-}
-
-TEST_F(JobSchedulerTest, GetRemainingTeamDriveList) {
-  ConnectToWifi();
-  fake_drive_service_->set_default_max_results(2);
-  fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_1", "TEAM_DRIVE_NAME 1");
-  fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_2", "TEAM_DRIVE_NAME 2");
-  fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_3", "TEAM_DRIVE_NAME 3");
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::TeamDriveList> team_drive_list;
-
-  scheduler_->GetAllTeamDriveList(
-      google_apis::test_util::CreateCopyResultCallback(&error,
-                                                       &team_drive_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(team_drive_list);
-
-  // Keep the next page_token before releasing the |file_list|.
-  std::string next_page_token(team_drive_list->next_page_token());
-
-  error = google_apis::DRIVE_OTHER_ERROR;
-  team_drive_list.reset();
-
-  scheduler_->GetRemainingTeamDriveList(
-      next_page_token, google_apis::test_util::CreateCopyResultCallback(
-                           &error, &team_drive_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(team_drive_list);
-}
-
-TEST_F(JobSchedulerTest, GetRemainingFileList) {
-  ConnectToWifi();
-  fake_drive_service_->set_default_max_results(2);
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileList> file_list;
-
-  scheduler_->GetFileListInDirectory(
-      fake_drive_service_->GetRootResourceId(),
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(file_list);
-
-  // Keep the next url before releasing the |file_list|.
-  GURL next_url(file_list->next_link());
-
-  error = google_apis::DRIVE_OTHER_ERROR;
-  file_list.reset();
-
-  scheduler_->GetRemainingFileList(
-      next_url,
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_list));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(file_list);
-}
-
-TEST_F(JobSchedulerTest, GetFileResource) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-
-  scheduler_->GetFileResource(
-      "2_file_resource_id",  // resource ID
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(entry);
-}
-
-TEST_F(JobSchedulerTest, TrashResource) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-
-  scheduler_->TrashResource(
-      "2_file_resource_id",
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-}
-
-TEST_F(JobSchedulerTest, CopyResource) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-
-  scheduler_->CopyResource(
-      "2_file_resource_id",  // resource ID
-      "1_folder_resource_id",  // parent resource ID
-      "New Document",  // new title
-      base::Time(),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(entry);
-}
-
-TEST_F(JobSchedulerTest, UpdateResource) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-
-  scheduler_->UpdateResource(
-      "2_file_resource_id",    // resource ID
-      "1_folder_resource_id",  // parent resource ID
-      "New Document",          // new title
-      base::Time(), base::Time(), google_apis::drive::Properties(),
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(entry);
-}
-
-TEST_F(JobSchedulerTest, AddResourceToDirectory) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-
-  scheduler_->AddResourceToDirectory(
-      "1_folder_resource_id",
-      "2_file_resource_id",
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-}
-
-TEST_F(JobSchedulerTest, RemoveResourceFromDirectory) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-
-  scheduler_->RemoveResourceFromDirectory(
-      "1_folder_resource_id",
-      "subdirectory_file_1_id",  // resource ID
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_NO_CONTENT, error);
-}
-
-TEST_F(JobSchedulerTest, AddNewDirectory) {
-  ConnectToWifi();
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(),  // Root directory.
-      "New Directory", AddNewDirectoryOptions(), ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(google_apis::HTTP_CREATED, error);
-  ASSERT_TRUE(entry);
-}
-
-TEST_F(JobSchedulerTest, PriorityHandling) {
-  // Saturate the metadata job queue with uninteresting jobs to prevent
-  // following jobs from starting.
-  google_apis::DriveApiErrorCode error_dontcare =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry_dontcare;
-  for (int i = 0; i < GetMetadataQueueMaxJobCount(); ++i) {
-    std::string resource_id("2_file_resource_id");
-    scheduler_->GetFileResource(
-        resource_id,
-        ClientContext(USER_INITIATED),
-        google_apis::test_util::CreateCopyResultCallback(&error_dontcare,
-                                                         &entry_dontcare));
-  }
-
-  // Start jobs with different priorities.
-  std::string title_1("new file 1");
-  std::string title_2("new file 2");
-  std::string title_3("new file 3");
-  std::string title_4("new file 4");
-  std::vector<std::string> titles;
-
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(), title_1,
-      AddNewDirectoryOptions(), ClientContext(USER_INITIATED),
-      base::Bind(&CopyTitleFromFileResourceCallback, &titles));
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(), title_2,
-      AddNewDirectoryOptions(), ClientContext(BACKGROUND),
-      base::Bind(&CopyTitleFromFileResourceCallback, &titles));
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(), title_3,
-      AddNewDirectoryOptions(), ClientContext(BACKGROUND),
-      base::Bind(&CopyTitleFromFileResourceCallback, &titles));
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(), title_4,
-      AddNewDirectoryOptions(), ClientContext(USER_INITIATED),
-      base::Bind(&CopyTitleFromFileResourceCallback, &titles));
-
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(4ul, titles.size());
-  EXPECT_EQ(title_1, titles[0]);
-  EXPECT_EQ(title_4, titles[1]);
-  EXPECT_EQ(title_2, titles[2]);
-  EXPECT_EQ(title_3, titles[3]);
-}
-
-TEST_F(JobSchedulerTest, NoConnectionUserInitiated) {
-  ConnectToNone();
-
-  std::string resource_id("2_file_resource_id");
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-  scheduler_->GetFileResource(
-      resource_id,
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(google_apis::DRIVE_NO_CONNECTION, error);
-}
-
-TEST_F(JobSchedulerTest, NoConnectionBackground) {
-  ConnectToNone();
-
-  std::string resource_id("2_file_resource_id");
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-  scheduler_->GetFileResource(
-      resource_id,
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_FALSE(entry);
-
-  // Reconnect to the net.
-  ConnectToWifi();
-
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  ASSERT_TRUE(entry);
-}
-
-TEST_F(JobSchedulerTest, DownloadFileCellularDisabled) {
-  ConnectToCellular();
-
-  // Disable fetching over cellular network.
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
-
-  // Try to get a file in the background
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  const base::FilePath kOutputFilePath =
-      temp_dir.GetPath().AppendASCII("whatever.txt");
-  google_apis::DriveApiErrorCode download_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  base::FilePath output_file_path;
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize,
-      kOutputFilePath,
-      "2_file_resource_id",
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(
-          &download_error, &output_file_path),
-      google_apis::GetContentCallback());
-  // Metadata should still work
-  google_apis::DriveApiErrorCode metadata_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-
-  // Try to get the metadata
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &metadata_error, &about_resource));
-  base::RunLoop().RunUntilIdle();
-
-  // Check the metadata
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error);
-  ASSERT_TRUE(about_resource);
-
-  // Check the download
-  EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR, download_error);
-
-  // Switch to a Wifi connection
-  ConnectToWifi();
-
-  base::RunLoop().RunUntilIdle();
-
-  // Check the download again
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error);
-  std::string content;
-  EXPECT_EQ(output_file_path, kOutputFilePath);
-  ASSERT_TRUE(base::ReadFileToString(output_file_path, &content));
-  EXPECT_EQ("This is some test content.", content);
-}
-
-TEST_F(JobSchedulerTest, DownloadFileWimaxDisabled) {
-  ConnectToWimax();
-
-  // Disable fetching over cellular network.
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
-
-  // Try to get a file in the background
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  const base::FilePath kOutputFilePath =
-      temp_dir.GetPath().AppendASCII("whatever.txt");
-  google_apis::DriveApiErrorCode download_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  base::FilePath output_file_path;
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize,
-      kOutputFilePath,
-      "2_file_resource_id",
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(
-          &download_error, &output_file_path),
-      google_apis::GetContentCallback());
-  // Metadata should still work
-  google_apis::DriveApiErrorCode metadata_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-
-  // Try to get the metadata
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &metadata_error, &about_resource));
-  base::RunLoop().RunUntilIdle();
-
-  // Check the metadata
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error);
-  ASSERT_TRUE(about_resource);
-
-  // Check the download
-  EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR, download_error);
-
-  // Switch to a Wifi connection
-  ConnectToWifi();
-
-  base::RunLoop().RunUntilIdle();
-
-  // Check the download again
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error);
-  std::string content;
-  EXPECT_EQ(output_file_path, kOutputFilePath);
-  ASSERT_TRUE(base::ReadFileToString(output_file_path, &content));
-  EXPECT_EQ("This is some test content.", content);
-}
-
-TEST_F(JobSchedulerTest, DownloadFileCellularEnabled) {
-  ConnectToCellular();
-
-  // Enable fetching over cellular network.
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false);
-
-  // Try to get a file in the background
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  const base::FilePath kOutputFilePath =
-      temp_dir.GetPath().AppendASCII("whatever.txt");
-  google_apis::DriveApiErrorCode download_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  base::FilePath output_file_path;
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize,
-      kOutputFilePath,
-      "2_file_resource_id",
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(
-          &download_error, &output_file_path),
-      google_apis::GetContentCallback());
-  // Metadata should still work
-  google_apis::DriveApiErrorCode metadata_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-
-  // Try to get the metadata
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &metadata_error, &about_resource));
-  base::RunLoop().RunUntilIdle();
-
-  // Check the metadata
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error);
-  ASSERT_TRUE(about_resource);
-
-  // Check the download
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error);
-  std::string content;
-  EXPECT_EQ(output_file_path, kOutputFilePath);
-  ASSERT_TRUE(base::ReadFileToString(output_file_path, &content));
-  EXPECT_EQ("This is some test content.", content);
-}
-
-TEST_F(JobSchedulerTest, DownloadFileWimaxEnabled) {
-  ConnectToWimax();
-
-  // Enable fetching over cellular network.
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false);
-
-  // Try to get a file in the background
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  const base::FilePath kOutputFilePath =
-      temp_dir.GetPath().AppendASCII("whatever.txt");
-  google_apis::DriveApiErrorCode download_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  base::FilePath output_file_path;
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize,
-      kOutputFilePath,
-      "2_file_resource_id",
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(
-          &download_error, &output_file_path),
-      google_apis::GetContentCallback());
-  // Metadata should still work
-  google_apis::DriveApiErrorCode metadata_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-
-  // Try to get the metadata
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &metadata_error, &about_resource));
-  base::RunLoop().RunUntilIdle();
-
-  // Check the metadata
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error);
-  ASSERT_TRUE(about_resource);
-
-  // Check the download
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error);
-  std::string content;
-  EXPECT_EQ(output_file_path, kOutputFilePath);
-  ASSERT_TRUE(base::ReadFileToString(output_file_path, &content));
-  EXPECT_EQ("This is some test content.", content);
-}
-
-TEST_F(JobSchedulerTest, JobInfo) {
-  JobListLogger logger;
-  scheduler_->AddObserver(&logger);
-
-  // Disable background upload/download.
-  ConnectToWimax();
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
-
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-  std::unique_ptr<google_apis::AboutResource> about_resource;
-  base::FilePath path;
-
-  std::set<JobType> expected_types;
-
-  // Add many jobs.
-  expected_types.insert(TYPE_ADD_NEW_DIRECTORY);
-  scheduler_->AddNewDirectory(
-      fake_drive_service_->GetRootResourceId(), "New Directory",
-      AddNewDirectoryOptions(), ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  expected_types.insert(TYPE_GET_ABOUT_RESOURCE);
-  scheduler_->GetAboutResource(
-      google_apis::test_util::CreateCopyResultCallback(
-          &error, &about_resource));
-  expected_types.insert(TYPE_UPDATE_RESOURCE);
-  scheduler_->UpdateResource(
-      "2_file_resource_id", std::string(), "New Title", base::Time(),
-      base::Time(), google_apis::drive::Properties(),
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  expected_types.insert(TYPE_DOWNLOAD_FILE);
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize, temp_dir.GetPath().AppendASCII("whatever.txt"),
-      "2_file_resource_id", ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&error, &path),
-      google_apis::GetContentCallback());
-
-  // The number of jobs queued so far.
-  EXPECT_EQ(4U, scheduler_->GetJobInfoList().size());
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_NEW_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_GET_ABOUT_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_UPDATE_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_DOWNLOAD_FILE));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_UPDATE_RESOURCE));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE));
-
-  // Add more jobs.
-  expected_types.insert(TYPE_ADD_RESOURCE_TO_DIRECTORY);
-  scheduler_->AddResourceToDirectory(
-      "1_folder_resource_id",
-      "2_file_resource_id",
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  expected_types.insert(TYPE_COPY_RESOURCE);
-  scheduler_->CopyResource(
-      "5_document_resource_id",
-      fake_drive_service_->GetRootResourceId(),
-      "New Document",
-      base::Time(),  // last_modified
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-
-  // 6 jobs in total were queued.
-  std::vector<JobInfo> jobs = scheduler_->GetJobInfoList();
-  EXPECT_EQ(6U, jobs.size());
-  std::set<JobType> actual_types;
-  std::set<JobID> job_ids;
-  for (size_t i = 0; i < jobs.size(); ++i) {
-    actual_types.insert(jobs[i].job_type);
-    job_ids.insert(jobs[i].job_id);
-  }
-  EXPECT_EQ(expected_types, actual_types);
-  EXPECT_EQ(6U, job_ids.size()) << "All job IDs must be unique";
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_RESOURCE_TO_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_COPY_RESOURCE));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE));
-
-  // Run the jobs.
-  base::RunLoop().RunUntilIdle();
-
-  // All jobs except the BACKGROUND job should have started running (UPDATED)
-  // and then finished (DONE).
-  jobs = scheduler_->GetJobInfoList();
-  ASSERT_EQ(1U, jobs.size());
-  EXPECT_EQ(TYPE_DOWNLOAD_FILE, jobs[0].job_type);
-
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_ADD_NEW_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_GET_ABOUT_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_UPDATE_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED,
-                         TYPE_ADD_RESOURCE_TO_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_COPY_RESOURCE));
-  EXPECT_FALSE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE));
-
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_UPDATE_RESOURCE));
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY));
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE));
-  EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE));
-
-  // Run the background downloading job as well.
-  ConnectToWifi();
-  base::RunLoop().RunUntilIdle();
-
-  // All jobs should have finished.
-  EXPECT_EQ(0U, scheduler_->GetJobInfoList().size());
-  EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE));
-  EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE));
-}
-
-TEST_F(JobSchedulerTest, JobInfoProgress) {
-  JobListLogger logger;
-  scheduler_->AddObserver(&logger);
-
-  ConnectToWifi();
-
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
-  base::FilePath path;
-
-  // Download job.
-  scheduler_->DownloadFile(
-      base::FilePath::FromUTF8Unsafe("drive/whatever.txt"),  // virtual path
-      kDummyDownloadFileSize, temp_dir.GetPath().AppendASCII("whatever.txt"),
-      "2_file_resource_id", ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&error, &path),
-      google_apis::GetContentCallback());
-  base::RunLoop().RunUntilIdle();
-
-  std::vector<int64_t> download_progress;
-  logger.GetProgressInfo(TYPE_DOWNLOAD_FILE, &download_progress);
-  ASSERT_TRUE(!download_progress.empty());
-  EXPECT_TRUE(base::STLIsSorted(download_progress));
-  EXPECT_GE(download_progress.front(), 0);
-  EXPECT_LE(download_progress.back(), 26);
-
-  // Upload job.
-  path = temp_dir.GetPath().AppendASCII("new_file.txt");
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, kHello));
-  google_apis::DriveApiErrorCode upload_error =
-      google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-
-  scheduler_->UploadNewFile(
-      fake_drive_service_->GetRootResourceId(), kHelloLen,
-      base::FilePath::FromUTF8Unsafe("drive/new_file.txt"), path, "dummy title",
-      "plain/plain", UploadNewFileOptions(), ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&upload_error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  std::vector<int64_t> upload_progress;
-  logger.GetProgressInfo(TYPE_UPLOAD_NEW_FILE, &upload_progress);
-  ASSERT_TRUE(!upload_progress.empty());
-  EXPECT_TRUE(base::STLIsSorted(upload_progress));
-  EXPECT_GE(upload_progress.front(), 0);
-  EXPECT_LE(upload_progress.back(), 13);
-}
-
-TEST_F(JobSchedulerTest, CancelPendingJob) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath upload_path = temp_dir.GetPath().AppendASCII("new_file.txt");
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, kHello));
-
-  // To create a pending job for testing, set the mode to cellular connection
-  // and issue BACKGROUND jobs.
-  ConnectToCellular();
-  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
-
-  // Start the first job and record its job ID.
-  google_apis::DriveApiErrorCode error1 = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-  scheduler_->UploadNewFile(
-      fake_drive_service_->GetRootResourceId(), kHelloLen,
-      base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path,
-      "dummy title 1", "text/plain", UploadNewFileOptions(),
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&error1, &entry));
-
-  const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList();
-  ASSERT_EQ(1u, jobs.size());
-  ASSERT_EQ(STATE_NONE, jobs[0].state);  // Not started yet.
-  JobID first_job_id = jobs[0].job_id;
-
-  // Start the second job.
-  google_apis::DriveApiErrorCode error2 = google_apis::DRIVE_OTHER_ERROR;
-  scheduler_->UploadNewFile(
-      fake_drive_service_->GetRootResourceId(), kHelloLen,
-      base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path,
-      "dummy title 2", "text/plain", UploadNewFileOptions(),
-      ClientContext(BACKGROUND),
-      google_apis::test_util::CreateCopyResultCallback(&error2, &entry));
-
-  // Cancel the first one.
-  scheduler_->CancelJob(first_job_id);
-
-  // Only the first job should be cancelled.
-  ConnectToWifi();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(google_apis::DRIVE_CANCELLED, error1);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error2);
-  EXPECT_TRUE(scheduler_->GetJobInfoList().empty());
-}
-
-TEST_F(JobSchedulerTest, CancelRunningJob) {
-  ConnectToWifi();
-
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath upload_path = temp_dir.GetPath().AppendASCII("new_file.txt");
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, kHello));
-
-  // Run as a cancelable task.
-  fake_drive_service_->set_upload_new_file_cancelable(true);
-  google_apis::DriveApiErrorCode error1 = google_apis::DRIVE_OTHER_ERROR;
-  std::unique_ptr<google_apis::FileResource> entry;
-  scheduler_->UploadNewFile(
-      fake_drive_service_->GetRootResourceId(), kHelloLen,
-      base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path,
-      "dummy title 1", "text/plain", UploadNewFileOptions(),
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error1, &entry));
-
-  const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList();
-  ASSERT_EQ(1u, jobs.size());
-  ASSERT_EQ(STATE_RUNNING, jobs[0].state);  // It's running.
-  JobID first_job_id = jobs[0].job_id;
-
-  // Start the second job normally.
-  fake_drive_service_->set_upload_new_file_cancelable(false);
-  google_apis::DriveApiErrorCode error2 = google_apis::DRIVE_OTHER_ERROR;
-  scheduler_->UploadNewFile(
-      fake_drive_service_->GetRootResourceId(), kHelloLen,
-      base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path,
-      "dummy title 2", "text/plain", UploadNewFileOptions(),
-      ClientContext(USER_INITIATED),
-      google_apis::test_util::CreateCopyResultCallback(&error2, &entry));
-
-  // Cancel the first one.
-  scheduler_->CancelJob(first_job_id);
-
-  // Only the first job should be cancelled.
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(google_apis::DRIVE_CANCELLED, error1);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error2);
-  EXPECT_TRUE(scheduler_->GetJobInfoList().empty());
-}
-
-}  // namespace drive
diff --git a/components/drive/local_file_reader.cc b/components/drive/local_file_reader.cc
deleted file mode 100644
index 9131fae..0000000
--- a/components/drive/local_file_reader.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/local_file_reader.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/sequenced_task_runner.h"
-#include "net/base/completion_once_callback.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-
-namespace drive {
-namespace util {
-
-LocalFileReader::LocalFileReader(
-    base::SequencedTaskRunner* sequenced_task_runner)
-    : file_stream_(sequenced_task_runner) {}
-
-LocalFileReader::~LocalFileReader() = default;
-
-void LocalFileReader::Open(const base::FilePath& file_path,
-                           int64_t offset,
-                           net::CompletionOnceCallback callback) {
-  DCHECK(!callback.is_null());
-  int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
-              base::File::FLAG_ASYNC;
-
-  int rv = file_stream_.Open(
-      file_path, flags,
-      BindOnce(&LocalFileReader::DidOpen, weak_ptr_factory_.GetWeakPtr(),
-               std::move(callback), offset));
-  DCHECK_EQ(rv, net::ERR_IO_PENDING);
-}
-
-void LocalFileReader::Read(net::IOBuffer* in_buffer,
-                           int buffer_length,
-                           net::CompletionOnceCallback callback) {
-  DCHECK(!callback.is_null());
-  DCHECK(file_stream_.IsOpen());
-  int rv = file_stream_.Read(in_buffer, buffer_length, std::move(callback));
-  DCHECK_EQ(rv, net::ERR_IO_PENDING);
-}
-
-void LocalFileReader::DidOpen(net::CompletionOnceCallback callback,
-                              int64_t offset,
-                              int error) {
-  if (error != net::OK)
-    return std::move(callback).Run(error);
-
-  int rv = file_stream_.Seek(offset, BindOnce(&LocalFileReader::DidSeek,
-                                              weak_ptr_factory_.GetWeakPtr(),
-                                              std::move(callback), offset));
-  DCHECK_EQ(rv, net::ERR_IO_PENDING);
-}
-
-void LocalFileReader::DidSeek(net::CompletionOnceCallback callback,
-                              int64_t offset,
-                              int64_t error) {
-  std::move(callback).Run(error == offset ? net::OK : net::ERR_FAILED);
-}
-
-}  // namespace util
-}  // namespace drive
diff --git a/components/drive/local_file_reader.h b/components/drive/local_file_reader.h
deleted file mode 100644
index 2fba1a7c6..0000000
--- a/components/drive/local_file_reader.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_LOCAL_FILE_READER_H_
-#define COMPONENTS_DRIVE_LOCAL_FILE_READER_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "net/base/completion_once_callback.h"
-#include "net/base/file_stream.h"
-
-namespace base {
-class FilePath;
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace net {
-class IOBuffer;
-}  // namespace net
-
-namespace drive {
-namespace util {
-
-// This is simple local file reader implementation focusing on Drive's use
-// case. All the operations run on |sequenced_task_runner| asynchronously and
-// the result will be notified to the caller via |callback|s on the caller's
-// thread.
-class LocalFileReader {
- public:
-  explicit LocalFileReader(base::SequencedTaskRunner* sequenced_task_runner);
-  ~LocalFileReader();
-
-  // Opens the file at |file_path|. The initial position of the read will be
-  // at |offset| from the beginning of the file.
-  // Upon completion, |callback| will be called.
-  // |callback| must not be null.
-  void Open(const base::FilePath& file_path,
-            int64_t offset,
-            net::CompletionOnceCallback callback);
-
-  // Reads the file and copies the data into |buffer|. |buffer_length|
-  // is the length of |buffer|.
-  // Upon completion, |callback| will be called with the result.
-  // |callback| must not be null.
-  void Read(net::IOBuffer* buffer,
-            int buffer_length,
-            net::CompletionOnceCallback callback);
-
- private:
-  void DidOpen(net::CompletionOnceCallback callback, int64_t offset, int error);
-  void DidSeek(net::CompletionOnceCallback callback,
-               int64_t offset,
-               int64_t error);
-
-  net::FileStream file_stream_;
-
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate the weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<LocalFileReader> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(LocalFileReader);
-};
-
-}  // namespace util
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_LOCAL_FILE_READER_H_
diff --git a/components/drive/local_file_reader_unittest.cc b/components/drive/local_file_reader_unittest.cc
deleted file mode 100644
index e3028811..0000000
--- a/components/drive/local_file_reader_unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/local_file_reader.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/ref_counted.h"
-#include "base/rand_util.h"
-#include "base/test/task_environment.h"
-#include "base/threading/thread.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "google_apis/drive/test_util.h"
-#include "net/base/io_buffer.h"
-#include "net/base/test_completion_callback.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace util {
-namespace {
-
-// An adapter to use test_util::ReadAllData.
-class LocalFileReaderAdapter {
- public:
-  explicit LocalFileReaderAdapter(LocalFileReader* reader) : reader_(reader) {}
-  int Read(net::IOBuffer* buffer,
-           int buffer_length,
-           net::CompletionOnceCallback callback) {
-    reader_->Read(buffer, buffer_length, std::move(callback));
-    // As LocalFileReader::Read always works asynchronously,
-    // return ERR_IO_PENDING.
-    return net::ERR_IO_PENDING;
-  }
-
- private:
-  LocalFileReader* reader_;
-};
-
-}  // namespace
-
-class LocalFileReaderTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    worker_thread_ = std::make_unique<base::Thread>("LocalFileReaderTest");
-    ASSERT_TRUE(worker_thread_->Start());
-    file_reader_ =
-        std::make_unique<LocalFileReader>(worker_thread_->task_runner().get());
-  }
-
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-  std::unique_ptr<base::Thread> worker_thread_;
-  std::unique_ptr<LocalFileReader> file_reader_;
-};
-
-TEST_F(LocalFileReaderTest, NonExistingFile) {
-  const base::FilePath kTestFile =
-      temp_dir_.GetPath().AppendASCII("non-existing");
-
-  net::TestCompletionCallback callback;
-  file_reader_->Open(kTestFile, 0, callback.callback());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback.WaitForResult());
-}
-
-TEST_F(LocalFileReaderTest, FullRead) {
-  base::FilePath test_file;
-  std::string expected_content;
-  ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize(
-      temp_dir_.GetPath(), 1024, &test_file, &expected_content));
-
-  net::TestCompletionCallback callback;
-  file_reader_->Open(test_file, 0, callback.callback());
-  ASSERT_EQ(net::OK, callback.WaitForResult());
-
-  LocalFileReaderAdapter adapter(file_reader_.get());
-  std::string content;
-  ASSERT_EQ(net::OK, test_util::ReadAllData(&adapter, &content));
-  EXPECT_EQ(expected_content, content);
-}
-
-TEST_F(LocalFileReaderTest, OpenWithOffset) {
-  base::FilePath test_file;
-  std::string expected_content;
-  ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize(
-      temp_dir_.GetPath(), 1024, &test_file, &expected_content));
-
-  size_t offset = expected_content.size() / 2;
-  expected_content.erase(0, offset);
-
-  net::TestCompletionCallback callback;
-  file_reader_->Open(test_file, static_cast<int64_t>(offset),
-                     callback.callback());
-  ASSERT_EQ(net::OK, callback.WaitForResult());
-
-  LocalFileReaderAdapter adapter(file_reader_.get());
-  std::string content;
-  ASSERT_EQ(net::OK, test_util::ReadAllData(&adapter, &content));
-  EXPECT_EQ(expected_content, content);
-}
-
-}  // namespace util
-}  // namespace drive
diff --git a/components/drive/remove_stale_cache_files_unittest.cc b/components/drive/remove_stale_cache_files_unittest.cc
deleted file mode 100644
index 3fed4df7..0000000
--- a/components/drive/remove_stale_cache_files_unittest.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/remove_stale_cache_files.h"
-
-#include <memory>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/chromeos/resource_metadata.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-#include "content/public/test/browser_task_environment.h"
-#include "google_apis/drive/test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-
-class RemoveStaleCacheFilesTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
-
-    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-
-    resource_metadata_.reset(new ResourceMetadata(
-        metadata_storage_.get(), cache_.get(),
-        base::ThreadTaskRunnerHandle::Get()));
-
-    ASSERT_TRUE(metadata_storage_->Initialize());
-    ASSERT_TRUE(cache_->Initialize());
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
-  }
-
-  content::BrowserTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
-      resource_metadata_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-};
-
-TEST_F(RemoveStaleCacheFilesTest, RemoveStaleCacheFiles) {
-  base::FilePath dummy_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &dummy_file));
-  std::string md5_metadata("abcdef0123456789"), md5_cache("ABCDEF9876543210");
-
-  // Create a stale cache file.
-  ResourceEntry entry;
-  std::string local_id;
-  entry.mutable_file_specific_info()->set_md5(md5_metadata);
-  entry.set_parent_local_id(util::kDriveGrandRootLocalId);
-  entry.set_title("File.txt");
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id));
-
-  EXPECT_EQ(FILE_ERROR_OK,
-            cache_->Store(local_id, md5_cache, dummy_file,
-                          FileCache::FILE_OPERATION_COPY));
-
-  // Remove stale cache files.
-  RemoveStaleCacheFiles(cache_.get(), resource_metadata_.get());
-
-  // Verify that the cache is deleted.
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(local_id, &entry));
-  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
-}
-
-TEST_F(RemoveStaleCacheFilesTest, DirtyCacheFiles) {
-  base::FilePath dummy_file;
-  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &dummy_file));
-
-  // Dirty entry.
-  std::string md5_metadata("abcdef0123456789");
-
-  ResourceEntry entry;
-  std::string local_id;
-  entry.mutable_file_specific_info()->set_md5(md5_metadata);
-  entry.set_parent_local_id(util::kDriveGrandRootLocalId);
-  entry.set_title("file.txt");
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id));
-
-  EXPECT_EQ(FILE_ERROR_OK,
-            cache_->Store(local_id, std::string(), dummy_file,
-                          FileCache::FILE_OPERATION_COPY));
-
-  // Remove stale cache files.
-  RemoveStaleCacheFiles(cache_.get(), resource_metadata_.get());
-
-  // Dirty cache should not be removed even though its MD5 doesn't match.
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(local_id, &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/resource_entry_conversion.cc b/components/drive/resource_entry_conversion.cc
deleted file mode 100644
index 2c7f2b9..0000000
--- a/components/drive/resource_entry_conversion.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/resource_entry_conversion.h"
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/logging.h"
-#include "base/time/time.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_api_util.h"
-#include "components/drive/file_system_core_util.h"
-#include "google_apis/drive/drive_api_parser.h"
-
-namespace drive {
-
-void ConvertChangeResourceToResourceEntry(
-    const google_apis::ChangeResource& input,
-    ResourceEntry* out_entry,
-    std::string* out_parent_resource_id) {
-  DCHECK(out_entry);
-  DCHECK(out_parent_resource_id);
-
-  out_entry->Clear();
-  out_parent_resource_id->clear();
-
-  if (input.type() == google_apis::ChangeResource::TEAM_DRIVE) {
-    if (input.team_drive()) {
-      ConvertTeamDriveResourceToResourceEntry(*input.team_drive(), out_entry);
-    } else {
-      // resource_id is same as the Team Drive ID.
-      // Both team_drive_id() and team_drive().id() holds the same ID, but the
-      // latter doesn't exist for deleted items.
-      out_entry->set_resource_id(input.team_drive_id());
-      out_entry->mutable_file_info()->set_is_directory(true);
-      out_entry->mutable_file_info()->set_is_team_drive_root(true);
-      out_entry->set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-    }
-  } else {
-    if (input.file()) {
-      ConvertFileResourceToResourceEntry(*input.file(), out_entry,
-                                         out_parent_resource_id);
-    }
-    out_entry->set_resource_id(input.file_id());
-  }
-  out_entry->set_deleted(out_entry->deleted() || input.is_deleted());
-  out_entry->set_modification_date(input.modification_date().ToInternalValue());
-}
-
-void ConvertFileResourceToResourceEntry(const google_apis::FileResource& input,
-                                        ResourceEntry* out_entry,
-                                        std::string* out_parent_resource_id) {
-  DCHECK(out_entry);
-  DCHECK(out_parent_resource_id);
-
-  out_entry->Clear();
-  out_parent_resource_id->clear();
-
-  // For regular files, the 'filename' and 'title' attribute in the metadata
-  // may be different (e.g. due to rename). To be consistent with the web
-  // interface and other client to use the 'title' attribute, instead of
-  // 'filename', as the file name in the local snapshot.
-  out_entry->set_title(input.title());
-  out_entry->set_base_name(util::NormalizeFileName(out_entry->title()));
-  out_entry->set_resource_id(input.file_id());
-
-  // Gets parent Resource ID. On drive.google.com, a file can have multiple
-  // parents or no parent, but we are forcing a tree-shaped structure (i.e. no
-  // multi-parent or zero-parent entries). Therefore the first found "parent" is
-  // used for the entry. Tracked in http://crbug.com/158904.
-  if (!input.parents().empty())
-    out_parent_resource_id->assign(input.parents()[0].file_id());
-
-  out_entry->set_deleted(input.labels().is_trashed());
-  out_entry->set_starred(input.labels().is_starred());
-  out_entry->set_shared_with_me(!input.shared_with_me_date().is_null());
-  out_entry->set_shared(input.shared());
-  if (!input.alternate_link().is_empty())
-    out_entry->set_alternate_url(input.alternate_link().spec());
-
-  PlatformFileInfoProto* file_info = out_entry->mutable_file_info();
-
-  file_info->set_last_modified(input.modified_date().ToInternalValue());
-  out_entry->set_last_modified_by_me(
-      input.modified_by_me_date().ToInternalValue());
-  // If the file has never been viewed (last_viewed_by_me_date().is_null() ==
-  // true), then we will set the last_accessed field in the protocol buffer to
-  // 0.
-  file_info->set_last_accessed(
-      input.last_viewed_by_me_date().ToInternalValue());
-  file_info->set_creation_time(input.created_date().ToInternalValue());
-
-  // Set the capabilities.
-  const google_apis::FileResourceCapabilities& capabilities =
-      input.capabilities();
-  out_entry->mutable_capabilities_info()->set_can_copy(capabilities.can_copy());
-  out_entry->mutable_capabilities_info()->set_can_delete(
-      capabilities.can_delete());
-  out_entry->mutable_capabilities_info()->set_can_rename(
-      capabilities.can_rename());
-  out_entry->mutable_capabilities_info()->set_can_add_children(
-      capabilities.can_add_children());
-  out_entry->mutable_capabilities_info()->set_can_share(
-      capabilities.can_share());
-
-  if (input.IsDirectory()) {
-    file_info->set_is_directory(true);
-  } else {
-    FileSpecificInfo* file_specific_info =
-        out_entry->mutable_file_specific_info();
-    if (!input.IsHostedDocument()) {
-      file_info->set_size(input.file_size());
-      file_specific_info->set_md5(input.md5_checksum());
-      file_specific_info->set_is_hosted_document(false);
-    } else {
-      // Attach .g<something> extension to hosted documents so we can special
-      // case their handling in UI.
-      // TODO(satorux): Figure out better way how to pass input info like kind
-      // to UI through the File API stack.
-      const std::string document_extension =
-          drive::util::GetHostedDocumentExtension(input.mime_type());
-      file_specific_info->set_document_extension(document_extension);
-      out_entry->set_base_name(
-          util::NormalizeFileName(out_entry->title() + document_extension));
-
-      // We don't know the size of hosted docs and it does not matter since
-      // it has no effect on the quota.
-      file_info->set_size(0);
-      file_specific_info->set_is_hosted_document(true);
-    }
-    file_info->set_is_directory(false);
-    file_specific_info->set_content_mime_type(input.mime_type());
-
-    const int64_t image_width = input.image_media_metadata().width();
-    if (image_width != -1)
-      file_specific_info->set_image_width(image_width);
-
-    const int64_t image_height = input.image_media_metadata().height();
-    if (image_height != -1)
-      file_specific_info->set_image_height(image_height);
-
-    const int64_t image_rotation = input.image_media_metadata().rotation();
-    if (image_rotation != -1)
-      file_specific_info->set_image_rotation(image_rotation);
-  }
-}
-
-void ConvertTeamDriveResourceToResourceEntry(
-    const google_apis::TeamDriveResource& input,
-    ResourceEntry* out_entry) {
-  DCHECK(out_entry);
-  out_entry->mutable_file_info()->set_is_directory(true);
-  out_entry->mutable_file_info()->set_is_team_drive_root(true);
-  out_entry->set_title(input.name());
-  out_entry->set_base_name(input.name());
-  out_entry->set_resource_id(input.id());
-  out_entry->set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-
-  // Set all the capabilities.
-  const google_apis::TeamDriveCapabilities& capabilities = input.capabilities();
-  out_entry->mutable_capabilities_info()->set_can_copy(capabilities.can_copy());
-  out_entry->mutable_capabilities_info()->set_can_delete(
-      capabilities.can_delete_team_drive());
-  out_entry->mutable_capabilities_info()->set_can_rename(
-      capabilities.can_rename_team_drive());
-  out_entry->mutable_capabilities_info()->set_can_add_children(
-      capabilities.can_add_children());
-  out_entry->mutable_capabilities_info()->set_can_share(
-      capabilities.can_share());
-}
-
-void ConvertResourceEntryToFileInfo(const ResourceEntry& entry,
-                                    base::File::Info* file_info) {
-  file_info->size = entry.file_info().size();
-  file_info->is_directory = entry.file_info().is_directory();
-  file_info->is_symbolic_link = entry.file_info().is_symbolic_link();
-  file_info->last_modified = base::Time::FromInternalValue(
-      entry.file_info().last_modified());
-  file_info->last_accessed = base::Time::FromInternalValue(
-      entry.file_info().last_accessed());
-  file_info->creation_time = base::Time::FromInternalValue(
-      entry.file_info().creation_time());
-}
-
-}  // namespace drive
diff --git a/components/drive/resource_entry_conversion.h b/components/drive/resource_entry_conversion.h
deleted file mode 100644
index ac1cd47d..0000000
--- a/components/drive/resource_entry_conversion.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_
-#define COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_
-
-#include <string>
-
-#include "base/files/file.h"
-
-namespace google_apis {
-class ChangeResource;
-class FileResource;
-class TeamDriveResource;
-}
-
-namespace drive {
-
-class ResourceEntry;
-
-// Converts a google_apis::ChangeResource into a drive::ResourceEntry.
-// The converted result will be stored in |out_entry| and
-// |out_parent_resource_id| will be set to the resource ID of the parent entry.
-//
-// Every entry is guaranteed to have one parent resource ID in ResourceMetadata.
-// This requirement is needed to represent contents in Drive as a file system
-// tree, and achieved as follows:
-//
-// 1) Entries without parents are allowed on drive.google.com. These entries are
-// collected to "drive/other", and have "drive/other" as the parent.
-//
-// 2) Entries with multiple parents are allowed on drive.google.com. For these
-// entries, the first parent is chosen.
-void ConvertChangeResourceToResourceEntry(
-    const google_apis::ChangeResource& input,
-    ResourceEntry* out_entry,
-    std::string* out_parent_resource_id);
-
-// Converts a google_apis::FileResource into a drive::ResourceEntry.
-// Also see the comment for ConvertChangeResourceToResourceEntry above.
-void ConvertFileResourceToResourceEntry(const google_apis::FileResource& input,
-                                        ResourceEntry* out_entry,
-                                        std::string* out_parent_resource_id);
-
-// Converts a TeamDriveResource into a drive::ResourceEntry.
-void ConvertTeamDriveResourceToResourceEntry(
-    const google_apis::TeamDriveResource& input,
-    ResourceEntry* out_entry);
-
-// Converts the resource entry to the platform file info.
-void ConvertResourceEntryToFileInfo(const ResourceEntry& entry,
-                                    base::File::Info* file_info);
-
-}  // namespace drive
-
-#endif  // COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_
diff --git a/components/drive/resource_entry_conversion_unittest.cc b/components/drive/resource_entry_conversion_unittest.cc
deleted file mode 100644
index 7ca0eba..0000000
--- a/components/drive/resource_entry_conversion_unittest.cc
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/resource_entry_conversion.h"
-
-#include <memory>
-
-#include "base/time/time.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/drive_api_util.h"
-#include "components/drive/file_system_core_util.h"
-#include "google_apis/drive/drive_api_parser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-
-namespace {
-
-base::Time GetTestTime() {
-  // 2011-12-14-T00:40:47.330Z
-  base::Time::Exploded exploded;
-  exploded.year = 2011;
-  exploded.month = 12;
-  exploded.day_of_month = 14;
-  exploded.day_of_week = 2;  // Tuesday
-  exploded.hour = 0;
-  exploded.minute = 40;
-  exploded.second = 47;
-  exploded.millisecond = 330;
-  base::Time out_time;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  return out_time;
-}
-
-}  // namespace
-
-TEST(ResourceEntryConversionTest, ConvertToResourceEntry_File) {
-  google_apis::FileResource file_resource;
-  file_resource.set_title("File 1.mp3");
-  file_resource.set_file_id("resource_id");
-  file_resource.set_created_date(GetTestTime());
-  file_resource.set_modified_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(10));
-  file_resource.set_modified_by_me_date(GetTestTime() +
-                                        base::TimeDelta::FromSeconds(5));
-  file_resource.set_mime_type("audio/mpeg");
-  file_resource.set_alternate_link(GURL("https://file_link_alternate"));
-  file_resource.set_file_size(892721);
-  file_resource.set_md5_checksum("3b4382ebefec6e743578c76bbd0575ce");
-
-  google_apis::FileResourceCapabilities capabilities;
-  capabilities.set_can_copy(true);
-  capabilities.set_can_delete(false);
-  capabilities.set_can_rename(true);
-  capabilities.set_can_add_children(false);
-  capabilities.set_can_share(true);
-  file_resource.set_capabilities(capabilities);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-
-  EXPECT_EQ(file_resource.title(), entry.title());
-  EXPECT_EQ(file_resource.title(), entry.base_name());
-  EXPECT_EQ(file_resource.file_id(), entry.resource_id());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_FALSE(entry.deleted());
-  EXPECT_FALSE(entry.starred());
-  EXPECT_FALSE(entry.shared_with_me());
-  EXPECT_FALSE(entry.shared());
-
-  EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
-            entry.file_info().last_modified());
-  EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
-            entry.last_modified_by_me());
-  // Last accessed value equal to 0 means that the file has never been viewed.
-  EXPECT_EQ(0, entry.file_info().last_accessed());
-  EXPECT_EQ(file_resource.created_date().ToInternalValue(),
-            entry.file_info().creation_time());
-  EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url());
-
-  EXPECT_EQ(file_resource.mime_type(),
-            entry.file_specific_info().content_mime_type());
-  EXPECT_FALSE(entry.file_specific_info().is_hosted_document());
-
-  // Regular file specific fields.
-  EXPECT_EQ(file_resource.file_size(), entry.file_info().size());
-  EXPECT_EQ(file_resource.md5_checksum(), entry.file_specific_info().md5());
-  EXPECT_FALSE(entry.file_info().is_directory());
-
-  // Capabilities.
-  EXPECT_TRUE(entry.capabilities_info().can_copy());
-  EXPECT_FALSE(entry.capabilities_info().can_delete());
-  EXPECT_TRUE(entry.capabilities_info().can_rename());
-  EXPECT_FALSE(entry.capabilities_info().can_add_children());
-  EXPECT_TRUE(entry.capabilities_info().can_share());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_HostedDocument) {
-  google_apis::FileResource file_resource;
-  file_resource.set_title("Document 1");
-  file_resource.set_file_id("resource_id");
-  file_resource.set_created_date(GetTestTime());
-  file_resource.set_modified_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(10));
-  file_resource.set_modified_by_me_date(GetTestTime() +
-                                        base::TimeDelta::FromSeconds(5));
-  file_resource.set_last_viewed_by_me_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(20));
-  file_resource.set_mime_type(util::kGoogleDocumentMimeType);
-  file_resource.set_alternate_link(GURL("https://file_link_alternate"));
-  // Do not set file size to represent a hosted document.
-
-  google_apis::FileResourceCapabilities capabilities;
-  capabilities.set_can_copy(false);
-  capabilities.set_can_delete(true);
-  capabilities.set_can_rename(false);
-  capabilities.set_can_add_children(true);
-  capabilities.set_can_share(false);
-  file_resource.set_capabilities(capabilities);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-
-  EXPECT_EQ(file_resource.title(), entry.title());
-  EXPECT_EQ(file_resource.title() + ".gdoc",
-            entry.base_name());  // The suffix added.
-  EXPECT_EQ(".gdoc", entry.file_specific_info().document_extension());
-  EXPECT_EQ(file_resource.file_id(), entry.resource_id());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_FALSE(entry.deleted());
-  EXPECT_FALSE(entry.starred());
-  EXPECT_FALSE(entry.shared_with_me());
-  EXPECT_FALSE(entry.shared());
-
-  EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
-            entry.file_info().last_modified());
-  EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
-            entry.last_modified_by_me());
-  EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
-            entry.file_info().last_accessed());
-  EXPECT_EQ(file_resource.created_date().ToInternalValue(),
-            entry.file_info().creation_time());
-  EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url());
-
-  EXPECT_EQ(file_resource.mime_type(),
-            entry.file_specific_info().content_mime_type());
-  EXPECT_TRUE(entry.file_specific_info().is_hosted_document());
-
-  // The size should be 0 for a hosted document.
-  EXPECT_EQ(0, entry.file_info().size());
-  EXPECT_FALSE(entry.file_info().is_directory());
-
-  // Capabilities.
-  EXPECT_FALSE(entry.capabilities_info().can_copy());
-  EXPECT_TRUE(entry.capabilities_info().can_delete());
-  EXPECT_FALSE(entry.capabilities_info().can_rename());
-  EXPECT_TRUE(entry.capabilities_info().can_add_children());
-  EXPECT_FALSE(entry.capabilities_info().can_share());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_Directory) {
-  google_apis::FileResource file_resource;
-  file_resource.set_title("Folder");
-  file_resource.set_file_id("resource_id");
-  file_resource.set_created_date(GetTestTime());
-  file_resource.set_modified_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(10));
-  file_resource.set_modified_by_me_date(GetTestTime() +
-                                        base::TimeDelta::FromSeconds(5));
-  file_resource.set_last_viewed_by_me_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(20));
-  file_resource.set_mime_type(util::kDriveFolderMimeType);
-
-  google_apis::ParentReference parent;
-  parent.set_file_id("parent_resource_id");
-  file_resource.mutable_parents()->push_back(parent);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-
-  EXPECT_EQ(file_resource.title(), entry.title());
-  EXPECT_EQ(file_resource.title(), entry.base_name());
-  EXPECT_EQ(file_resource.file_id(), entry.resource_id());
-  EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url());
-  // The parent resource ID should be obtained as this is a sub directory
-  // under a non-root directory.
-  EXPECT_EQ(parent.file_id(), parent_resource_id);
-
-  EXPECT_FALSE(entry.deleted());
-  EXPECT_FALSE(entry.starred());
-  EXPECT_FALSE(entry.shared_with_me());
-  EXPECT_FALSE(entry.shared());
-
-  EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
-            entry.file_info().last_modified());
-  EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
-            entry.last_modified_by_me());
-  EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
-            entry.file_info().last_accessed());
-  EXPECT_EQ(file_resource.created_date().ToInternalValue(),
-            entry.file_info().creation_time());
-
-  EXPECT_TRUE(entry.file_info().is_directory());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_DeletedHostedDocument) {
-  google_apis::FileResource file_resource;
-  file_resource.set_title("Document 1");
-  file_resource.set_file_id("resource_id");
-  file_resource.set_created_date(GetTestTime());
-  file_resource.set_modified_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(10));
-  file_resource.set_modified_by_me_date(GetTestTime() +
-                                        base::TimeDelta::FromSeconds(5));
-  file_resource.set_last_viewed_by_me_date(
-      GetTestTime() + base::TimeDelta::FromSeconds(20));
-  file_resource.set_mime_type(util::kGoogleDocumentMimeType);
-  file_resource.set_alternate_link(GURL("https://file_link_alternate"));
-  file_resource.mutable_labels()->set_trashed(true);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-
-  EXPECT_EQ(file_resource.title(), entry.title());
-  EXPECT_EQ(file_resource.title() + ".gdoc", entry.base_name());
-  EXPECT_EQ(file_resource.file_id(), entry.resource_id());
-  EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_TRUE(entry.deleted());  // The document was deleted.
-  EXPECT_FALSE(entry.starred());
-  EXPECT_FALSE(entry.shared_with_me());
-  EXPECT_FALSE(entry.shared());
-
-  EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
-            entry.file_info().last_modified());
-  EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
-            entry.last_modified_by_me());
-  EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
-            entry.file_info().last_accessed());
-  EXPECT_EQ(file_resource.created_date().ToInternalValue(),
-            entry.file_info().creation_time());
-
-  EXPECT_EQ(file_resource.mime_type(),
-            entry.file_specific_info().content_mime_type());
-  EXPECT_TRUE(entry.file_specific_info().is_hosted_document());
-
-  // The size should be 0 for a hosted document.
-  EXPECT_EQ(0, entry.file_info().size());
-}
-
-TEST(ResourceEntryConversionTest, ConvertChangeResourceToResourceEntry) {
-  google_apis::ChangeResource change_resource;
-  change_resource.set_type(google_apis::ChangeResource::FILE);
-  change_resource.set_file(std::make_unique<google_apis::FileResource>());
-  change_resource.set_file_id("resource_id");
-  change_resource.set_modification_date(GetTestTime());
-
-  google_apis::FileResource* file_resource = change_resource.mutable_file();
-  file_resource->set_title("File 1.mp3");
-  file_resource->set_file_id("resource_id");
-  // Set dummy file size to declare that this is a regular file.
-  file_resource->set_file_size(12345);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertChangeResourceToResourceEntry(change_resource, &entry,
-                                       &parent_resource_id);
-
-  EXPECT_EQ(change_resource.file_id(), entry.resource_id());
-  EXPECT_EQ(change_resource.modification_date().ToInternalValue(),
-            entry.modification_date());
-
-  EXPECT_EQ(file_resource->title(), entry.title());
-  EXPECT_EQ(file_resource->title(), entry.base_name());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_FALSE(entry.deleted());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertChangeResourceToResourceEntry_Trashed) {
-  google_apis::ChangeResource change_resource;
-  change_resource.set_type(google_apis::ChangeResource::FILE);
-  change_resource.set_file(std::make_unique<google_apis::FileResource>());
-  change_resource.set_file_id("resource_id");
-  change_resource.set_modification_date(GetTestTime());
-
-  google_apis::FileResource* file_resource = change_resource.mutable_file();
-  file_resource->set_title("File 1.mp3");
-  file_resource->set_file_id("resource_id");
-  // Set dummy file size to declare that this is a regular file.
-  file_resource->set_file_size(12345);
-  file_resource->mutable_labels()->set_trashed(true);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertChangeResourceToResourceEntry(change_resource, &entry,
-                                       &parent_resource_id);
-
-  EXPECT_EQ(change_resource.file_id(), entry.resource_id());
-  EXPECT_EQ(change_resource.modification_date().ToInternalValue(),
-            entry.modification_date());
-
-  EXPECT_EQ(file_resource->title(), entry.title());
-  EXPECT_EQ(file_resource->title(), entry.base_name());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_TRUE(entry.deleted());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertChangeResourceToResourceEntry_Deleted) {
-  google_apis::ChangeResource change_resource;
-  change_resource.set_type(google_apis::ChangeResource::FILE);
-  change_resource.set_deleted(true);
-  change_resource.set_file_id("resource_id");
-  change_resource.set_modification_date(GetTestTime());
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertChangeResourceToResourceEntry(change_resource, &entry,
-                                       &parent_resource_id);
-
-  EXPECT_EQ(change_resource.file_id(), entry.resource_id());
-  EXPECT_EQ("", parent_resource_id);
-
-  EXPECT_TRUE(entry.deleted());
-
-  EXPECT_EQ(change_resource.modification_date().ToInternalValue(),
-            entry.modification_date());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_StarredEntry) {
-  google_apis::FileResource file_resource;
-  file_resource.mutable_labels()->set_starred(true);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-  EXPECT_TRUE(entry.starred());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_SharedWithMeEntry) {
-  google_apis::FileResource file_resource;
-  file_resource.set_shared(true);
-  file_resource.set_shared_with_me_date(GetTestTime());
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertFileResourceToResourceEntry(file_resource, &entry,
-                                     &parent_resource_id);
-  EXPECT_TRUE(entry.shared_with_me());
-  EXPECT_TRUE(entry.shared());
-}
-
-TEST(ResourceEntryConversionTest, ToPlatformFileInfo) {
-  ResourceEntry entry;
-  entry.mutable_file_info()->set_size(12345);
-  entry.mutable_file_info()->set_is_directory(true);
-  entry.mutable_file_info()->set_is_symbolic_link(true);
-  entry.mutable_file_info()->set_creation_time(999);
-  entry.mutable_file_info()->set_last_modified(123456789);
-  entry.mutable_file_info()->set_last_accessed(987654321);
-
-  base::File::Info file_info;
-  ConvertResourceEntryToFileInfo(entry, &file_info);
-  EXPECT_EQ(entry.file_info().size(), file_info.size);
-  EXPECT_EQ(entry.file_info().is_directory(), file_info.is_directory);
-  EXPECT_EQ(entry.file_info().is_symbolic_link(), file_info.is_symbolic_link);
-  EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().creation_time()),
-            file_info.creation_time);
-  EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().last_modified()),
-            file_info.last_modified);
-  EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().last_accessed()),
-            file_info.last_accessed);
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertFileResourceToResourceEntry_ImageMediaMetadata) {
-  google_apis::FileResource entry_all_fields;
-  google_apis::FileResource entry_zero_fields;
-  google_apis::FileResource entry_no_fields;
-
-  entry_all_fields.mutable_image_media_metadata()->set_width(640);
-  entry_all_fields.mutable_image_media_metadata()->set_height(480);
-  entry_all_fields.mutable_image_media_metadata()->set_rotation(90);
-
-  entry_zero_fields.mutable_image_media_metadata()->set_width(0);
-  entry_zero_fields.mutable_image_media_metadata()->set_height(0);
-  entry_zero_fields.mutable_image_media_metadata()->set_rotation(0);
-
-  {
-    ResourceEntry entry;
-    std::string parent_resource_id;
-    ConvertFileResourceToResourceEntry(entry_all_fields, &entry,
-                                       &parent_resource_id);
-    EXPECT_EQ(640, entry.file_specific_info().image_width());
-    EXPECT_EQ(480, entry.file_specific_info().image_height());
-    EXPECT_EQ(90, entry.file_specific_info().image_rotation());
-  }
-  {
-    ResourceEntry entry;
-    std::string parent_resource_id;
-    ConvertFileResourceToResourceEntry(entry_zero_fields, &entry,
-                                       &parent_resource_id);
-    EXPECT_TRUE(entry.file_specific_info().has_image_width());
-    EXPECT_TRUE(entry.file_specific_info().has_image_height());
-    EXPECT_TRUE(entry.file_specific_info().has_image_rotation());
-    EXPECT_EQ(0, entry.file_specific_info().image_width());
-    EXPECT_EQ(0, entry.file_specific_info().image_height());
-    EXPECT_EQ(0, entry.file_specific_info().image_rotation());
-  }
-  {
-    ResourceEntry entry;
-    std::string parent_resource_id;
-    ConvertFileResourceToResourceEntry(entry_no_fields, &entry,
-                                       &parent_resource_id);
-    EXPECT_FALSE(entry.file_specific_info().has_image_width());
-    EXPECT_FALSE(entry.file_specific_info().has_image_height());
-    EXPECT_FALSE(entry.file_specific_info().has_image_rotation());
-  }
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertTeamDriveChangeResourceToResourceEntry) {
-  google_apis::ChangeResource change_resource;
-  change_resource.set_type(google_apis::ChangeResource::TEAM_DRIVE);
-  change_resource.set_team_drive(
-      std::make_unique<google_apis::TeamDriveResource>());
-  change_resource.set_team_drive_id("team_drive_id");
-  change_resource.set_modification_date(GetTestTime());
-  change_resource.set_deleted(false);
-
-  google_apis::TeamDriveResource* team_drive_resource =
-      change_resource.mutable_team_drive();
-  team_drive_resource->set_name("ABC Team Drive");
-  team_drive_resource->set_id("team_drive_id");
-
-  google_apis::TeamDriveCapabilities team_drive_capabilities;
-  team_drive_capabilities.set_can_copy(true);
-  team_drive_capabilities.set_can_delete_team_drive(false);
-  team_drive_capabilities.set_can_rename_team_drive(true);
-  // Can_rename is ignored for team drives.
-  team_drive_capabilities.set_can_rename(false);
-  team_drive_capabilities.set_can_add_children(false);
-  team_drive_capabilities.set_can_share(true);
-  team_drive_resource->set_capabilities(team_drive_capabilities);
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertChangeResourceToResourceEntry(change_resource, &entry,
-                                       &parent_resource_id);
-
-  EXPECT_EQ(change_resource.team_drive_id(), entry.resource_id());
-  EXPECT_EQ(team_drive_resource->name(), entry.title());
-  EXPECT_EQ(team_drive_resource->name(), entry.base_name());
-  EXPECT_EQ(change_resource.modification_date().ToInternalValue(),
-            entry.modification_date());
-  EXPECT_TRUE(entry.file_info().is_directory());
-  EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id());
-  EXPECT_EQ("", parent_resource_id);
-  EXPECT_FALSE(entry.deleted());
-
-  EXPECT_TRUE(entry.capabilities_info().can_copy());
-  EXPECT_FALSE(entry.capabilities_info().can_delete());
-  EXPECT_TRUE(entry.capabilities_info().can_rename());
-  EXPECT_FALSE(entry.capabilities_info().can_add_children());
-  EXPECT_TRUE(entry.capabilities_info().can_share());
-}
-
-TEST(ResourceEntryConversionTest, ConvertTeamDriveResourceToResourceEntry) {
-  google_apis::TeamDriveResource team_drive_resource;
-  team_drive_resource.set_name("ABC Team Drive");
-  team_drive_resource.set_id("team_drive_id");
-
-  ResourceEntry entry;
-  ConvertTeamDriveResourceToResourceEntry(team_drive_resource, &entry);
-
-  EXPECT_EQ(team_drive_resource.id(), entry.resource_id());
-  EXPECT_EQ(team_drive_resource.name(), entry.title());
-  EXPECT_EQ(team_drive_resource.name(), entry.base_name());
-  EXPECT_TRUE(entry.file_info().is_directory());
-  EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id());
-}
-
-TEST(ResourceEntryConversionTest,
-     ConvertTeamDriveRemovalChangeResourceToResourceEntry) {
-  google_apis::ChangeResource change_resource;
-  change_resource.set_type(google_apis::ChangeResource::TEAM_DRIVE);
-  change_resource.set_team_drive_id("team_drive_id");
-  change_resource.set_modification_date(GetTestTime());
-  change_resource.set_deleted(true);
-  // team_drive field is not filled for a deleted change resource.
-
-  ResourceEntry entry;
-  std::string parent_resource_id;
-  ConvertChangeResourceToResourceEntry(change_resource, &entry,
-                                       &parent_resource_id);
-
-  EXPECT_EQ(change_resource.team_drive_id(), entry.resource_id());
-  EXPECT_EQ(change_resource.modification_date().ToInternalValue(),
-            entry.modification_date());
-  EXPECT_TRUE(entry.file_info().is_directory());
-  EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id());
-  EXPECT_EQ("", parent_resource_id);
-  EXPECT_TRUE(entry.deleted());
-}
-
-}  // namespace drive
diff --git a/components/drive/resource_metadata_storage_unittest.cc b/components/drive/resource_metadata_storage_unittest.cc
index f304599f..c759a3b8 100644
--- a/components/drive/resource_metadata_storage_unittest.cc
+++ b/components/drive/resource_metadata_storage_unittest.cc
@@ -16,10 +16,10 @@
 #include "base/stl_util.h"
 #include "base/strings/string_split.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_test_util.h"
 #include "components/drive/drive.pb.h"
 #include "components/drive/file_system_core_util.h"
 #include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
@@ -27,6 +27,23 @@
 namespace drive {
 namespace internal {
 
+namespace {
+
+// Helper to destroy objects which needs Destroy() to be called on destruction.
+// Note: When using this helper, you should destruct objects before
+// BrowserThread.
+struct DestroyHelperForTests {
+  template <typename T>
+  void operator()(T* object) const {
+    if (object) {
+      object->Destroy();
+      content::RunAllTasksUntilIdle();  // Finish destruction.
+    }
+  }
+};
+
+}  // namespace
+
 class ResourceMetadataStorageTest : public testing::Test {
  protected:
   ResourceMetadataStorageTest() = default;
@@ -78,8 +95,7 @@
 
   content::BrowserTaskEnvironment task_environment_;
   base::ScopedTempDir temp_dir_;
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      storage_;
+  std::unique_ptr<ResourceMetadataStorage, DestroyHelperForTests> storage_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceMetadataStorageTest);
 };
diff --git a/components/drive/resource_metadata_unittest.cc b/components/drive/resource_metadata_unittest.cc
deleted file mode 100644
index fdc2051..0000000
--- a/components/drive/resource_metadata_unittest.cc
+++ /dev/null
@@ -1,724 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/drive/chromeos/resource_metadata.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/drive.pb.h"
-#include "components/drive/file_system_core_util.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-// The start page token of the resource metadata used in ResourceMetadataTest.
-constexpr char kTestStartPageToken[] = "a token";
-
-// Returns the sorted base names from |entries|.
-std::vector<std::string> GetSortedBaseNames(
-    const ResourceEntryVector& entries) {
-  std::vector<std::string> base_names;
-  for (size_t i = 0; i < entries.size(); ++i)
-    base_names.push_back(entries[i].base_name());
-  std::sort(base_names.begin(), base_names.end());
-
-  return base_names;
-}
-
-// Creates a ResourceEntry for a directory with explicitly set resource_id.
-ResourceEntry CreateDirectoryEntryWithResourceId(
-    const std::string& title,
-    const std::string& resource_id,
-    const std::string& parent_local_id) {
-  ResourceEntry entry;
-  entry.set_title(title);
-  entry.set_resource_id(resource_id);
-  entry.set_parent_local_id(parent_local_id);
-  entry.mutable_file_info()->set_is_directory(true);
-  entry.mutable_directory_specific_info()->set_start_page_token(
-      kTestStartPageToken);
-  return entry;
-}
-
-// Creates a ResourceEntry for a directory.
-ResourceEntry CreateDirectoryEntry(const std::string& title,
-                                   const std::string& parent_local_id) {
-  return CreateDirectoryEntryWithResourceId(
-      title, "id:" + title, parent_local_id);
-}
-
-// Creates a ResourceEntry for a file with explicitly set resource_id.
-ResourceEntry CreateFileEntryWithResourceId(
-    const std::string& title,
-    const std::string& resource_id,
-    const std::string& parent_local_id) {
-  ResourceEntry entry;
-  entry.set_title(title);
-  entry.set_resource_id(resource_id);
-  entry.set_parent_local_id(parent_local_id);
-  entry.mutable_file_info()->set_is_directory(false);
-  entry.mutable_file_info()->set_size(1024);
-  entry.mutable_file_specific_info()->set_md5("md5:" + title);
-  return entry;
-}
-
-// Creates a ResourceEntry for a file.
-ResourceEntry CreateFileEntry(const std::string& title,
-                              const std::string& parent_local_id) {
-  return CreateFileEntryWithResourceId(title, "id:" + title, parent_local_id);
-}
-
-// Creates the following files/directories
-// drive/root/dir1/
-// drive/root/dir2/
-// drive/root/dir1/dir3/
-// drive/root/dir1/file4
-// drive/root/dir1/file5
-// drive/root/dir2/file6
-// drive/root/dir2/file7
-// drive/root/dir2/file8
-// drive/root/dir1/dir3/file9
-// drive/root/dir1/dir3/file10
-void SetUpEntries(ResourceMetadata* resource_metadata) {
-  std::string local_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath(
-      util::GetDriveMyDriveRootPath(), &local_id));
-  const std::string root_local_id = local_id;
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateDirectoryEntry("dir1", root_local_id), &local_id));
-  const std::string local_id_dir1 = local_id;
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateDirectoryEntry("dir2", root_local_id), &local_id));
-  const std::string local_id_dir2 = local_id;
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateDirectoryEntry("dir3", local_id_dir1), &local_id));
-  const std::string local_id_dir3 = local_id;
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file4", local_id_dir1), &local_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file5", local_id_dir1), &local_id));
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file6", local_id_dir2), &local_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file7", local_id_dir2), &local_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file8", local_id_dir2), &local_id));
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file9", local_id_dir3), &local_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
-      CreateFileEntry("file10", local_id_dir3), &local_id));
-
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata->SetStartPageToken(kTestStartPageToken));
-}
-
-}  // namespace
-
-// Tests for methods running on the blocking task runner.
-class ResourceMetadataTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_TRUE(metadata_storage_->Initialize());
-
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-    ASSERT_TRUE(cache_->Initialize());
-
-    resource_metadata_.reset(new ResourceMetadata(
-        metadata_storage_.get(), cache_.get(),
-        base::ThreadTaskRunnerHandle::Get()));
-
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
-
-    SetUpEntries(resource_metadata_.get());
-  }
-
-  base::ScopedTempDir temp_dir_;
-  content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
-      resource_metadata_;
-};
-
-TEST_F(ResourceMetadataTest, StartPageToken) {
-  constexpr char kStartPageToken[] = "1234567";
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->SetStartPageToken(kStartPageToken));
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_EQ(kStartPageToken, start_page_token);
-}
-
-TEST_F(ResourceMetadataTest, GetResourceEntryByPath) {
-  // Confirm that an existing file is found.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
-  EXPECT_EQ("file4", entry.base_name());
-
-  // Confirm that a non existing file is not found.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"), &entry));
-
-  // Confirm that the root is found.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive"), &entry));
-
-  // Confirm that a non existing file is not found at the root level.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("non_existing"), &entry));
-
-  // Confirm that an entry is not found with a wrong root.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("non_existing/root"), &entry));
-}
-
-TEST_F(ResourceMetadataTest, ReadDirectoryByPath) {
-  // Confirm that an existing directory is found.
-  ResourceEntryVector entries;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->ReadDirectoryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entries));
-  ASSERT_EQ(3U, entries.size());
-  // The order is not guaranteed so we should sort the base names.
-  std::vector<std::string> base_names = GetSortedBaseNames(entries);
-  EXPECT_EQ("dir3", base_names[0]);
-  EXPECT_EQ("file4", base_names[1]);
-  EXPECT_EQ("file5", base_names[2]);
-
-  // Confirm that a non existing directory is not found.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->ReadDirectoryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/non_existing"), &entries));
-
-  // Confirm that reading a file results in FILE_ERROR_NOT_A_DIRECTORY.
-  EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, resource_metadata_->ReadDirectoryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entries));
-}
-
-TEST_F(ResourceMetadataTest, RefreshEntry) {
-  base::FilePath drive_file_path;
-  ResourceEntry entry;
-
-  // Get file9.
-  std::string file_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &file_id));
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(file_id, &entry));
-  EXPECT_EQ("file9", entry.base_name());
-  EXPECT_TRUE(!entry.file_info().is_directory());
-  EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
-
-  // Rename it.
-  ResourceEntry file_entry(entry);
-  file_entry.set_title("file100");
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->RefreshEntry(file_entry));
-
-  base::FilePath path;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path));
-  EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
-  entry.Clear();
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(file_id, &entry));
-  EXPECT_EQ("file100", entry.base_name());
-  EXPECT_TRUE(!entry.file_info().is_directory());
-  EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
-
-  // Update the file md5.
-  const std::string updated_md5("md5:updated");
-  file_entry = entry;
-  file_entry.mutable_file_specific_info()->set_md5(updated_md5);
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->RefreshEntry(file_entry));
-
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path));
-  EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
-  entry.Clear();
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(file_id, &entry));
-  EXPECT_EQ("file100", entry.base_name());
-  EXPECT_TRUE(!entry.file_info().is_directory());
-  EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
-
-  // Make sure we get the same thing from GetResourceEntryByPath.
-  entry.Clear();
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"), &entry));
-  EXPECT_EQ("file100", entry.base_name());
-  ASSERT_TRUE(!entry.file_info().is_directory());
-  EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
-
-  // Get dir2.
-  entry.Clear();
-  std::string dir_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &dir_id));
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(dir_id, &entry));
-  EXPECT_EQ("dir2", entry.base_name());
-  ASSERT_TRUE(entry.file_info().is_directory());
-
-  // Get dir3's ID.
-  std::string dir3_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_id));
-
-  // Change the name to dir100 and change the parent to drive/dir1/dir3.
-  ResourceEntry dir_entry(entry);
-  dir_entry.set_title("dir100");
-  dir_entry.set_parent_local_id(dir3_id);
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(dir_entry));
-
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(dir_id, &path));
-  EXPECT_EQ("drive/root/dir1/dir3/dir100", path.AsUTF8Unsafe());
-  entry.Clear();
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryById(dir_id, &entry));
-  EXPECT_EQ("dir100", entry.base_name());
-  EXPECT_TRUE(entry.file_info().is_directory());
-  EXPECT_EQ("id:dir2", entry.resource_id());
-
-  // Make sure the children have moved over. Test file6.
-  entry.Clear();
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/dir100/file6"),
-      &entry));
-  EXPECT_EQ("file6", entry.base_name());
-
-  // Make sure dir2 no longer exists.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &entry));
-
-  // Make sure that directory cannot move under a file.
-  dir_entry.set_parent_local_id(file_id);
-  EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY,
-            resource_metadata_->RefreshEntry(dir_entry));
-
-  // Cannot refresh root.
-  dir_entry.Clear();
-  dir_entry.set_local_id(util::kDriveGrandRootLocalId);
-  dir_entry.set_title("new-root-name");
-  dir_entry.set_parent_local_id(dir3_id);
-  EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
-            resource_metadata_->RefreshEntry(dir_entry));
-}
-
-TEST_F(ResourceMetadataTest, RefreshEntry_ResourceIDCheck) {
-  // Get an entry with a non-empty resource ID.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entry));
-  EXPECT_FALSE(entry.resource_id().empty());
-
-  // Add a new entry with an empty resource ID.
-  ResourceEntry new_entry;
-  new_entry.set_parent_local_id(entry.local_id());
-  new_entry.set_title("new entry");
-  std::string local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(new_entry, &local_id));
-
-  // Try to refresh the new entry with a used resource ID.
-  new_entry.set_local_id(local_id);
-  new_entry.set_resource_id(entry.resource_id());
-  EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
-            resource_metadata_->RefreshEntry(new_entry));
-}
-
-TEST_F(ResourceMetadataTest, RefreshEntry_DoNotOverwriteCacheState) {
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
-
-  // Try to set MD5 with RefreshEntry.
-  entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5");
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry));
-
-  // Cache state is unchanged.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
-
-  // Pin the file.
-  EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(entry.local_id()));
-
-  // Try to clear the cache state with RefreshEntry.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
-  entry.mutable_file_specific_info()->clear_cache_state();
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry));
-
-  // Cache state is not cleared.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
-  EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
-}
-
-TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) {
-  std::set<base::FilePath> sub_directories;
-
-  // file9: not a directory, so no children.
-  std::string local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
-      local_id, &sub_directories));
-  EXPECT_TRUE(sub_directories.empty());
-
-  // dir2: no child directories.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
-      local_id, &sub_directories));
-  EXPECT_TRUE(sub_directories.empty());
-  const std::string dir2_id = local_id;
-
-  // dir1: dir3 is the only child
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
-      local_id, &sub_directories));
-  EXPECT_EQ(1u, sub_directories.size());
-  EXPECT_EQ(1u, sub_directories.count(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3")));
-  sub_directories.clear();
-
-  // Add a few more directories to make sure deeper nesting works.
-  // dir2/dir100
-  // dir2/dir101
-  // dir2/dir101/dir102
-  // dir2/dir101/dir103
-  // dir2/dir101/dir104
-  // dir2/dir101/dir104/dir105
-  // dir2/dir101/dir104/dir105/dir106
-  // dir2/dir101/dir104/dir105/dir106/dir107
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir100", dir2_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir101", dir2_id), &local_id));
-  const std::string dir101_id = local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir102", dir101_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir103", dir101_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir104", dir101_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir105", local_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir106", local_id), &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("dir107", local_id), &local_id));
-
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
-      dir2_id, &sub_directories));
-  EXPECT_EQ(8u, sub_directories.size());
-  EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/dir2/dir101")));
-  EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/dir2/dir101/dir104")));
-  EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
-      "drive/root/dir2/dir101/dir104/dir105/dir106/dir107")));
-}
-
-TEST_F(ResourceMetadataTest, AddEntry) {
-  // Add a file to dir3.
-  std::string local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &local_id));
-  ResourceEntry file_entry = CreateFileEntry("file100", local_id);
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(file_entry, &local_id));
-  base::FilePath path;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path));
-  EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
-
-  // Add a directory.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
-  ResourceEntry dir_entry = CreateDirectoryEntry("dir101", local_id);
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(dir_entry, &local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path));
-  EXPECT_EQ("drive/root/dir1/dir101", path.AsUTF8Unsafe());
-
-  // Add to an invalid parent.
-  ResourceEntry file_entry3 = CreateFileEntry("file103", "id:invalid");
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
-            resource_metadata_->AddEntry(file_entry3, &local_id));
-
-  // Add an existing file.
-  EXPECT_EQ(FILE_ERROR_EXISTS,
-            resource_metadata_->AddEntry(file_entry, &local_id));
-}
-
-TEST_F(ResourceMetadataTest, RemoveEntry) {
-  // Make sure file9 is found.
-  std::string file9_local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"),
-      &file9_local_id));
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      file9_local_id, &entry));
-  EXPECT_EQ("file9", entry.base_name());
-
-  // Remove file9.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id));
-
-  // file9 should no longer exist.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
-      file9_local_id, &entry));
-
-  // Look for dir3.
-  std::string dir3_local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_local_id));
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      dir3_local_id, &entry));
-  EXPECT_EQ("dir3", entry.base_name());
-
-  // Remove dir3.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id));
-
-  // dir3 should no longer exist.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
-      dir3_local_id, &entry));
-
-  // Remove unknown local_id using RemoveEntry.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo"));
-
-  // Try removing root. This should fail.
-  EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry(
-      util::kDriveGrandRootLocalId));
-}
-
-TEST_F(ResourceMetadataTest, GetResourceEntryById_RootDirectory) {
-  // Look up the root directory by its ID.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      util::kDriveGrandRootLocalId, &entry));
-  EXPECT_EQ("drive", entry.base_name());
-}
-
-TEST_F(ResourceMetadataTest, GetResourceEntryById) {
-  // Get file4 by path.
-  std::string local_id;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &local_id));
-
-  // Confirm that an existing file is found.
-  ResourceEntry entry;
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      local_id, &entry));
-  EXPECT_EQ("file4", entry.base_name());
-
-  // Confirm that a non existing file is not found.
-  EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
-      "non_existing", &entry));
-}
-
-TEST_F(ResourceMetadataTest, Iterate) {
-  std::unique_ptr<ResourceMetadata::Iterator> it =
-      resource_metadata_->GetIterator();
-  ASSERT_TRUE(it);
-
-  int file_count = 0, directory_count = 0;
-  for (; !it->IsAtEnd(); it->Advance()) {
-    if (!it->GetValue().file_info().is_directory())
-      ++file_count;
-    else
-      ++directory_count;
-  }
-
-  EXPECT_EQ(7, file_count);
-  EXPECT_EQ(9, directory_count);
-}
-
-TEST_F(ResourceMetadataTest, DuplicatedNames) {
-  std::string root_local_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
-
-  ResourceEntry entry;
-
-  // When multiple entries with the same title are added in a single directory,
-  // their base_names are de-duped.
-  // - drive/root/foo
-  // - drive/root/foo (1)
-  std::string dir_id_0;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntryWithResourceId(
-          "foo", "foo0", root_local_id), &dir_id_0));
-  std::string dir_id_1;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntryWithResourceId(
-          "foo", "foo1", root_local_id), &dir_id_1));
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      dir_id_0, &entry));
-  EXPECT_EQ("foo", entry.base_name());
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      dir_id_1, &entry));
-  EXPECT_EQ("foo (1)", entry.base_name());
-
-  // - drive/root/foo/bar.txt
-  // - drive/root/foo/bar (1).txt
-  // - drive/root/foo/bar (2).txt
-  // ...
-  // - drive/root/foo/bar (99).txt
-  std::vector<std::string> file_ids(100);
-  for (size_t i = 0; i < file_ids.size(); ++i) {
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-        CreateFileEntryWithResourceId(
-            "bar.txt", base::StringPrintf("bar%d", static_cast<int>(i)),
-            dir_id_0), &file_ids[i]));
-  }
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      file_ids[0], &entry));
-  EXPECT_EQ("bar.txt", entry.base_name());
-  for (size_t i = 1; i < file_ids.size(); ++i) {
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-        file_ids[i], &entry)) << i;
-    EXPECT_EQ(base::StringPrintf("bar (%d).txt", static_cast<int>(i)),
-              entry.base_name());
-  }
-
-  // Same name but different parent. No renaming.
-  // - drive/root/foo (1)/bar.txt
-  std::string file_id_3;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateFileEntryWithResourceId(
-          "bar.txt", "bar_different_parent", dir_id_1), &file_id_3));
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      file_id_3, &entry));
-  EXPECT_EQ("bar.txt", entry.base_name());
-
-  // Checks that the entries can be looked up by the de-duped paths.
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/foo/bar (2).txt"), &entry));
-  EXPECT_EQ("bar2", entry.resource_id());
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root/foo (1)/bar.txt"), &entry));
-  EXPECT_EQ("bar_different_parent", entry.resource_id());
-}
-
-TEST_F(ResourceMetadataTest, EncodedNames) {
-  std::string root_local_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-      base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
-
-  ResourceEntry entry;
-
-  std::string dir_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateDirectoryEntry("\\(^o^)/", root_local_id), &dir_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      dir_id, &entry));
-  EXPECT_EQ("\\(^o^)_", entry.base_name());
-
-  std::string file_id;
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-      CreateFileEntryWithResourceId("Slash /.txt", "myfile", dir_id),
-      &file_id));
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
-      file_id, &entry));
-  EXPECT_EQ("Slash _.txt", entry.base_name());
-
-  ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
-      base::FilePath::FromUTF8Unsafe(
-          "drive/root/\\(^o^)_/Slash _.txt"),
-      &entry));
-  EXPECT_EQ("myfile", entry.resource_id());
-}
-
-TEST_F(ResourceMetadataTest, Reset) {
-  // The grand root has "root" which is not empty.
-  std::vector<ResourceEntry> entries;
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive/root"), &entries));
-  ASSERT_FALSE(entries.empty());
-
-  // Reset.
-  EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset());
-
-  // change stamp should be reset.
-  std::string start_page_token;
-  EXPECT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetStartPageToken(&start_page_token));
-  EXPECT_TRUE(start_page_token.empty());
-
-  // root should continue to exist.
-  ResourceEntry entry;
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->GetResourceEntryByPath(
-                base::FilePath::FromUTF8Unsafe("drive"), &entry));
-  EXPECT_EQ("drive", entry.base_name());
-  ASSERT_TRUE(entry.file_info().is_directory());
-  EXPECT_EQ(util::kDriveGrandRootLocalId, entry.local_id());
-
-  // There are "other", "trash" and "root", "team_drives" and "Computers"
-  // under "drive".
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive"), &entries));
-  EXPECT_EQ(5U, entries.size());
-
-  // The "other" directory should be empty.
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive/other"), &entries));
-  EXPECT_TRUE(entries.empty());
-
-  // The "trash" directory should be empty.
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive/trash"), &entries));
-  EXPECT_TRUE(entries.empty());
-
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive/team_drives"), &entries));
-  EXPECT_TRUE(entries.empty());
-
-  ASSERT_EQ(FILE_ERROR_OK,
-            resource_metadata_->ReadDirectoryByPath(
-                base::FilePath::FromUTF8Unsafe("drive/Computers"), &entries));
-  EXPECT_TRUE(entries.empty());
-}
-
-}  // namespace internal
-}  // namespace drive
diff --git a/components/drive/search_metadata_unittest.cc b/components/drive/search_metadata_unittest.cc
index fa9e7f5b..bd4eb40 100644
--- a/components/drive/search_metadata_unittest.cc
+++ b/components/drive/search_metadata_unittest.cc
@@ -10,21 +10,8 @@
 #include <memory>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/i18n/string_search.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/drive/chromeos/drive_test_util.h"
-#include "components/drive/chromeos/fake_free_disk_space_getter.h"
-#include "components/drive/chromeos/file_cache.h"
-#include "components/drive/drive_api_util.h"
-#include "components/drive/file_system_core_util.h"
-#include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace drive {
@@ -32,8 +19,6 @@
 
 namespace {
 
-const int kDefaultAtMostNumMatches = 10;
-
 // A simple wrapper for testing FindAndHighlightWrapper(). It just converts the
 // query text parameter to FixedPatternStringSearchIgnoringCaseAndAccents.
 bool FindAndHighlightWrapper(
@@ -51,503 +36,6 @@
 
 }  // namespace
 
-class SearchMetadataTest : public testing::Test {
- protected:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();
-
-    metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_TRUE(metadata_storage_->Initialize());
-
-    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
-                               base::ThreadTaskRunnerHandle::Get().get(),
-                               fake_free_disk_space_getter_.get()));
-    ASSERT_TRUE(cache_->Initialize());
-
-    resource_metadata_.reset(
-        new ResourceMetadata(metadata_storage_.get(),
-                             cache_.get(),
-                             base::ThreadTaskRunnerHandle::Get().get()));
-    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
-
-    AddEntriesToMetadata();
-  }
-
-  void AddEntriesToMetadata() {
-    base::FilePath temp_file;
-    EXPECT_TRUE(
-        base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file));
-    const std::string temp_file_md5 = "md5";
-
-    ResourceEntry entry;
-    std::string local_id;
-
-    // drive/root
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
-        util::GetDriveMyDriveRootPath(), &local_id));
-    const std::string root_local_id = local_id;
-
-    // drive/root/Directory-1
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->AddEntry(
-                  GetDirectoryEntry("Directory-1", "dir1", 1, 1, root_local_id),
-                  &local_id));
-    const std::string dir1_local_id = local_id;
-
-    // drive/root/Directory-1/SubDirectory File 1.txt
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-                                 GetFileEntry("SubDirectory File 1.txt",
-                                              "file1a", 2, 99, dir1_local_id),
-                                 &local_id));
-    EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-        local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY));
-
-    // drive/root/Directory-1/Shared To The Account Owner.txt
-    entry = GetFileEntry("Shared To The Account Owner.txt", "file1b", 3, 3,
-                         dir1_local_id);
-    entry.set_shared_with_me(true);
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id));
-
-    // drive/root/Directory 2 excludeDir-test
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->AddEntry(
-                  GetDirectoryEntry("Directory 2 excludeDir-test", "dir2", 4, 4,
-                                    root_local_id),
-                  &local_id));
-
-    // drive/root/Slash \xE2\x88\x95 in directory
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->AddEntry(
-                  GetDirectoryEntry("Slash \xE2\x88\x95 in directory", "dir3",
-                                    5, 5, root_local_id),
-                  &local_id));
-    const std::string dir3_local_id = local_id;
-
-    // drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-                                 GetFileEntry("Slash SubDir File.txt", "file3a",
-                                              6, 6, dir3_local_id),
-                                 &local_id));
-
-    // drive/root/File 2.txt
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->AddEntry(
-                  GetFileEntry("File 2.txt", "file2", 7, 7, root_local_id),
-                  &local_id));
-    EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
-        local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY));
-
-    // drive/root/Document 1 excludeDir-test
-    entry =
-        GetFileEntry("Document 1 excludeDir-test", "doc1", 8, 8, root_local_id);
-    entry.mutable_file_specific_info()->set_is_hosted_document(true);
-    entry.mutable_file_specific_info()->set_document_extension(".gdoc");
-    entry.mutable_file_specific_info()->set_content_mime_type(
-        drive::util::kGoogleDocumentMimeType);
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id));
-
-    // drive/team_drives
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->GetIdByPath(
-                  util::GetDriveTeamDrivesRootPath(), &local_id));
-    const std::string team_drive_root_local_id = local_id;
-
-    // drive/team_drives/TD-1
-    EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
-                                 GetDirectoryEntry("TD-1", "team_drive1", 1, 1,
-                                                   team_drive_root_local_id),
-                                 &local_id));
-    const std::string team_drive_dir1_local_id = local_id;
-
-    // drive/team_drives/TD-1/TD File 1.txt
-    EXPECT_EQ(FILE_ERROR_OK,
-              resource_metadata_->AddEntry(
-                  GetFileEntry("TD File 1.txt", "team_drive1_file1a", 2, 99,
-                               team_drive_dir1_local_id),
-                  &local_id));
-  }
-
-  ResourceEntry GetFileEntry(const std::string& name,
-                             const std::string& resource_id,
-                             int64_t last_accessed,
-                             int64_t last_modified,
-                             const std::string& parent_local_id) {
-    ResourceEntry entry;
-    entry.set_title(name);
-    entry.set_resource_id(resource_id);
-    entry.set_parent_local_id(parent_local_id);
-    entry.mutable_file_info()->set_last_accessed(last_accessed);
-    entry.mutable_file_info()->set_last_modified(last_modified);
-    return entry;
-  }
-
-  ResourceEntry GetDirectoryEntry(const std::string& name,
-                                  const std::string& resource_id,
-                                  int64_t last_accessed,
-                                  int64_t last_modified,
-                                  const std::string& parent_local_id) {
-    ResourceEntry entry;
-    entry.set_title(name);
-    entry.set_resource_id(resource_id);
-    entry.set_parent_local_id(parent_local_id);
-    entry.mutable_file_info()->set_last_accessed(last_accessed);
-    entry.mutable_file_info()->set_last_modified(last_modified);
-    entry.mutable_file_info()->set_is_directory(true);
-    return entry;
-  }
-
-  content::BrowserTaskEnvironment task_environment_;
-  base::ScopedTempDir temp_dir_;
-  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
-  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
-      metadata_storage_;
-  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
-      resource_metadata_;
-  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
-};
-
-TEST_F(SearchMetadataTest, SearchMetadata_ZeroMatches) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "NonExistent", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(0U, result->size());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_RegularFile) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "SubDirectory File 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_TeamDrive_RegularFile) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "TD File 1.txt", base::BindRepeating(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/team_drives/TD-1/TD File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-// This test checks if |FindAndHighlightWrapper| does case-insensitive search.
-// Tricker test cases for |FindAndHighlightWrapper| can be found below.
-TEST_F(SearchMetadataTest, SearchMetadata_CaseInsensitiveSearch) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  // The query is all in lower case.
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "subdirectory file 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_RegularFiles) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir",
-      base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches,
-      MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(2U, result->size());
-
-  // All base names should contain "File". The results should be sorted by the
-  // last accessed time in descending order.
-  EXPECT_EQ("drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt",
-            result->at(0).path.AsUTF8Unsafe());
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(1).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastAccessed) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  // There are two files matching "SubDir" but only one file should be
-  // returned. Results are ordered by last accessed time.
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir",
-      base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      1,  // at_most_num_matches
-      MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastModified) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  // There are two files matching "SubDir" but only one file should be
-  // returned. Results are ordered by last modified time.
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir",
-      base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      1,  // at_most_num_matches
-      MetadataSearchOrder::LAST_MODIFIED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_Directory) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "Directory-1", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Directory-1", result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_TeamDrive_Directory) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "TD-1",
-      base::BindRepeating(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/team_drives/TD-1", result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_HostedDocument) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document",
-      base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches,
-      MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-
-  EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_ExcludeHostedDocument) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document",
-      base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(0U, result->size());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_SharedWithMe) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "",
-      base::Bind(&MatchesType, SEARCH_METADATA_SHARED_WITH_ME),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-  EXPECT_EQ("drive/root/Directory-1/Shared To The Account Owner.txt",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_FileAndDirectory) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "excludeDir-test", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(2U, result->size());
-
-  EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc",
-            result->at(0).path.AsUTF8Unsafe());
-  EXPECT_EQ("drive/root/Directory 2 excludeDir-test",
-            result->at(1).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_ExcludeDirectory) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "excludeDir-test",
-      base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_DIRECTORIES),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(1U, result->size());
-
-  EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc",
-            result->at(0).path.AsUTF8Unsafe());
-}
-
-// "drive", "drive/root", "drive/other" should be excluded.
-TEST_F(SearchMetadataTest, SearchMetadata_ExcludeSpecialDirectories) {
-  const char* const kQueries[] = { "drive", "root", "other" };
-  for (size_t i = 0; i < base::size(kQueries); ++i) {
-    FileError error = FILE_ERROR_FAILED;
-    std::unique_ptr<MetadataSearchResultVector> result;
-
-    const std::string query = kQueries[i];
-    SearchMetadata(
-        base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), query,
-        base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches,
-        MetadataSearchOrder::LAST_ACCESSED,
-        google_apis::test_util::CreateCopyResultCallback(&error, &result));
-
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(FILE_ERROR_OK, error);
-    ASSERT_TRUE(result);
-    ASSERT_TRUE(result->empty()) << ": " << query << " should not match";
-  }
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_Offline) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "",
-      base::Bind(&MatchesType, SEARCH_METADATA_OFFLINE),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_EQ(3U, result->size());
-
-  // This is not included in the cache but is a hosted document.
-  EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc",
-            result->at(0).path.AsUTF8Unsafe());
-
-  EXPECT_EQ("drive/root/File 2.txt",
-            result->at(1).path.AsUTF8Unsafe());
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(2).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest, SearchMetadata_MultipleKeywords) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      "Directory 1", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(2U, result->size());
-
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-  EXPECT_EQ("drive/root/Directory-1", result->at(1).path.AsUTF8Unsafe());
-}
-
-TEST_F(SearchMetadataTest,
-       SearchMetadata_KeywordsSeparatedWithIdeographicSpace) {
-  FileError error = FILE_ERROR_FAILED;
-  std::unique_ptr<MetadataSearchResultVector> result;
-
-  // \xE3\x80\x80 is ideographic space.
-  SearchMetadata(
-      base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(),
-      R"(Directory 1)", base::Bind(&MatchesType, SEARCH_METADATA_ALL),
-      kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED,
-      google_apis::test_util::CreateCopyResultCallback(&error, &result));
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-  ASSERT_TRUE(result);
-  ASSERT_EQ(2U, result->size());
-
-  EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt",
-            result->at(0).path.AsUTF8Unsafe());
-  EXPECT_EQ("drive/root/Directory-1", result->at(1).path.AsUTF8Unsafe());
-}
-
 TEST(SearchMetadataSimpleTest, FindAndHighlight_ZeroMatches) {
   std::string highlighted_text;
   EXPECT_FALSE(FindAndHighlightWrapper("text", "query", &highlighted_text));
diff --git a/components/media_message_center/media_notification_view.cc b/components/media_message_center/media_notification_view.cc
index 22d1524..c9a0261 100644
--- a/components/media_message_center/media_notification_view.cc
+++ b/components/media_message_center/media_notification_view.cc
@@ -322,11 +322,23 @@
 
   accessible_name_ = GetAccessibleNameFromMetadata(metadata);
 
-  if (!metadata.title.empty())
+  // The title label should only be a11y-focusable when there is text to be
+  // read.
+  if (metadata.title.empty()) {
+    title_label_->SetFocusBehavior(FocusBehavior::NEVER);
+  } else {
+    title_label_->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
     RecordMetadataHistogram(Metadata::kTitle);
+  }
 
-  if (!metadata.artist.empty())
+  // The artist label should only be a11y-focusable when there is text to be
+  // read.
+  if (metadata.artist.empty()) {
+    artist_label_->SetFocusBehavior(FocusBehavior::NEVER);
+  } else {
+    artist_label_->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
     RecordMetadataHistogram(Metadata::kArtist);
+  }
 
   if (!metadata.album.empty())
     RecordMetadataHistogram(Metadata::kAlbum);
diff --git a/components/paint_preview/renderer/DEPS b/components/paint_preview/renderer/DEPS
index 53de874..497159a7 100644
--- a/components/paint_preview/renderer/DEPS
+++ b/components/paint_preview/renderer/DEPS
@@ -3,4 +3,5 @@
   "+content/public/renderer",
   "+content/public/test",
   "+third_party/blink/public",
+  "+ui/native_theme/native_theme_features.h",
 ]
diff --git a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
index c62e7aa..327d1389 100644
--- a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
+++ b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
@@ -7,11 +7,17 @@
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/threading/thread_restrictions.h"
+#include "components/paint_preview/common/file_stream.h"
 #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/test/render_view_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/skia/include/core/SkPicture.h"
+#include "ui/native_theme/native_theme_features.h"
 
 namespace paint_preview {
 
@@ -38,6 +44,12 @@
 
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+
+    // TODO(crbug/1022398): This is required to bypass a seemingly unrelated
+    // DCHECK for |use_overlay_scrollbars_| in NativeThemeAura on ChromeOS when
+    // painting scrollbars when first calling LoadHTML().
+    feature_list_.InitAndDisableFeature(features::kOverlayScrollbar);
+
     RenderViewTest::SetUp();
   }
 
@@ -49,14 +61,155 @@
 
  private:
   base::ScopedTempDir temp_dir_;
+  base::test::ScopedFeatureList feature_list_;
 };
 
-TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrame) {
+TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrameAndClipping) {
+  LoadHTML(
+      "<body>"
+      "  <div style='width: 600px; height: 80vh; "
+      "              background-color: #ff0000'>&nbsp;</div>"
+      "  <a style='display:inline-block' href='http://www.google.com'>Foo</a>"
+      "  <div style='width: 100px; height: 600px; "
+      "              background-color: #000000'>&nbsp;</div>"
+      "  <div style='overflow: hidden; width: 100px; height: 100px;"
+      "              background: orange;'>"
+      "    <div style='width: 500px; height: 500px;"
+      "                background: yellow;'></div>"
+      "  </div>"
+      "</body>");
+  base::FilePath skp_path = MakeTestFilePath("test.skp");
+
+  mojom::PaintPreviewCaptureParamsPtr params =
+      mojom::PaintPreviewCaptureParams::New();
+  auto token = base::UnguessableToken::Create();
+  params->guid = token;
+  params->clip_rect = gfx::Rect();
+  params->is_main_frame = true;
+  base::File skp_file(skp_path,
+                      base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+  params->file = std::move(skp_file);
+
+  auto out_response = mojom::PaintPreviewCaptureResponse::New();
+  content::RenderFrame* frame = GetFrame();
+  int routing_id = frame->GetRoutingID();
+  PaintPreviewRecorderImpl paint_preview_recorder(frame);
+  paint_preview_recorder.CapturePaintPreview(
+      std::move(params),
+      base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk,
+                     base::Unretained(&out_response)));
+
+  // Here id() is just the routing ID.
+  EXPECT_EQ(static_cast<int>(out_response->id), routing_id);
+  EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U);
+
+  EXPECT_EQ(out_response->links.size(), 1U);
+  EXPECT_EQ(out_response->links[0]->url, GURL("http://www.google.com/"));
+  // Relaxed checks on dimensions and no checks on positions. This is not
+  // intended to test the rendering behavior of the page only that a link
+  // was captured and has a bounding box.
+  EXPECT_GT(out_response->links[0]->rect.width(), 0);
+  EXPECT_GT(out_response->links[0]->rect.height(), 0);
+
+  sk_sp<SkPicture> pic;
+  {
+    base::ScopedAllowBlockingForTesting scope;
+    FileRStream rstream(base::File(
+        skp_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ));
+    pic = SkPicture::MakeFromStream(&rstream, nullptr);
+  }
+  // The min page height is the sum of the three top level divs of 800. The min
+  // width is that of the widest div at 600.
+  EXPECT_GE(pic->cullRect().height(), 800);
+  EXPECT_GE(pic->cullRect().width(), 600);
+  SkBitmap bitmap;
+  ASSERT_TRUE(bitmap.tryAllocN32Pixels(pic->cullRect().width(),
+                                       pic->cullRect().height()));
+  SkCanvas canvas(bitmap);
+  canvas.drawPicture(pic);
+  // This should be inside the top right corner of the first top level div.
+  // Success means there was no horizontal clipping as this region is red,
+  // matching the div.
+  EXPECT_EQ(bitmap.getColor(600, 50), 0xFFFF0000U);
+  // This should be inside the bottom of the second top level div. Success means
+  // there was no vertical clipping as this region is black matching the div. If
+  // the yellow div within the orange div overflowed then this would be yellow
+  // and fail.
+  EXPECT_EQ(bitmap.getColor(50, pic->cullRect().height() - 150), 0xFF000000U);
+  // This should be for the white background in the bottom right. This checks
+  // that the background is not clipped.
+  EXPECT_EQ(bitmap.getColor(pic->cullRect().width() - 50,
+                            pic->cullRect().height() - 50),
+            0xFFFFFFFFU);
+}
+
+TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureFragment) {
+  // Use position absolute position to check that the captured link dimensions
+  // match what is specified.
   LoadHTML(
       "<body style='min-height:1000px;'>"
-      "  <div style='width: 100px; height: 100px; "
-      "              background-color: #000000'>&nbsp;</div>"
-      "  <p><a href='https://www.foo.com'>Foo</a></p>"
+      "  <a style='position: absolute; left: -15px; top: 0px; width: 20px; "
+      "   height: 30px;' href='#fragment'>Foo</a>"
+      "  <h1 id='fragment'>I'm a fragment</h1>"
+      "</body>");
+  base::FilePath skp_path = MakeTestFilePath("test.skp");
+
+  mojom::PaintPreviewCaptureParamsPtr params =
+      mojom::PaintPreviewCaptureParams::New();
+  auto token = base::UnguessableToken::Create();
+  params->guid = token;
+  params->clip_rect = gfx::Rect();
+  params->is_main_frame = true;
+  base::File skp_file(skp_path,
+                      base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+  params->file = std::move(skp_file);
+
+  auto out_response = mojom::PaintPreviewCaptureResponse::New();
+  content::RenderFrame* frame = GetFrame();
+  int routing_id = frame->GetRoutingID();
+  PaintPreviewRecorderImpl paint_preview_recorder(frame);
+  paint_preview_recorder.CapturePaintPreview(
+      std::move(params),
+      base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk,
+                     &out_response));
+  // Here id() is just the routing ID.
+  EXPECT_EQ(static_cast<int>(out_response->id), routing_id);
+  EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U);
+
+  EXPECT_EQ(out_response->links.size(), 1U);
+  EXPECT_EQ(out_response->links[0]->url, GURL("fragment"));
+  EXPECT_EQ(out_response->links[0]->rect.x(), -15);
+  EXPECT_EQ(out_response->links[0]->rect.y(), 0);
+  EXPECT_EQ(out_response->links[0]->rect.width(), 20);
+  EXPECT_EQ(out_response->links[0]->rect.height(), 30);
+}
+
+TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureInvalidFile) {
+  LoadHTML("<body></body>");
+
+  mojom::PaintPreviewCaptureParamsPtr params =
+      mojom::PaintPreviewCaptureParams::New();
+  auto token = base::UnguessableToken::Create();
+  params->guid = token;
+  params->clip_rect = gfx::Rect();
+  params->is_main_frame = true;
+  base::File skp_file;  // Invalid file.
+  params->file = std::move(skp_file);
+
+  content::RenderFrame* frame = GetFrame();
+  PaintPreviewRecorderImpl paint_preview_recorder(frame);
+  paint_preview_recorder.CapturePaintPreview(
+      std::move(params),
+      base::BindOnce(&OnCaptureFinished,
+                     mojom::PaintPreviewStatus::kCaptureFailed, nullptr));
+}
+
+TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrameAndLocalFrame) {
+  LoadHTML(
+      "<body style='min-height:1000px;'>"
+      "  <iframe style='width: 500px, height: 500px'"
+      "          srcdoc=\"<div style='width: 100px; height: 100px;"
+      "          background-color: #000000'>&nbsp;</div>\"></iframe>"
       "</body>");
   base::FilePath skp_path = MakeTestFilePath("test.skp");
 
@@ -81,29 +234,40 @@
   // Here id() is just the routing ID.
   EXPECT_EQ(static_cast<int>(out_response->id), routing_id);
   EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U);
-
-  // NOTE: should be non-zero once the Blink implementation is hooked up.
-  EXPECT_EQ(out_response->links.size(), 0U);
 }
 
-TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureInvalidFile) {
-  LoadHTML("<body></body>");
+TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureLocalFrame) {
+  LoadHTML(
+      "<body style='min-height:1000px;'>"
+      "  <iframe style='width: 500px, height: 500px'"
+      "          srcdoc=\"<div style='width: 100px; height: 100px;"
+      "          background-color: #000000'>&nbsp;</div>\"></iframe>"
+      "</body>");
+  base::FilePath skp_path = MakeTestFilePath("test.skp");
 
   mojom::PaintPreviewCaptureParamsPtr params =
       mojom::PaintPreviewCaptureParams::New();
   auto token = base::UnguessableToken::Create();
   params->guid = token;
   params->clip_rect = gfx::Rect();
-  params->is_main_frame = true;
-  base::File skp_file;  // Invalid file.
+  params->is_main_frame = false;
+  base::File skp_file(skp_path,
+                      base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
   params->file = std::move(skp_file);
 
-  content::RenderFrame* frame = GetFrame();
-  PaintPreviewRecorderImpl paint_preview_recorder(frame);
+  auto out_response = mojom::PaintPreviewCaptureResponse::New();
+  auto* child_frame = content::RenderFrame::FromWebFrame(
+      GetFrame()->GetWebFrame()->FirstChild()->ToWebLocalFrame());
+  ASSERT_TRUE(child_frame);
+  int routing_id = child_frame->GetRoutingID();
+  PaintPreviewRecorderImpl paint_preview_recorder(child_frame);
   paint_preview_recorder.CapturePaintPreview(
       std::move(params),
-      base::BindOnce(&OnCaptureFinished,
-                     mojom::PaintPreviewStatus::kCaptureFailed, nullptr));
+      base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk,
+                     base::Unretained(&out_response)));
+  // Here id() is just the routing ID.
+  EXPECT_EQ(static_cast<int>(out_response->id), routing_id);
+  EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U);
 }
 
 }  // namespace paint_preview
diff --git a/components/paint_preview/renderer/paint_preview_recorder_impl.cc b/components/paint_preview/renderer/paint_preview_recorder_impl.cc
index 3b236b3..d807c8ec 100644
--- a/components/paint_preview/renderer/paint_preview_recorder_impl.cc
+++ b/components/paint_preview/renderer/paint_preview_recorder_impl.cc
@@ -101,15 +101,18 @@
   }
 
   cc::PaintRecorder recorder;
-  recorder.beginRecording(bounds.width(), bounds.height());
   PaintPreviewTracker tracker(params->guid, routing_id_, is_main_frame_);
-  // TODO(crbug/1008885): Create a method on |canvas| to inject |tracker_| to
-  // propagate to graphics contexts and inner canvases
-  // TODO(crbug/1001109): Create a method on |frame| to execute the capture
-  // within Blink.
+  cc::PaintCanvas* canvas =
+      recorder.beginRecording(bounds.width(), bounds.height());
+  canvas->SetPaintPreviewTracker(&tracker);
+  bool success = frame->CapturePaintPreview(bounds, canvas);
 
   // Restore to before out-of-lifecycle paint phase.
   frame->DispatchAfterPrintEvent();
+  if (!success) {
+    *status = mojom::PaintPreviewStatus::kCaptureFailed;
+    return;
+  }
 
   // TODO(crbug/1011896): Determine if making this async would be beneficial.
   *status = FinishRecording(recorder.finishRecordingAsPicture(), bounds,
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index af5f94e..7f0747f 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -302,7 +302,7 @@
     newly_blacklisted_ = false;
   }
 
-  if (password_overridden_ &&
+  if (IsPasswordUpdate() &&
       pending_credentials_.type == PasswordForm::Type::kGenerated &&
       !HasGeneratedPassword()) {
     metrics_util::LogPasswordGenerationSubmissionEvent(
@@ -310,7 +310,7 @@
     pending_credentials_.type = PasswordForm::Type::kManual;
   }
 
-  if (is_new_login_) {
+  if (IsNewLogin()) {
     metrics_util::LogNewlySavedPasswordIsGenerated(
         pending_credentials_.type == PasswordForm::Type::kGenerated);
     SanitizePossibleUsernames(&pending_credentials_);
@@ -319,6 +319,9 @@
                                     GetBestMatches(), &pending_credentials_);
     SavePendingToStore(false /*update*/);
   } else {
+    // It sounds wrong that we still update even if the
+    // |pending_credentials_state_| is NONE. We should double check if this
+    // actually necessary. Currently some tests depend on this behavior.
     ProcessUpdate();
     SavePendingToStore(true /*update*/);
   }
@@ -346,7 +349,7 @@
   pending_credentials_.skip_zero_click = skip_zero_click;
   pending_credentials_.preferred = true;
   pending_credentials_.date_last_used = base::Time::Now();
-  is_new_login_ = false;
+  pending_credentials_state_ = PendingCredentialsState::UPDATE;
   ProcessUpdate();
   SavePendingToStore(true /*update*/);
 
@@ -465,7 +468,8 @@
 }
 
 bool PasswordFormManager::IsNewLogin() const {
-  return is_new_login_;
+  return pending_credentials_state_ == PendingCredentialsState::NEW_LOGIN ||
+         pending_credentials_state_ == PendingCredentialsState::AUTOMATIC_SAVE;
 }
 
 FormFetcher* PasswordFormManager::GetFormFetcher() {
@@ -518,7 +522,7 @@
 }
 
 bool PasswordFormManager::IsPasswordUpdate() const {
-  return password_overridden_;
+  return pending_credentials_state_ == PendingCredentialsState::UPDATE;
 }
 
 base::WeakPtr<PasswordManagerDriver> PasswordFormManager::GetDriver() const {
@@ -608,8 +612,7 @@
     result->parsed_submitted_form_.reset(
         new PasswordForm(*parsed_submitted_form_));
   }
-  result->is_new_login_ = is_new_login_;
-  result->password_overridden_ = password_overridden_;
+  result->pending_credentials_state_ = pending_credentials_state_;
   result->is_submitted_ = is_submitted_;
 
   return result;
@@ -907,8 +910,8 @@
 
   // This function might be called multiple times so set variables that are
   // changed in this function to initial states.
-  is_new_login_ = true;
-  SetPasswordOverridden(false);
+  pending_credentials_state_ = PendingCredentialsState::NONE;
+  votes_uploader_.set_password_overridden(false);
 
   ValueElementPair password_to_save(PasswordToSave(*parsed_submitted_form_));
   // Look for the actually submitted credentials in the list of previously saved
@@ -916,16 +919,18 @@
   const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating(
       *parsed_submitted_form_, GetBestMatches());
   if (saved_form) {
-    // A similar credential exists in the store already.
+    // A similar credential exists in the store already. We should either update
+    // the password or create an new record if it's a PSL-matched credentials.
     pending_credentials_ = *saved_form;
-    SetPasswordOverridden(pending_credentials_.password_value !=
-                          password_to_save.first);
-    // If the autofilled credentials were a PSL match, store a copy with the
-    // current origin and signon realm. This ensures that on the next visit, a
-    // precise match is found.
-    is_new_login_ = pending_credentials_.is_public_suffix_match;
-
-    if (is_new_login_) {
+    if (pending_credentials_.password_value != password_to_save.first) {
+      // Password should be updated.
+      pending_credentials_state_ = PendingCredentialsState::UPDATE;
+      votes_uploader_.set_password_overridden(true);
+    } else if (pending_credentials_.is_public_suffix_match) {
+      // If the autofilled credentials were a PSL match, store a copy with the
+      // current origin and signon realm. This ensures that on the next visit, a
+      // precise match is found.
+      pending_credentials_state_ = PendingCredentialsState::AUTOMATIC_SAVE;
       // Update credential to reflect that it has been used for submission.
       // If this isn't updated, then password generation uploads are off for
       // sites where PSL matching is required to fill the login form, as two
@@ -938,7 +943,7 @@
       pending_credentials_.action = parsed_submitted_form_->action;
     }
   } else {
-    is_new_login_ = true;
+    pending_credentials_state_ = PendingCredentialsState::NEW_LOGIN;
     // No stored credentials can be matched to the submitted form. Offer to
     // save new credentials.
     CreatePendingCredentialsForNewCredentials(password_to_save.second);
@@ -956,6 +961,8 @@
               kCorrectedUsernameInForm);
     }
   }
+  // Whether it's a new credential or an update to existing one, we set the
+  // following fields.
   pending_credentials_.password_value =
       HasGeneratedPassword() ? generation_manager_->generated_password()
                              : password_to_save.first;
@@ -1133,7 +1140,7 @@
 void PasswordFormManager::SavePendingToStore(bool update) {
   const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating(
       *parsed_submitted_form_, GetBestMatches());
-  if ((update || password_overridden_) &&
+  if ((update || IsPasswordUpdate()) &&
       !pending_credentials_.IsFederatedCredential()) {
     DCHECK(saved_form);
   }
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 1522780..5b194e6 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -35,6 +35,8 @@
 class PasswordManagerDriver;
 struct PossibleUsernameData;
 
+enum class PendingCredentialsState { NONE, NEW_LOGIN, UPDATE, AUTOMATIC_SAVE };
+
 // This class helps with filling the observed form and with saving/updating the
 // stored information about it.
 class PasswordFormManager : public PasswordFormManagerForUI,
@@ -246,11 +248,6 @@
   void CreatePendingCredentialsForNewCredentials(
       const base::string16& password_element);
 
-  void SetPasswordOverridden(bool password_overridden) {
-    password_overridden_ = password_overridden;
-    votes_uploader_.set_password_overridden(password_overridden);
-  }
-
   // Helper for Save in the case there is at least one match for the pending
   // credentials. This sends needed signals to the autofill server, and also
   // triggers some UMA reporting.
@@ -329,19 +326,12 @@
   // |submitted_form_| and |best_matches_|.
   autofill::PasswordForm pending_credentials_;
 
-  // Whether |pending_credentials_| stores a credential that should be added
-  // to the password store. False means it's a pure update to the existing ones.
-  // TODO(crbug/831123): this value only makes sense internally. Remove public
-  // dependencies on it.
-  bool is_new_login_ = true;
+  PendingCredentialsState pending_credentials_state_ =
+      PendingCredentialsState::NONE;
 
   // Handles the user flows related to the generation.
   std::unique_ptr<PasswordGenerationManager> generation_manager_;
 
-  // Whether a saved password was overridden. The flag is true when there is a
-  // credential in the store that will get a new password value.
-  bool password_overridden_ = false;
-
   // If Chrome has already autofilled a few times, it is probable that autofill
   // is triggered by programmatic changes in the page. We set a maximum number
   // of times that Chrome will autofill to avoid being stuck in an infinite
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn
index cb1d23a..0d8e13c1 100644
--- a/components/performance_manager/BUILD.gn
+++ b/components/performance_manager/BUILD.gn
@@ -26,6 +26,8 @@
     "graph/page_node.cc",
     "graph/page_node_impl.cc",
     "graph/page_node_impl.h",
+    "graph/policies/process_priority_policy.cc",
+    "graph/policies/process_priority_policy.h",
     "graph/process_node.cc",
     "graph/process_node_impl.cc",
     "graph/process_node_impl.h",
@@ -95,6 +97,7 @@
     "graph/node_attached_data_unittest.cc",
     "graph/node_base_unittest.cc",
     "graph/page_node_impl_unittest.cc",
+    "graph/policies/process_priority_policy_unittest.cc",
     "graph/process_node_impl_unittest.cc",
     "graph/properties_unittest.cc",
     "graph/system_node_impl_unittest.cc",
diff --git a/components/performance_manager/graph/graph_impl.cc b/components/performance_manager/graph/graph_impl.cc
index 70e6525..c689418a 100644
--- a/components/performance_manager/graph/graph_impl.cc
+++ b/components/performance_manager/graph/graph_impl.cc
@@ -211,6 +211,10 @@
   return GetAllNodesOfType<WorkerNodeImpl, const WorkerNode*>();
 }
 
+bool GraphImpl::IsEmpty() const {
+  return nodes_.empty();
+}
+
 ukm::UkmRecorder* GraphImpl::GetUkmRecorder() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return ukm_recorder();
diff --git a/components/performance_manager/graph/graph_impl.h b/components/performance_manager/graph/graph_impl.h
index f2b7c70..87bee66 100644
--- a/components/performance_manager/graph/graph_impl.h
+++ b/components/performance_manager/graph/graph_impl.h
@@ -70,6 +70,7 @@
   std::vector<const FrameNode*> GetAllFrameNodes() const override;
   std::vector<const PageNode*> GetAllPageNodes() const override;
   std::vector<const WorkerNode*> GetAllWorkerNodes() const override;
+  bool IsEmpty() const override;
   ukm::UkmRecorder* GetUkmRecorder() const override;
   uintptr_t GetImplType() const override;
   const void* GetImpl() const override;
diff --git a/components/performance_manager/graph/graph_impl_unittest.cc b/components/performance_manager/graph/graph_impl_unittest.cc
index 23d5849f..049f26c 100644
--- a/components/performance_manager/graph/graph_impl_unittest.cc
+++ b/components/performance_manager/graph/graph_impl_unittest.cc
@@ -25,7 +25,9 @@
 }
 
 TEST_F(GraphImplTest, FindOrCreateSystemNode) {
+  EXPECT_TRUE(graph()->IsEmpty());
   SystemNodeImpl* system_node = graph()->FindOrCreateSystemNodeImpl();
+  EXPECT_FALSE(graph()->IsEmpty());
 
   // A second request should return the same instance.
   EXPECT_EQ(system_node, graph()->FindOrCreateSystemNodeImpl());
diff --git a/components/performance_manager/graph/policies/process_priority_policy.cc b/components/performance_manager/graph/policies/process_priority_policy.cc
new file mode 100644
index 0000000..91c79a7
--- /dev/null
+++ b/components/performance_manager/graph/policies/process_priority_policy.cc
@@ -0,0 +1,143 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/performance_manager/graph/policies/process_priority_policy.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/task/post_task.h"
+#include "components/performance_manager/public/render_process_host_proxy.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+
+namespace performance_manager {
+namespace policies {
+
+namespace {
+
+#if DCHECK_IS_ON()
+size_t g_instance_count = 0;
+#endif
+
+// Used as a testing seam. If this is set then SetProcessPriorityOnUiThread will
+// invoke the provided callback immediately after calling SetPriorityOverride on
+// the RenderProcessHost.
+ProcessPriorityPolicy::SetPriorityOnUiThreadCallback* g_callback = nullptr;
+
+// Maps a TaskPriority to a "is_foreground" bool. Process priorities are
+// currently simply "background" or "foreground", despite there actually being
+// more expressive power on most platforms.
+bool IsForegroundTaskPriority(base::TaskPriority priority) {
+  switch (priority) {
+    case base::TaskPriority::BEST_EFFORT:
+      return false;
+
+    case base::TaskPriority::USER_VISIBLE:
+    case base::TaskPriority::USER_BLOCKING:
+      break;
+  }
+
+  return true;
+}
+
+// Helper function for setting the RenderProcessHost priority.
+void SetProcessPriorityOnUIThread(RenderProcessHostProxy rph_proxy,
+                                  bool foreground) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // Deliver the policy message if the RPH still exists by the time the
+  // message arrives. Note that this will involve yet another bounce over to
+  // the process launcher thread.
+  auto* rph = rph_proxy.Get();
+  if (rph)
+    rph->SetPriorityOverride(foreground);
+
+  // Invoke the testing seam callback if one was provided.
+  if (g_callback && !g_callback->is_null())
+    g_callback->Run(rph_proxy, foreground);
+}
+
+// Dispatches a process priority change to the RenderProcessHost associated with
+// a given ProcessNode. The task is posted to the UI thread, where the RPH
+// lives.
+void DispatchSetProcessPriority(const ProcessNode* process_node,
+                                bool foreground) {
+  // TODO(chrisha): This will actually result in a further thread-hop over to
+  // the process launcher thread. If we migrate to process priority logic being
+  // driven 100% from the PM, we could post directly to the launcher thread
+  // via the base::Process directly.
+  const auto& proxy = process_node->GetRenderProcessHostProxy();
+  base::PostTask(
+      FROM_HERE, {content::BrowserThread::UI},
+      base::BindOnce(&SetProcessPriorityOnUIThread, proxy, foreground));
+}
+
+}  // namespace
+
+ProcessPriorityPolicy::ProcessPriorityPolicy() {
+#if DCHECK_IS_ON()
+  DCHECK_EQ(0u, g_instance_count);
+  ++g_instance_count;
+#endif
+}
+
+ProcessPriorityPolicy::~ProcessPriorityPolicy() {
+#if DCHECK_IS_ON()
+  DCHECK_EQ(1u, g_instance_count);
+  --g_instance_count;
+#endif
+}
+
+// static
+void ProcessPriorityPolicy::SetCallbackForTesting(
+    SetPriorityOnUiThreadCallback callback) {
+  ClearCallbackForTesting();
+  g_callback = new SetPriorityOnUiThreadCallback(callback);
+}
+
+void ProcessPriorityPolicy::ClearCallbackForTesting() {
+  if (!g_callback)
+    return;
+  delete g_callback;
+  g_callback = nullptr;
+}
+
+void ProcessPriorityPolicy::OnPassedToGraph(Graph* graph) {
+  DCHECK(graph->IsEmpty());
+  graph->AddProcessNodeObserver(this);
+}
+
+void ProcessPriorityPolicy::OnTakenFromGraph(Graph* graph) {
+  graph->RemoveProcessNodeObserver(this);
+}
+
+void ProcessPriorityPolicy::OnProcessNodeAdded(
+    const ProcessNode* process_node) {
+  // Set the initial process priority.
+  // TODO(chrisha): Get provisional nodes working so we can make an informed
+  // choice in the graph (processes launching ads-to-be, or extensions, or
+  // frames for backgrounded tabs, etc, can be launched with background
+  // priority).
+  // TODO(chrisha): Make process creation take a detour through the graph in
+  // order to get the initial priority parameter that is set here. Currently
+  // this is effectively a nop.
+  DispatchSetProcessPriority(
+      process_node, IsForegroundTaskPriority(process_node->GetPriority()));
+}
+
+void ProcessPriorityPolicy::OnPriorityChanged(
+    const ProcessNode* process_node,
+    base::TaskPriority previous_value) {
+  bool previous_foreground = IsForegroundTaskPriority(previous_value);
+  bool current_foreground =
+      IsForegroundTaskPriority(process_node->GetPriority());
+
+  // Only dispatch a message if the resulting process priority has changed.
+  if (previous_foreground != current_foreground)
+    DispatchSetProcessPriority(process_node, current_foreground);
+}
+
+}  // namespace policies
+}  // namespace performance_manager
diff --git a/components/performance_manager/graph/policies/process_priority_policy.h b/components/performance_manager/graph/policies/process_priority_policy.h
new file mode 100644
index 0000000..06796db
--- /dev/null
+++ b/components/performance_manager/graph/policies/process_priority_policy.h
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_
+
+#include "base/callback.h"
+#include "components/performance_manager/public/graph/graph.h"
+#include "components/performance_manager/public/graph/process_node.h"
+#include "components/performance_manager/public/render_process_host_proxy.h"
+
+namespace performance_manager {
+namespace policies {
+
+// Policy that observes priority changes on ProcessNodes, and applies these
+// to the actual processes via RenderProcessHost::SetPriorityOverride. There
+// is no need for more than one of these to be instantiated at a time (enforced
+// by a DCHECK). This policy expects to be attached to an empty graph (also
+// enforced by a DCHECK).
+class ProcessPriorityPolicy : public GraphOwned,
+                              public ProcessNode::ObserverDefaultImpl {
+ public:
+  using SetPriorityOnUiThreadCallback =
+      base::RepeatingCallback<void(RenderProcessHostProxy rph_proxy,
+                                   bool foreground)>;
+
+  ProcessPriorityPolicy();
+  ProcessPriorityPolicy(const ProcessPriorityPolicy&) = delete;
+  ProcessPriorityPolicy(ProcessPriorityPolicy&&) = delete;
+  ProcessPriorityPolicy& operator=(const ProcessPriorityPolicy&) = delete;
+  ProcessPriorityPolicy& operator=(ProcessPriorityPolicy&&) = delete;
+  ~ProcessPriorityPolicy() override;
+
+  // Testing seams. This allows testing this class without requiring a full
+  // browser test.
+  static void SetCallbackForTesting(SetPriorityOnUiThreadCallback callback);
+  static void ClearCallbackForTesting();
+
+ private:
+  // GraphOwned implementation:
+  void OnPassedToGraph(Graph* graph) override;
+  void OnTakenFromGraph(Graph* graph) override;
+
+  // ProcessNodeObserver implementation:
+  void OnProcessNodeAdded(const ProcessNode* process_node) override;
+  void OnPriorityChanged(const ProcessNode* process_node,
+                         base::TaskPriority previous_value) override;
+};
+
+}  // namespace policies
+}  // namespace performance_manager
+
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_
diff --git a/components/performance_manager/graph/policies/process_priority_policy_unittest.cc b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc
new file mode 100644
index 0000000..58e28c7
--- /dev/null
+++ b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc
@@ -0,0 +1,141 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/performance_manager/graph/policies/process_priority_policy.h"
+
+#include "base/test/bind_test_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/performance_manager/graph/process_node_impl.h"
+#include "components/performance_manager/performance_manager_test_harness.h"
+#include "components/performance_manager/public/performance_manager.h"
+#include "components/performance_manager/render_process_user_data.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/test/navigation_simulator.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace performance_manager {
+namespace policies {
+
+namespace {
+
+// Returns a priority that will lead to an opposite process priority.
+base::TaskPriority GetOppositePriority(base::TaskPriority priority) {
+  switch (priority) {
+    case base::TaskPriority::BEST_EFFORT:
+      return base::TaskPriority::USER_BLOCKING;
+
+    case base::TaskPriority::USER_VISIBLE:
+    case base::TaskPriority::USER_BLOCKING:
+      break;
+  }
+
+  return base::TaskPriority::BEST_EFFORT;
+}
+
+void PostToggleProcessNodePriority(content::RenderProcessHost* rph) {
+  auto* rpud = RenderProcessUserData::GetForRenderProcessHost(rph);
+  auto* process_node = rpud->process_node();
+
+  PerformanceManager::CallOnGraph(
+      FROM_HERE,
+      base::BindLambdaForTesting([process_node](Graph* graph_unused) {
+        process_node->set_priority(
+            GetOppositePriority(process_node->priority()));
+      }));
+}
+
+class ProcessPriorityPolicyTest : public PerformanceManagerTestHarness {
+ public:
+  ProcessPriorityPolicyTest() {}
+  ProcessPriorityPolicyTest(const ProcessPriorityPolicyTest&) = delete;
+  ProcessPriorityPolicyTest(ProcessPriorityPolicyTest&&) = delete;
+  ProcessPriorityPolicyTest& operator=(const ProcessPriorityPolicyTest&) =
+      delete;
+  ProcessPriorityPolicyTest& operator=(ProcessPriorityPolicyTest&&) = delete;
+  ~ProcessPriorityPolicyTest() override {}
+
+  void SetUp() override {
+    PerformanceManagerTestHarness::SetUp();
+
+    // It's safe to pass unretained as we clear the callback before being
+    // torn down.
+    ProcessPriorityPolicy::SetCallbackForTesting(
+        base::Bind(&ProcessPriorityPolicyTest::OnSetPriorityWrapper,
+                   base::Unretained(this)));
+  }
+
+  void TearDown() override {
+    ProcessPriorityPolicy::ClearCallbackForTesting();
+
+    // Clean up the web contents, which should dispose of the page and frame
+    // nodes involved.
+    DeleteContents();
+
+    // The RenderProcessHosts seem to get leaked, or at least be still alive
+    // here, so explicitly detach from them in order to clean up the graph
+    // nodes.
+    RenderProcessUserData::DetachAndDestroyAll();
+
+    PerformanceManagerTestHarness::TearDown();
+  }
+
+  void RunUntilOnSetPriority() {
+    base::RunLoop run_loop;
+    quit_closure_ = run_loop.QuitClosure();
+    run_loop.Run();
+    quit_closure_.Reset();
+  }
+
+  // This is eventually invoked by the testing callback when the policy sets a
+  // process priority.
+  MOCK_METHOD2(OnSetPriority, void(content::RenderProcessHost*, bool));
+
+ private:
+  void OnSetPriorityWrapper(RenderProcessHostProxy rph_proxy, bool foreground) {
+    OnSetPriority(rph_proxy.Get(), foreground);
+    quit_closure_.Run();
+  }
+
+  base::RepeatingClosure quit_closure_;
+};
+
+}  // namespace
+
+TEST_F(ProcessPriorityPolicyTest, GraphReflectedToRenderProcessHost) {
+  // Create an instance of the process priority policy.
+  PerformanceManager::CallOnGraph(
+      FROM_HERE, base::Bind([](Graph* graph) {
+        std::unique_ptr<ProcessPriorityPolicy> policy(
+            new ProcessPriorityPolicy());
+        graph->PassToGraph(std::move(policy));
+      }));
+
+  // Set the active contents in the RenderViewHostTestHarness.
+  SetContents(CreateTestWebContents());
+  auto* rvh = web_contents()->GetRenderViewHost();
+  DCHECK(rvh);
+  auto* rph = rvh->GetProcess();
+  DCHECK(rph);
+
+  // Simulate a navigation so that graph nodes spring into existence.
+  content::NavigationSimulator::NavigateAndCommitFromBrowser(
+      web_contents(), GURL("https://www.foo.com/"));
+
+  // Expect a background priority override to be set for process creation.
+  // NOTE: This is going to change once we have provisional frames and the like,
+  // and can calculate meaningful process startup priorities.
+  EXPECT_CALL(*this, OnSetPriority(rph, false));
+  RunUntilOnSetPriority();
+
+  // Toggle the priority and expect it to change.
+  PostToggleProcessNodePriority(rph);
+  EXPECT_CALL(*this, OnSetPriority(rph, true));
+  RunUntilOnSetPriority();
+
+  testing::Mock::VerifyAndClearExpectations(this);
+}
+
+}  // namespace policies
+}  // namespace performance_manager
diff --git a/components/performance_manager/public/graph/graph.h b/components/performance_manager/public/graph/graph.h
index 37cd408..e69bdbc 100644
--- a/components/performance_manager/public/graph/graph.h
+++ b/components/performance_manager/public/graph/graph.h
@@ -80,6 +80,9 @@
   virtual std::vector<const PageNode*> GetAllPageNodes() const = 0;
   virtual std::vector<const WorkerNode*> GetAllWorkerNodes() const = 0;
 
+  // Returns true if the graph is currently empty.
+  virtual bool IsEmpty() const = 0;
+
   // Returns the associated UKM recorder if it is defined.
   virtual ukm::UkmRecorder* GetUkmRecorder() const = 0;
 
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index 11619c2..0d8a926f 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -6,9 +6,13 @@
 
 option optimize_for = LITE_RUNTIME;
 
+import "policy_common_definitions.proto";
+
 package enterprise_management;
 
-import "policy_common_definitions.proto";
+// Everything below this comment will be synchronized between client and server
+// repos ( go/cros-proto-sync ).
+// Please don't manually edit any lines below this comment.
 
 message DevicePolicyRefreshRateProto {
   // In milliseconds.
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index e67f9c9..51c9939 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -10,6 +10,7 @@
 
 // Everything below this comment will be synchronized between client and server
 // repos ( go/cros-proto-sync ).
+// Please don't manually edit any lines below this comment.
 
 // This enum needs to be shared between DeviceRegisterRequest and
 // LicenseAvailability protos. With java_api_version 1, this means that enum
diff --git a/components/policy/proto/policy_common_definitions.proto b/components/policy/proto/policy_common_definitions.proto
index 274ae91..b5ffd71 100644
--- a/components/policy/proto/policy_common_definitions.proto
+++ b/components/policy/proto/policy_common_definitions.proto
@@ -8,6 +8,10 @@
 
 package enterprise_management;
 
+// Everything below this comment will be synchronized between client and server
+// repos ( go/cros-proto-sync ).
+// Please don't manually edit any lines below this comment.
+
 message StringList {
   repeated string entries = 1;
 }
@@ -42,4 +46,4 @@
 message StringListPolicyProto {
   optional PolicyOptions policy_options = 1;
   optional StringList value = 2;
-}
\ No newline at end of file
+}
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn
index ff1e1c08..6b21f91 100644
--- a/components/sessions/BUILD.gn
+++ b/components/sessions/BUILD.gn
@@ -48,6 +48,8 @@
     sources = [
       "ios/ios_live_tab.h",
       "ios/ios_live_tab.mm",
+      "ios/ios_restore_live_tab.h",
+      "ios/ios_restore_live_tab.mm",
       "ios/ios_serialized_navigation_builder.h",
       "ios/ios_serialized_navigation_builder.mm",
       "ios/ios_serialized_navigation_driver.cc",
@@ -62,6 +64,7 @@
     deps = [
       "//base",
       "//ios/web/common",
+      "//ios/web/public/session",
     ]
   }
 }
diff --git a/components/sessions/ios/ios_restore_live_tab.h b/components/sessions/ios/ios_restore_live_tab.h
new file mode 100644
index 0000000..e68c2e6
--- /dev/null
+++ b/components/sessions/ios/ios_restore_live_tab.h
@@ -0,0 +1,43 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_
+#define COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_
+
+#include "base/macros.h"
+#include "base/supports_user_data.h"
+#include "components/sessions/core/live_tab.h"
+
+@class CRWSessionStorage;
+
+namespace sessions {
+
+// An implementation of LiveTab that is backed by web::CRWSessionStorage for use
+// when restoring tabs from a crashed session.
+class SESSIONS_EXPORT RestoreIOSLiveTab : public LiveTab {
+ public:
+  explicit RestoreIOSLiveTab(CRWSessionStorage* session);
+  ~RestoreIOSLiveTab() override;
+  RestoreIOSLiveTab(const RestoreIOSLiveTab&) = delete;
+  RestoreIOSLiveTab& operator=(const RestoreIOSLiveTab&) = delete;
+
+  // LiveTab:
+  bool IsInitialBlankNavigation() override;
+  int GetCurrentEntryIndex() override;
+  int GetPendingEntryIndex() override;
+  sessions::SerializedNavigationEntry GetEntryAtIndex(int index) override;
+  sessions::SerializedNavigationEntry GetPendingEntry() override;
+  int GetEntryCount() override;
+  const std::string& GetUserAgentOverride() override;
+
+ private:
+  CRWSessionStorage* session_;
+
+  // Needed to return an empty string in GetUserAgentOverride().
+  const std::string user_agent_override_;
+};
+
+}  // namespace sessions
+
+#endif  // COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_
diff --git a/components/sessions/ios/ios_restore_live_tab.mm b/components/sessions/ios/ios_restore_live_tab.mm
new file mode 100644
index 0000000..f26fa555
--- /dev/null
+++ b/components/sessions/ios/ios_restore_live_tab.mm
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sessions/ios/ios_restore_live_tab.h"
+
+#include "components/sessions/ios/ios_serialized_navigation_builder.h"
+#include "ios/web/public/session/crw_navigation_item_storage.h"
+#include "ios/web/public/session/crw_session_storage.h"
+
+namespace sessions {
+
+RestoreIOSLiveTab::RestoreIOSLiveTab(CRWSessionStorage* session)
+    : session_(session) {}
+
+RestoreIOSLiveTab::~RestoreIOSLiveTab() {}
+
+bool RestoreIOSLiveTab::IsInitialBlankNavigation() {
+  return false;
+}
+
+int RestoreIOSLiveTab::GetCurrentEntryIndex() {
+  return session_.lastCommittedItemIndex;
+}
+
+int RestoreIOSLiveTab::GetPendingEntryIndex() {
+  return -1;
+}
+
+sessions::SerializedNavigationEntry RestoreIOSLiveTab::GetEntryAtIndex(
+    int index) {
+  NSArray* item_storages = session_.itemStorages;
+  CRWNavigationItemStorage* item = item_storages[index];
+  return sessions::IOSSerializedNavigationBuilder::FromNavigationStorageItem(
+      index, item);
+}
+
+sessions::SerializedNavigationEntry RestoreIOSLiveTab::GetPendingEntry() {
+  return sessions::SerializedNavigationEntry();
+}
+
+int RestoreIOSLiveTab::GetEntryCount() {
+  return session_.itemStorages.count;
+}
+
+const std::string& RestoreIOSLiveTab::GetUserAgentOverride() {
+  // Dynamic user agent overrides are not supported on iOS.
+  return user_agent_override_;
+}
+
+}  // namespace sessions
diff --git a/components/sessions/ios/ios_serialized_navigation_builder.h b/components/sessions/ios/ios_serialized_navigation_builder.h
index def0b1f1..7871753 100644
--- a/components/sessions/ios/ios_serialized_navigation_builder.h
+++ b/components/sessions/ios/ios_serialized_navigation_builder.h
@@ -12,6 +12,8 @@
 class NavigationItem;
 }
 
+@class CRWNavigationItemStorage;
+
 namespace sessions {
 class SerializedNavigationEntry;
 
@@ -24,6 +26,12 @@
   static SerializedNavigationEntry FromNavigationItem(
       int index, const web::NavigationItem& item);
 
+  // Construct a SerializedNavigationEntry for a particular index from the given
+  // CRWNavigationItemStorage.
+  static SerializedNavigationEntry FromNavigationStorageItem(
+      int index,
+      CRWNavigationItemStorage* item);
+
   // Convert the given SerializedNavigationEntry into a NavigationItem. The
   // NavigationItem will have a transition type of
   // PAGE_TRANSITION_RELOAD and a new unique ID.
diff --git a/components/sessions/ios/ios_serialized_navigation_builder.mm b/components/sessions/ios/ios_serialized_navigation_builder.mm
index 8224e75..096bf40 100644
--- a/components/sessions/ios/ios_serialized_navigation_builder.mm
+++ b/components/sessions/ios/ios_serialized_navigation_builder.mm
@@ -8,6 +8,7 @@
 #include "ios/web/public/favicon/favicon_status.h"
 #include "ios/web/public/navigation/navigation_item.h"
 #include "ios/web/public/navigation/referrer.h"
+#include "ios/web/public/session/crw_navigation_item_storage.h"
 
 namespace sessions {
 
@@ -30,6 +31,26 @@
   return navigation;
 }
 
+SerializedNavigationEntry
+IOSSerializedNavigationBuilder::FromNavigationStorageItem(
+    int index,
+    CRWNavigationItemStorage* item) {
+  // Create a NavigationItem to reserve a UniqueID.
+  auto navigation_item = web::NavigationItem::Create();
+  SerializedNavigationEntry navigation;
+  navigation.index_ = index;
+  navigation.unique_id_ = navigation_item->GetUniqueID();
+  navigation.referrer_url_ = item.referrer.url;
+  navigation.referrer_policy_ = item.referrer.policy;
+  navigation.virtual_url_ = item.virtualURL;
+  navigation.title_ = item.title;
+  // Use reload transition type to avoid incorrect increase for typed count.
+  navigation.transition_type_ = ui::PAGE_TRANSITION_RELOAD;
+  navigation.timestamp_ = item.timestamp;
+
+  return navigation;
+}
+
 // static
 std::unique_ptr<web::NavigationItem>
 IOSSerializedNavigationBuilder::ToNavigationItem(
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
index 17e96fd..d93f242 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
@@ -207,7 +207,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   // Get the list of new account ids.
-  std::set<std::string> new_account_ids;
+  std::set<CoreAccountId> new_account_ids;
   for (const auto& new_account : provider_->GetAllAccounts()) {
     DCHECK(!new_account.gaia.empty());
     DCHECK(!new_account.email.empty());
@@ -216,7 +216,7 @@
     // the GAIA ID is available if any client of this token service starts
     // a fetch access token operation when it receives a
     // |OnRefreshTokenAvailable| notification.
-    std::string account_id = account_tracker_service_->SeedAccountInfo(
+    CoreAccountId account_id = account_tracker_service_->SeedAccountInfo(
         AccountInfoFromDeviceAccount(new_account));
     new_account_ids.insert(account_id);
   }
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
index 5374520..b0eeef2 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
@@ -99,7 +99,7 @@
     auth_error_changed_count_ = 0;
   }
 
-  std::string GetAccountId(const ProviderAccount& provider_account) {
+  CoreAccountId GetAccountId(const ProviderAccount& provider_account) {
     return account_tracker_.PickAccountIdForAccount(provider_account.gaia,
                                                     provider_account.email);
   }
@@ -139,7 +139,8 @@
   EXPECT_EQ(0, tokens_loaded_count_);
   EXPECT_EQ(1, token_revoked_count_);
   EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size());
-  EXPECT_FALSE(oauth2_delegate_->RefreshTokenIsAvailable("another_account"));
+  EXPECT_FALSE(oauth2_delegate_->RefreshTokenIsAvailable(
+      CoreAccountId("another_account")));
 }
 
 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
@@ -277,7 +278,7 @@
   ResetObserverCounts();
   GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_ERROR);
   oauth2_delegate_->UpdateAuthError(GetAccountId(account1), error);
-  EXPECT_EQ(error, oauth2_delegate_->GetAuthError("gaia_1"));
+  EXPECT_EQ(error, oauth2_delegate_->GetAuthError(GetAccountId(account1)));
   EXPECT_EQ(1, auth_error_changed_count_);
 
   oauth2_delegate_->RevokeAllCredentials();
@@ -292,15 +293,15 @@
   oauth2_delegate_->ReloadCredentials();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
-            oauth2_delegate_->GetAuthError("gaia_1"));
+            oauth2_delegate_->GetAuthError(GetAccountId(account1)));
   // Update the error.
   GoogleServiceAuthError error =
       GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
           GoogleServiceAuthError::InvalidGaiaCredentialsReason::
               CREDENTIALS_REJECTED_BY_SERVER);
-  oauth2_delegate_->UpdateAuthError("gaia_1", error);
-  EXPECT_EQ(error, oauth2_delegate_->GetAuthError("gaia_1"));
+  oauth2_delegate_->UpdateAuthError(GetAccountId(account1), error);
+  EXPECT_EQ(error, oauth2_delegate_->GetAuthError(GetAccountId(account1)));
   // Unknown account has no error.
   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
-            oauth2_delegate_->GetAuthError("gaia_2"));
+            oauth2_delegate_->GetAuthError(CoreAccountId("gaia_2")));
 }
diff --git a/components/storage_monitor/image_capture_device.mm b/components/storage_monitor/image_capture_device.mm
index 3b2b0207e..cfc9e1e 100644
--- a/components/storage_monitor/image_capture_device.mm
+++ b/components/storage_monitor/image_capture_device.mm
@@ -263,4 +263,36 @@
   NOTIMPLEMENTED();
 }
 
+// Mac 10.15 SDK methods, not yet implemented (https://crbug.com/849689)
+
+- (void)cameraDevice:(ICCameraDevice*)camera didRemoveItems:(NSArray*)items {
+  NOTIMPLEMENTED();
+}
+
+- (void)cameraDevice:(ICCameraDevice*)camera
+    didReceiveThumbnail:(CGImageRef)thumbnail
+                forItem:(ICCameraItem*)item
+                  error:(NSError*)error {
+  NOTIMPLEMENTED();
+}
+
+- (void)cameraDevice:(ICCameraDevice*)camera
+    didReceiveMetadata:(NSDictionary*)metadata
+               forItem:(ICCameraItem*)item
+                 error:(NSError*)error {
+  NOTIMPLEMENTED();
+}
+
+- (void)cameraDeviceDidEnableAccessRestriction:(ICDevice*)device {
+  NOTIMPLEMENTED();
+}
+
+- (void)cameraDeviceDidRemoveAccessRestriction:(ICDevice*)device {
+  NOTIMPLEMENTED();
+}
+
+- (void)device:(ICDevice*)device didCloseSessionWithError:(NSError*)error {
+  NOTIMPLEMENTED();
+}
+
 @end  // ImageCaptureDevice
diff --git a/components/sync/base/pref_names.cc b/components/sync/base/pref_names.cc
index 6a90cbb50..291d4ce7 100644
--- a/components/sync/base/pref_names.cc
+++ b/components/sync/base/pref_names.cc
@@ -28,6 +28,10 @@
 const char kSyncKeepEverythingSynced[] = "sync.keep_everything_synced";
 
 #if defined(OS_CHROMEOS)
+// Boolean indicating that the user has enabled the Chrome OS system-setting
+// sync feature.
+const char kOsSyncFeatureEnabled[] = "sync.os_sync_feature_enabled";
+
 // Boolean specifying whether to automatically sync all Chrome OS specific data
 // types (including future ones). This includes types like printers, OS-only
 // settings, etc. If set, the individual type preferences can be ignored.
diff --git a/components/sync/base/pref_names.h b/components/sync/base/pref_names.h
index ce39c2f..eae73ce 100644
--- a/components/sync/base/pref_names.h
+++ b/components/sync/base/pref_names.h
@@ -18,6 +18,7 @@
 extern const char kSyncKeepEverythingSynced[];
 
 #if defined(OS_CHROMEOS)
+extern const char kOsSyncFeatureEnabled[];
 extern const char kSyncAllOsTypes[];
 #endif
 
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index 7a7af515..8c310b32 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -282,6 +282,7 @@
     RegisterTypeSelectedPref(registry, type);
   }
 #if defined(OS_CHROMEOS)
+  registry->RegisterBooleanPref(prefs::kOsSyncFeatureEnabled, false);
   registry->RegisterBooleanPref(prefs::kSyncAllOsTypes, true);
   for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) {
     registry->RegisterBooleanPref(GetPrefNameForOsType(type), false);
@@ -520,6 +521,16 @@
     observer.OnPreferredDataTypesPrefChange();
   }
 }
+
+bool SyncPrefs::GetOsSyncFeatureEnabled() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return pref_service_->GetBoolean(prefs::kOsSyncFeatureEnabled);
+}
+
+void SyncPrefs::SetOsSyncFeatureEnabled(bool enabled) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetBoolean(prefs::kOsSyncFeatureEnabled, enabled);
+}
 #endif  // defined(OS_CHROMEOS)
 
 bool SyncPrefs::IsManaged() const {
diff --git a/components/sync/base/sync_prefs.h b/components/sync/base/sync_prefs.h
index 74e8c13..273e4f3 100644
--- a/components/sync/base/sync_prefs.h
+++ b/components/sync/base/sync_prefs.h
@@ -130,6 +130,8 @@
   void SetSelectedOsTypes(bool sync_all_os_types,
                           UserSelectableOsTypeSet registered_types,
                           UserSelectableOsTypeSet selected_types);
+  bool GetOsSyncFeatureEnabled() const;
+  void SetOsSyncFeatureEnabled(bool enabled);
 #endif
 
   // Whether Sync is forced off by enterprise policy. Note that this only covers
diff --git a/components/sync/driver/sync_auth_manager.cc b/components/sync/driver/sync_auth_manager.cc
index 060f597..3287a32e 100644
--- a/components/sync/driver/sync_auth_manager.cc
+++ b/components/sync/driver/sync_auth_manager.cc
@@ -437,12 +437,14 @@
   // Sign out of the old account (if any).
   if (!sync_account_.account_info.account_id.empty()) {
     sync_account_ = SyncAccountInfo();
+    // Let the client (SyncService) know of the removed account *before*
+    // throwing away the access token, so it can do "unregister" tasks.
+    account_state_changed_callback_.Run();
     // Also clear any pending request or auth errors we might have, since they
     // aren't meaningful anymore.
     partial_token_status_ = SyncTokenStatus();
     ClearAccessTokenAndRequest();
     SetLastAuthError(GoogleServiceAuthError::AuthErrorNone());
-    account_state_changed_callback_.Run();
   }
 
   // Sign in to the new account (if any).
diff --git a/components/sync/driver/sync_auth_manager_unittest.cc b/components/sync/driver/sync_auth_manager_unittest.cc
index b971d59..df83ccbe 100644
--- a/components/sync/driver/sync_auth_manager_unittest.cc
+++ b/components/sync/driver/sync_auth_manager_unittest.cc
@@ -136,6 +136,39 @@
   EXPECT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
             second_account_id);
 }
+
+TEST_F(SyncAuthManagerTest, NotifiesOfSignoutBeforeAccessTokenIsGone) {
+  // Start out already signed in before the SyncAuthManager is created.
+  CoreAccountId account_id =
+      identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
+
+  base::MockCallback<AccountStateChangedCallback> account_state_changed;
+  base::MockCallback<CredentialsChangedCallback> credentials_changed;
+  auto auth_manager =
+      CreateAuthManager(account_state_changed.Get(), base::DoNothing());
+
+  auth_manager->RegisterForAuthNotifications();
+
+  ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+            account_id);
+
+  auth_manager->ConnectionOpened();
+
+  // Make sure an access token is available.
+  identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now() + base::TimeDelta::FromHours(1));
+  ASSERT_EQ(auth_manager->GetCredentials().access_token, "access_token");
+
+  // Sign out of the account.
+  EXPECT_CALL(account_state_changed, Run()).WillOnce([&]() {
+    // At the time the callback gets run, the access token should still be here.
+    EXPECT_FALSE(auth_manager->GetCredentials().access_token.empty());
+  });
+  identity_env()->ClearPrimaryAccount();
+  // After the signout is complete, the access token should be gone.
+  EXPECT_TRUE(
+      auth_manager->GetActiveAccountInfo().account_info.account_id.empty());
+}
 #endif  // !defined(OS_CHROMEOS)
 
 // Unconsented primary accounts (aka secondary accounts) are only supported on
diff --git a/components/sync/driver/sync_user_settings.h b/components/sync/driver/sync_user_settings.h
index f5c6d73..159dcba 100644
--- a/components/sync/driver/sync_user_settings.h
+++ b/components/sync/driver/sync_user_settings.h
@@ -80,6 +80,11 @@
   virtual void SetSelectedOsTypes(bool sync_all_os_types,
                                   UserSelectableOsTypeSet types) = 0;
   virtual UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const = 0;
+
+  // Whether the OS sync feature is enabled. Implies the user has consented.
+  // Exists in this interface for easier mocking in tests.
+  virtual bool GetOsSyncFeatureEnabled() const = 0;
+  virtual void SetOsSyncFeatureEnabled(bool enabled) = 0;
 #endif  // defined(OS_CHROMEOS)
 
   // Encryption state.
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc
index 76426abb7..5c67c5b 100644
--- a/components/sync/driver/sync_user_settings_impl.cc
+++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -142,6 +142,14 @@
   }
   return registered_types;
 }
+
+bool SyncUserSettingsImpl::GetOsSyncFeatureEnabled() const {
+  return prefs_->GetOsSyncFeatureEnabled();
+}
+
+void SyncUserSettingsImpl::SetOsSyncFeatureEnabled(bool enabled) {
+  prefs_->SetOsSyncFeatureEnabled(enabled);
+}
 #endif  // defined(OS_CHROMEOS)
 
 UserSelectableTypeSet SyncUserSettingsImpl::GetForcedTypes() const {
diff --git a/components/sync/driver/sync_user_settings_impl.h b/components/sync/driver/sync_user_settings_impl.h
index 98f885a..d1fd467a6 100644
--- a/components/sync/driver/sync_user_settings_impl.h
+++ b/components/sync/driver/sync_user_settings_impl.h
@@ -54,6 +54,9 @@
   void SetSelectedOsTypes(bool sync_all_os_types,
                           UserSelectableOsTypeSet types) override;
   UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const override;
+
+  bool GetOsSyncFeatureEnabled() const override;
+  void SetOsSyncFeatureEnabled(bool enabled) override;
 #endif
 
   bool IsEncryptEverythingAllowed() const override;
diff --git a/components/sync/driver/sync_user_settings_mock.h b/components/sync/driver/sync_user_settings_mock.h
index 2f002ce..c630d39 100644
--- a/components/sync/driver/sync_user_settings_mock.h
+++ b/components/sync/driver/sync_user_settings_mock.h
@@ -38,6 +38,9 @@
   MOCK_CONST_METHOD0(GetSelectedOsTypes, UserSelectableOsTypeSet());
   MOCK_METHOD2(SetSelectedOsTypes, void(bool, UserSelectableOsTypeSet));
   MOCK_CONST_METHOD0(GetRegisteredSelectableOsTypes, UserSelectableOsTypeSet());
+
+  MOCK_CONST_METHOD0(GetOsSyncFeatureEnabled, bool());
+  MOCK_METHOD1(SetOsSyncFeatureEnabled, void(bool));
 #endif
 
   MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool());
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc
index cc649939..b0fe7aa 100644
--- a/components/sync/driver/test_sync_user_settings.cc
+++ b/components/sync/driver/test_sync_user_settings.cc
@@ -133,6 +133,14 @@
     const {
   return UserSelectableOsTypeSet::All();
 }
+
+bool TestSyncUserSettings::GetOsSyncFeatureEnabled() const {
+  return os_sync_feature_enabled_;
+}
+
+void TestSyncUserSettings::SetOsSyncFeatureEnabled(bool enabled) {
+  os_sync_feature_enabled_ = enabled;
+}
 #endif
 
 bool TestSyncUserSettings::IsEncryptEverythingAllowed() const {
diff --git a/components/sync/driver/test_sync_user_settings.h b/components/sync/driver/test_sync_user_settings.h
index 2bb7ebf..6ad37d7f 100644
--- a/components/sync/driver/test_sync_user_settings.h
+++ b/components/sync/driver/test_sync_user_settings.h
@@ -43,6 +43,9 @@
   void SetSelectedOsTypes(bool sync_all_os_types,
                           UserSelectableOsTypeSet types) override;
   UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const override;
+
+  bool GetOsSyncFeatureEnabled() const override;
+  void SetOsSyncFeatureEnabled(bool enabled) override;
 #endif
 
   bool IsEncryptEverythingAllowed() const override;
@@ -77,6 +80,7 @@
   bool first_setup_complete_ = true;
   bool sync_everything_enabled_ = true;
 #if defined(OS_CHROMEOS)
+  bool os_sync_feature_enabled_ = true;
   bool sync_all_os_types_enabled_ = true;
 #endif
 
diff --git a/components/test/data/autofill_assistant/html/form_target_website.html b/components/test/data/autofill_assistant/html/form_target_website.html
new file mode 100644
index 0000000..76c8546
--- /dev/null
+++ b/components/test/data/autofill_assistant/html/form_target_website.html
@@ -0,0 +1,43 @@
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="robots" content="noindex, nofollow">
+    <title>Form tests.</title>
+  </head>
+  <body>
+    <h3>Form filling</h3>
+
+    <h4>Credit card</h4>
+    <div>
+      <form id="form1" action="https://example.com/" method="post">
+        Name on card: <input type="text" id="name" name="name"/><br/>
+        Card Number: <input type="text" id="card_number" name="card_number"/><br/>
+        CVC: <input type="text" name="cv2_number" id="cv2_number"/><br/>
+        Expiry date: <select name="exp_month" id="exp_month">
+          <option value="01">01</option>
+          <option value="02">02</option>
+          <option value="03">03</option>
+          <option value="04">04</option>
+          <option value="05">05</option>
+          <option value="06">06</option>
+          <option value="07">07</option>
+          <option value="08">08</option>
+          <option value="09">09</option>
+          <option value="10">10</option>
+          <option value="11">11</option>
+          <option value="12">12</option>
+        </select>
+        <select name="exp_year" id="exp_year">
+          <option value="2019">2019</option>
+          <option value="2020">2020</option>
+          <option value="2021">2021</option>
+          <option value="2022">2022</option>
+          <option value="2023">2023</option>
+          <option value="2050">2050</option>
+        </select>
+      </form>
+    </div>
+  </body>
+</html>
+
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker.cc b/components/url_formatter/spoof_checks/idn_spoof_checker.cc
index bc26d591..fdcdcde 100644
--- a/components/url_formatter/spoof_checks/idn_spoof_checker.cc
+++ b/components/url_formatter/spoof_checks/idn_spoof_checker.cc
@@ -298,6 +298,11 @@
       icelandic_characters_.containsSome(label_string))
     return false;
 
+  // Disallow Latin Schwa (U+0259) for domains outside Azerbaijan's ccTLD (.az).
+  if (label_string.length() > 1 && top_level_domain != "az" &&
+      label_string.indexOf("É™") != -1)
+    return false;
+
   // If there's no script mixing, the input is regarded as safe without any
   // extra check unless it falls into one of three categories:
   //   - contains Kana letter exceptions
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
index 981a4c0..4e8363f 100644
--- a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
+++ b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
@@ -1123,6 +1123,10 @@
     {"xn--mnpqr-jta.com", L"mnðpqr.com", false},
     {"xn--acdef-wva.is", L"aþcdef.is", true},
     {"xn--mnpqr-jta.is", L"mnðpqr.is", true},
+
+    // U+0259 (É™) is only allowed under the .az TLD.
+    {"xn--xample-vyc.com", L"əxample.com", false},
+    {"xn--xample-vyc.az", L"əxample.az", true},
 };  // namespace
 
 namespace test {
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index 7fe0b75a..18b3f6d 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -124,10 +124,15 @@
 
     public_deps = [
       "//skia",
+      "//third_party/dawn/src/dawn:dawn_headers",
     ]
 
     deps = [
       "//base",
+      "//third_party/dawn:libdawn_native",
+      "//third_party/dawn:libdawn_native_sources",
+      "//third_party/dawn/src/dawn:dawncpp",
+      "//third_party/dawn/src/dawn:libdawn_proc",
     ]
   }
 }
diff --git a/components/viz/common/display/overlay_strategy.cc b/components/viz/common/display/overlay_strategy.cc
index 7dfdd63..1d647e8 100644
--- a/components/viz/common/display/overlay_strategy.cc
+++ b/components/viz/common/display/overlay_strategy.cc
@@ -9,7 +9,7 @@
 
 namespace viz {
 
-std::vector<OverlayStrategy> ParseOverlayStategies(
+std::vector<OverlayStrategy> ParseOverlayStrategies(
     const std::string& strategies_string) {
   std::vector<OverlayStrategy> strategies;
 
diff --git a/components/viz/common/display/overlay_strategy.h b/components/viz/common/display/overlay_strategy.h
index d88cc31..bd8d68af 100644
--- a/components/viz/common/display/overlay_strategy.h
+++ b/components/viz/common/display/overlay_strategy.h
@@ -26,7 +26,7 @@
 
 // Parses a comma separated list of overlay strategy types and returns a list
 // of the corresponding OverlayStrategy enum values.
-VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStategies(
+VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStrategies(
     const std::string& strategies_string);
 
 }  // namespace viz
diff --git a/components/viz/common/display/overlay_strategy_unittest.cc b/components/viz/common/display/overlay_strategy_unittest.cc
index 7df3227..d0c1299 100644
--- a/components/viz/common/display/overlay_strategy_unittest.cc
+++ b/components/viz/common/display/overlay_strategy_unittest.cc
@@ -16,13 +16,13 @@
 namespace viz {
 
 TEST(ParseOverlayStrategiesTest, ParseEmptyList) {
-  std::vector<OverlayStrategy> strategies = ParseOverlayStategies("");
+  std::vector<OverlayStrategy> strategies = ParseOverlayStrategies("");
   EXPECT_THAT(strategies, IsEmpty());
 }
 
 TEST(ParseOverlayStrategiesTest, ParseFullList) {
   std::vector<OverlayStrategy> strategies =
-      ParseOverlayStategies("single-fullscreen,single-on-top,underlay,cast");
+      ParseOverlayStrategies("single-fullscreen,single-on-top,underlay,cast");
 
   EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen,
                                                OverlayStrategy::kSingleOnTop,
@@ -32,7 +32,7 @@
 
 TEST(ParseOverlayStrategiesTest, BadValue) {
   std::vector<OverlayStrategy> strategies =
-      ParseOverlayStategies("single-fullscreen,bad-value,underlay");
+      ParseOverlayStrategies("single-fullscreen,bad-value,underlay");
 
   // The string "bad-value" doesn't correspond to an overlay strategy so it
   // should be skipped.
diff --git a/components/viz/common/gpu/DEPS b/components/viz/common/gpu/DEPS
index ba50fcbe2..5cbd28a 100644
--- a/components/viz/common/gpu/DEPS
+++ b/components/viz/common/gpu/DEPS
@@ -7,6 +7,7 @@
   "+gpu/command_buffer",
   "+gpu/GLES2/gl2extchromium.h",
   "+gpu/vulkan",
+  "+third_party/dawn/src/include",
   "+third_party/khronos/GLES2/gl2.h",
   "+third_party/skia/include/gpu",
   "+third_party/vulkan/include",
diff --git a/components/viz/common/gpu/dawn_context_provider.cc b/components/viz/common/gpu/dawn_context_provider.cc
index 0321686f..38fa7cd0 100644
--- a/components/viz/common/gpu/dawn_context_provider.cc
+++ b/components/viz/common/gpu/dawn_context_provider.cc
@@ -4,10 +4,28 @@
 
 #include "components/viz/common/gpu/dawn_context_provider.h"
 
+#include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "build/build_config.h"
+#include "third_party/dawn/src/include/dawn/dawn_proc.h"
 
 namespace viz {
 
+namespace {
+
+dawn_native::BackendType GetDefaultBackendType() {
+#if defined(OS_WIN)
+  return dawn_native::BackendType::D3D12;
+#elif defined(OS_LINUX)
+  return dawn_native::BackendType::Vulkan;
+#else
+  NOTREACHED();
+  return dawn_native::BackendType::Null;
+#endif
+}
+
+}  // namespace
+
 std::unique_ptr<DawnContextProvider> DawnContextProvider::Create() {
   auto context_provider = base::WrapUnique(new DawnContextProvider());
   if (!context_provider->IsValid())
@@ -15,8 +33,25 @@
   return context_provider;
 }
 
-DawnContextProvider::DawnContextProvider() = default;
+DawnContextProvider::DawnContextProvider() {
+  device_ = CreateDevice(GetDefaultBackendType());
+  if (device_)
+    gr_context_ = GrContext::MakeDawn(device_);
+}
 
 DawnContextProvider::~DawnContextProvider() = default;
 
+dawn::Device DawnContextProvider::CreateDevice(dawn_native::BackendType type) {
+  instance_.DiscoverDefaultAdapters();
+  DawnProcTable backend_procs = dawn_native::GetProcs();
+  dawnProcSetProcs(&backend_procs);
+
+  std::vector<dawn_native::Adapter> adapters = instance_.GetAdapters();
+  for (dawn_native::Adapter adapter : adapters) {
+    if (adapter.GetBackendType() == type)
+      return adapter.CreateDevice();
+  }
+  return nullptr;
+}
+
 }  // namespace viz
diff --git a/components/viz/common/gpu/dawn_context_provider.h b/components/viz/common/gpu/dawn_context_provider.h
index ef88a8a..b1d81b1 100644
--- a/components/viz/common/gpu/dawn_context_provider.h
+++ b/components/viz/common/gpu/dawn_context_provider.h
@@ -7,7 +7,9 @@
 
 #include "base/macros.h"
 #include "components/viz/common/viz_dawn_context_provider_export.h"
+#include "third_party/dawn/src/include/dawn_native/DawnNative.h"
 #include "third_party/skia/include/gpu/GrContext.h"
+#include "third_party/skia/include/gpu/dawn/GrDawnTypes.h"
 
 class GrContext;
 
@@ -18,12 +20,17 @@
   static std::unique_ptr<DawnContextProvider> Create();
   ~DawnContextProvider();
 
+  dawn::Device GetDevice() { return device_; }
   GrContext* GetGrContext() { return gr_context_.get(); }
   bool IsValid() { return !!gr_context_; }
 
  private:
   DawnContextProvider();
 
+  dawn::Device CreateDevice(dawn_native::BackendType type);
+
+  dawn_native::Instance instance_;
+  dawn::Device device_;
   sk_sp<GrContext> gr_context_;
 
   DISALLOW_COPY_AND_ASSIGN(DawnContextProvider);
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc
index f17aa1f..cb69e08 100644
--- a/components/viz/host/renderer_settings_creation.cc
+++ b/components/viz/host/renderer_settings_creation.cc
@@ -86,7 +86,7 @@
 
 #if defined(USE_OZONE)
   if (command_line->HasSwitch(switches::kEnableHardwareOverlays)) {
-    renderer_settings.overlay_strategies = ParseOverlayStategies(
+    renderer_settings.overlay_strategies = ParseOverlayStrategies(
         command_line->GetSwitchValueASCII(switches::kEnableHardwareOverlays));
   } else {
     auto& host_properties =
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 79aa878..bff4aa5 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -6,6 +6,7 @@
 import("//components/viz/viz.gni")
 import("//gpu/vulkan/features.gni")
 import("//media/gpu/args.gni")
+import("//skia/features.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 
 config("viz_service_implementation") {
@@ -391,6 +392,21 @@
     configs = [ "//build/config/linux:x11" ]
     deps += [ "//ui/gfx/x" ]
   }
+
+  if (skia_use_dawn) {
+    sources += [
+      "display_embedder/skia_output_device_dawn.cc",
+      "display_embedder/skia_output_device_dawn.h",
+    ]
+
+    public_deps += [ "//third_party/dawn/src/dawn:dawn_headers" ]
+
+    deps += [
+      "//third_party/dawn:libdawn_native",
+      "//third_party/dawn:libdawn_native_sources",
+      "//third_party/dawn/src/dawn:dawncpp",
+    ]
+  }
 }
 
 viz_source_set("unit_tests") {
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS
index 577b438e..38a3343 100644
--- a/components/viz/service/display_embedder/DEPS
+++ b/components/viz/service/display_embedder/DEPS
@@ -31,6 +31,7 @@
   "+mojo/public/cpp/bindings",
   "+mojo/public/cpp/system",
   "+skia",
+  "+third_party/dawn/src/include",
   "+third_party/khronos/GLES2/gl2.h",
   "+third_party/khronos/GLES2/gl2ext.h",
   "+third_party/skia",
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.cc b/components/viz/service/display_embedder/skia_output_device_dawn.cc
new file mode 100644
index 0000000..b2153b8
--- /dev/null
+++ b/components/viz/service/display_embedder/skia_output_device_dawn.cc
@@ -0,0 +1,121 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/skia_output_device_dawn.h"
+
+#include "base/logging.h"
+#include "build/build_config.h"
+#include "components/viz/common/gpu/dawn_context_provider.h"
+
+#if defined(OS_WIN)
+#include "third_party/dawn/src/include/dawn_native/D3D12Backend.h"
+#elif defined(OS_LINUX)
+#include "third_party/dawn/src/include/dawn_native/VulkanBackend.h"
+#endif
+
+namespace viz {
+
+namespace {
+
+// Some Vulkan drivers do not support kRGB_888x_SkColorType. Always use
+// kRGBA_8888_SkColorType instead and initialize surface to opaque as necessary.
+constexpr SkColorType kSurfaceColorType = kRGBA_8888_SkColorType;
+constexpr dawn::TextureFormat kSwapChainFormat =
+    dawn::TextureFormat::RGBA8Unorm;
+
+constexpr dawn::TextureUsage kUsage =
+    dawn::TextureUsage::OutputAttachment | dawn::TextureUsage::CopySrc;
+
+}  // namespace
+
+SkiaOutputDeviceDawn::SkiaOutputDeviceDawn(
+    DawnContextProvider* context_provider,
+    gfx::AcceleratedWidget widget,
+    DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
+    : SkiaOutputDevice(/*need_swap_semaphore=*/false,
+                       did_swap_buffer_complete_callback),
+      context_provider_(context_provider),
+      widget_(widget) {
+  capabilities_.supports_post_sub_buffer = false;
+}
+
+SkiaOutputDeviceDawn::~SkiaOutputDeviceDawn() = default;
+
+bool SkiaOutputDeviceDawn::Reshape(const gfx::Size& size,
+                                   float device_scale_factor,
+                                   const gfx::ColorSpace& color_space,
+                                   bool has_alpha,
+                                   gfx::OverlayTransform transform) {
+  DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
+
+  DiscardBackbuffer();
+  size_ = size;
+  sk_color_space_ = color_space.ToSkColorSpace();
+
+  CreateSwapChainImplementation();
+  dawn::SwapChainDescriptor desc;
+  desc.implementation = reinterpret_cast<int64_t>(&swap_chain_implementation_);
+  swap_chain_ = context_provider_->GetDevice().CreateSwapChain(&desc);
+  if (!swap_chain_)
+    return false;
+  swap_chain_.Configure(kSwapChainFormat, kUsage, size_.width(),
+                        size_.height());
+
+  EnsureBackbuffer();
+  return true;
+}
+
+void SkiaOutputDeviceDawn::SwapBuffers(
+    BufferPresentedCallback feedback,
+    std::vector<ui::LatencyInfo> latency_info) {
+  StartSwapBuffers(std::move(feedback));
+  swap_chain_.Present(texture_);
+  texture_ = swap_chain_.GetNextTexture();
+  FinishSwapBuffers(gfx::SwapResult::SWAP_ACK,
+                    gfx::Size(size_.width(), size_.height()),
+                    std::move(latency_info));
+}
+
+SkSurface* SkiaOutputDeviceDawn::BeginPaint() {
+  GrDawnImageInfo info;
+  info.fTexture = texture_;
+  info.fFormat = kSwapChainFormat;
+  info.fLevelCount = 1;
+  GrBackendTexture backend_texture(size_.width(), size_.height(), info);
+  DCHECK(backend_texture.isValid());
+  sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
+      context_provider_->GetGrContext(), backend_texture,
+      !capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin
+                                            : kBottomLeft_GrSurfaceOrigin,
+      /*sampleCount=*/0, kSurfaceColorType, sk_color_space_,
+      /*surfaceProps=*/nullptr);
+  return sk_surface_.get();
+}
+
+void SkiaOutputDeviceDawn::EndPaint(const GrBackendSemaphore& semaphore) {
+  GrFlushInfo flush_info;
+  sk_surface_->flush(SkSurface::BackendSurfaceAccess::kPresent, flush_info);
+  sk_surface_.reset();
+}
+
+void SkiaOutputDeviceDawn::EnsureBackbuffer() {
+  if (swap_chain_)
+    texture_ = swap_chain_.GetNextTexture();
+}
+
+void SkiaOutputDeviceDawn::DiscardBackbuffer() {
+  texture_ = nullptr;
+}
+
+void SkiaOutputDeviceDawn::CreateSwapChainImplementation() {
+#if defined(OS_WIN)
+  swap_chain_implementation_ = dawn_native::d3d12::CreateNativeSwapChainImpl(
+      context_provider_->GetDevice().Get(), widget_);
+#else
+  NOTREACHED();
+  ALLOW_UNUSED_LOCAL(widget_);
+#endif
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.h b/components/viz/service/display_embedder/skia_output_device_dawn.h
new file mode 100644
index 0000000..a39722b
--- /dev/null
+++ b/components/viz/service/display_embedder/skia_output_device_dawn.h
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_
+
+#include "components/viz/service/display_embedder/skia_output_device.h"
+#include "third_party/dawn/src/include/dawn/dawn_wsi.h"
+#include "third_party/dawn/src/include/dawn/dawncpp.h"
+#include "third_party/dawn/src/include/dawn_native/DawnNative.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+#include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace viz {
+
+class DawnContextProvider;
+
+class SkiaOutputDeviceDawn : public SkiaOutputDevice {
+ public:
+  SkiaOutputDeviceDawn(
+      DawnContextProvider* context_provider,
+      gfx::AcceleratedWidget widget,
+      DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
+  ~SkiaOutputDeviceDawn() override;
+
+  // SkiaOutputDevice implementation:
+  bool Reshape(const gfx::Size& size,
+               float device_scale_factor,
+               const gfx::ColorSpace& color_space,
+               bool has_alpha,
+               gfx::OverlayTransform transform) override;
+  void SwapBuffers(BufferPresentedCallback feedback,
+                   std::vector<ui::LatencyInfo> latency_info) override;
+  SkSurface* BeginPaint() override;
+  void EndPaint(const GrBackendSemaphore& semaphore) override;
+  void EnsureBackbuffer() override;
+  void DiscardBackbuffer() override;
+
+ private:
+  // Create a platform-specific swapchain implementation.
+  void CreateSwapChainImplementation();
+
+  DawnContextProvider* const context_provider_;
+  gfx::AcceleratedWidget widget_;
+  DawnSwapChainImplementation swap_chain_implementation_;
+  dawn::SwapChain swap_chain_;
+  dawn::Texture texture_;
+  sk_sp<SkSurface> sk_surface_;
+
+  gfx::Size size_;
+  sk_sp<SkColorSpace> sk_color_space_;
+  GrBackendTexture backend_texture_;
+
+  DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceDawn);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency.h b/components/viz/service/display_embedder/skia_output_surface_dependency.h
index f901706..2eb2156f 100644
--- a/components/viz/service/display_embedder/skia_output_surface_dependency.h
+++ b/components/viz/service/display_embedder/skia_output_surface_dependency.h
@@ -44,6 +44,7 @@
 
 namespace viz {
 
+class DawnContextProvider;
 class VulkanContextProvider;
 
 // This class exists to allow SkiaOutputSurfaceImpl to ignore differences
@@ -59,6 +60,7 @@
   // These are client thread methods. All other methods should be called on
   // the GPU thread only.
   virtual bool IsUsingVulkan() = 0;
+  virtual bool IsUsingDawn() = 0;
   // Returns a new task execution sequence. Sequences should not outlive the
   // task executor.
   virtual std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() = 0;
@@ -71,6 +73,8 @@
   virtual gpu::raster::GrShaderCache* GetGrShaderCache() = 0;
   // May return null.
   virtual VulkanContextProvider* GetVulkanContextProvider() = 0;
+  // May return null.
+  virtual DawnContextProvider* GetDawnContextProvider() = 0;
   virtual const gpu::GpuPreferences& GetGpuPreferences() = 0;
   virtual const gpu::GpuFeatureInfo& GetGpuFeatureInfo() = 0;
   virtual gpu::MailboxManager* GetMailboxManager() = 0;
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
index f90e12b2..83979b6 100644
--- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
@@ -33,6 +33,10 @@
   return gpu_service_impl_->is_using_vulkan();
 }
 
+bool SkiaOutputSurfaceDependencyImpl::IsUsingDawn() {
+  return gpu_service_impl_->is_using_dawn();
+}
+
 gpu::SharedImageManager*
 SkiaOutputSurfaceDependencyImpl::GetSharedImageManager() {
   return gpu_service_impl_->shared_image_manager();
@@ -62,6 +66,10 @@
   return gpu_service_impl_->vulkan_context_provider();
 }
 
+DawnContextProvider* SkiaOutputSurfaceDependencyImpl::GetDawnContextProvider() {
+  return gpu_service_impl_->dawn_context_provider();
+}
+
 const gpu::GpuPreferences&
 SkiaOutputSurfaceDependencyImpl::GetGpuPreferences() {
   return gpu_service_impl_->gpu_preferences();
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
index 27d32cc9..a113658 100644
--- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
+++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
@@ -26,12 +26,14 @@
 
   std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() override;
   bool IsUsingVulkan() override;
+  bool IsUsingDawn() override;
   gpu::SharedImageManager* GetSharedImageManager() override;
   gpu::SyncPointManager* GetSyncPointManager() override;
   const gpu::GpuDriverBugWorkarounds& GetGpuDriverBugWorkarounds() override;
   scoped_refptr<gpu::SharedContextState> GetSharedContextState() override;
   gpu::raster::GrShaderCache* GetGrShaderCache() override;
   VulkanContextProvider* GetVulkanContextProvider() override;
+  DawnContextProvider* GetDawnContextProvider() override;
   const gpu::GpuPreferences& GetGpuPreferences() override;
   const gpu::GpuFeatureInfo& GetGpuFeatureInfo() override;
   gpu::MailboxManager* GetMailboxManager() override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index 568a71a..95fdd006 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -31,6 +31,7 @@
 #include "gpu/ipc/service/context_url.h"
 #include "gpu/ipc/single_task_sequence.h"
 #include "gpu/vulkan/buildflags.h"
+#include "skia/buildflags.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_gl_api_implementation.h"
@@ -98,6 +99,41 @@
                                : OutputSurface::Type::kOpenGL;
 }
 
+#if BUILDFLAG(SKIA_USE_DAWN)
+// TODO(sgilhuly): Resolve conflicts with X11/X.h so that this can be moved to
+// resource_format_utils.cc.
+dawn::TextureFormat ToDawnFormat(ResourceFormat format) {
+  switch (format) {
+    case RGBA_8888:
+    case RGBX_8888:
+      return dawn::TextureFormat::RGBA8Unorm;
+    case BGRA_8888:
+    case BGRX_8888:
+      return dawn::TextureFormat::BGRA8Unorm;
+    case RED_8:
+    case ALPHA_8:
+    case LUMINANCE_8:
+      return dawn::TextureFormat::R8Unorm;
+    case RGBA_4444:
+    case RGB_565:
+    case BGR_565:
+    case RG_88:
+    case RGBA_F16:
+    case R16_EXT:
+    case RGBX_1010102:
+    case BGRX_1010102:
+    case YVU_420:
+    case YUV_420_BIPLANAR:
+    case ETC1:
+    case LUMINANCE_F16:
+    case P010:
+      break;
+  }
+  NOTREACHED() << "Unsupported format " << format;
+  return dawn::TextureFormat::Undefined;
+}
+#endif
+
 }  // namespace
 
 SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
@@ -132,7 +168,6 @@
     const RendererSettings& renderer_settings)
     : SkiaOutputSurface(GetOutputSurfaceType(deps.get())),
       dependency_(std::move(deps)),
-      is_using_vulkan_(dependency_->IsUsingVulkan()),
       renderer_settings_(renderer_settings) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
@@ -814,14 +849,7 @@
     ResourceFormat resource_format,
     uint32_t gl_texture_target,
     const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info) {
-  if (!is_using_vulkan_) {
-    DCHECK(!ycbcr_info);
-    // Convert internal format from GLES2 to platform GL.
-    unsigned int texture_storage_format = gpu::GetGrGLBackendTextureFormat(
-        impl_on_gpu_->GetFeatureInfo(), resource_format);
-
-    return GrBackendFormat::MakeGL(texture_storage_format, gl_texture_target);
-  } else {
+  if (dependency_->IsUsingVulkan()) {
 #if BUILDFLAG(ENABLE_VULKAN)
     if (!ycbcr_info) {
       // YCbCr info is required for YUV images.
@@ -836,11 +864,22 @@
                                           ->GetVulkanPhysicalDevice(),
                                       VK_IMAGE_TILING_OPTIMAL, ycbcr_info);
     return GrBackendFormat::MakeVk(gr_ycbcr_info);
-#else
-    NOTREACHED();
-    return GrBackendFormat();
 #endif
+  } else if (dependency_->IsUsingDawn()) {
+#if BUILDFLAG(SKIA_USE_DAWN)
+    dawn::TextureFormat format = ToDawnFormat(resource_format);
+    return GrBackendFormat::MakeDawn(format);
+#endif
+  } else {
+    DCHECK(!ycbcr_info);
+    // Convert internal format from GLES2 to platform GL.
+    unsigned int texture_storage_format = gpu::GetGrGLBackendTextureFormat(
+        impl_on_gpu_->GetFeatureInfo(), resource_format);
+
+    return GrBackendFormat::MakeGL(texture_storage_format, gl_texture_target);
   }
+  NOTREACHED();
+  return GrBackendFormat();
 }
 
 void SkiaOutputSurfaceImpl::SwapBuffers(OutputSurfaceFrame frame) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h
index 0af491dc..e2a4960 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -199,7 +199,6 @@
 
   uint64_t sync_fence_release_ = 0;
   std::unique_ptr<SkiaOutputSurfaceDependency> dependency_;
-  const bool is_using_vulkan_;
   UpdateVSyncParametersCallback update_vsync_parameters_callback_;
   GpuVSyncCallback gpu_vsync_callback_;
   bool is_displayed_as_overlay_ = false;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index 56975ad2..8db3c24 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -9,6 +9,7 @@
 #include "base/bind_helpers.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
+#include "base/debug/alias.h"
 #include "base/optional.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -46,6 +47,7 @@
 #include "gpu/ipc/common/gpu_client_ids.h"
 #include "gpu/ipc/common/gpu_surface_lookup.h"
 #include "gpu/vulkan/buildflags.h"
+#include "skia/buildflags.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
 #include "third_party/skia/include/private/SkDeferredDisplayList.h"
@@ -63,7 +65,7 @@
 #include "components/viz/service/display_embedder/skia_output_device_vulkan.h"
 #endif
 
-#if BUILDFLAG(ENABLE_VULKAN) && defined(USE_X11)
+#if (BUILDFLAG(ENABLE_VULKAN) || BUILDFLAG(SKIA_USE_DAWN)) && defined(USE_X11)
 #include "components/viz/service/display_embedder/skia_output_device_x11.h"
 #endif
 
@@ -73,6 +75,11 @@
 #include "ui/ozone/public/surface_factory_ozone.h"
 #endif
 
+#if BUILDFLAG(SKIA_USE_DAWN)
+#include "components/viz/common/gpu/dawn_context_provider.h"
+#include "components/viz/service/display_embedder/skia_output_device_dawn.h"
+#endif
+
 namespace viz {
 
 namespace {
@@ -625,6 +632,7 @@
       shared_image_representation_factory_(
           CreateSharedImageRepresentationFactory(dependency_)),
       vulkan_context_provider_(dependency_->GetVulkanContextProvider()),
+      dawn_context_provider_(dependency_->GetDawnContextProvider()),
       renderer_settings_(renderer_settings),
       sequence_id_(sequence_id),
       did_swap_buffer_complete_callback_(
@@ -891,9 +899,14 @@
     DCHECK(offscreen.surface());
   } else {
 #if DCHECK_IS_ON()
+    // TODO(crbug.com/1022304): Remove aliasing after figuring out how
+    // characterizations are different.
     SkSurfaceCharacterization characterization;
-    DCHECK(offscreen.surface()->characterize(&characterization) &&
-           characterization == ddl->characterization());
+    DCHECK(offscreen.surface()->characterize(&characterization));
+    base::debug::Alias(&characterization);
+    SkSurfaceCharacterization ddl_characterization = ddl->characterization();
+    base::debug::Alias(&ddl_characterization);
+    DCHECK(characterization == ddl_characterization);
 #endif
   }
   {
@@ -962,8 +975,8 @@
       base::BindOnce([](std::vector<std::unique_ptr<SkDeferredDisplayList>>) {},
                      std::move(destroy_after_swap_)));
 
-  bool use_gl_renderer_copier =
-      !is_using_vulkan() && !features::IsUsingSkiaForGLReadback();
+  bool use_gl_renderer_copier = !is_using_vulkan() && !is_using_dawn() &&
+                                !features::IsUsingSkiaForGLReadback();
   if (use_gl_renderer_copier)
     gpu::ContextUrl::SetActiveUrl(copier_active_url_);
 
@@ -1283,8 +1296,16 @@
           ->CreatePlatformWindowSurface(dependency_->GetSurfaceHandle());
 #endif
 
-  if (!(is_using_vulkan() ? InitializeForVulkan() : InitializeForGL()))
-    return false;
+  if (is_using_vulkan()) {
+    if (!InitializeForVulkan())
+      return false;
+  } else if (is_using_dawn()) {
+    if (!InitializeForDawn())
+      return false;
+  } else {
+    if (!InitializeForGL())
+      return false;
+  }
   max_resource_cache_bytes_ = context_state_->max_resource_cache_bytes();
   return true;
 }
@@ -1378,6 +1399,33 @@
   return true;
 }
 
+bool SkiaOutputSurfaceImplOnGpu::InitializeForDawn() {
+  context_state_ = dependency_->GetSharedContextState();
+  DCHECK(context_state_);
+#if BUILDFLAG(SKIA_USE_DAWN)
+  if (dependency_->IsOffscreen()) {
+    output_device_ = std::make_unique<SkiaOutputDeviceOffscreen>(
+        context_state_, false /* flipped */,
+        renderer_settings_.requires_alpha_channel,
+        did_swap_buffer_complete_callback_);
+    supports_alpha_ = renderer_settings_.requires_alpha_channel;
+  } else {
+#if defined(USE_X11)
+    // TODO(sgilhuly): Set up a Vulkan swapchain so that Linux can also use
+    // SkiaOutputDeviceDawn.
+    output_device_ = std::make_unique<SkiaOutputDeviceX11>(
+        context_state_, dependency_->GetSurfaceHandle(),
+        did_swap_buffer_complete_callback_);
+#else
+    output_device_ = std::make_unique<SkiaOutputDeviceDawn>(
+        dawn_context_provider_, dependency_->GetSurfaceHandle(),
+        did_swap_buffer_complete_callback_);
+#endif
+  }
+#endif
+  return true;
+}
+
 bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) {
   if (!is_using_vulkan()) {
     if (context_state_->context_lost())
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index f3b5952..852c5a97 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -60,9 +60,10 @@
 
 namespace viz {
 
+class DawnContextProvider;
 class DirectContextProvider;
-class ImageContextImpl;
 class GLRendererCopier;
+class ImageContextImpl;
 class SkiaOutputSurfaceDependency;
 class TextureDeleter;
 class VulkanContextProvider;
@@ -205,6 +206,7 @@
   bool Initialize();
   bool InitializeForGL();
   bool InitializeForVulkan();
+  bool InitializeForDawn();
 
   // Make context current for GL, and return false if the context is lost.
   // It will do nothing when Vulkan is used.
@@ -224,6 +226,10 @@
     return !!vulkan_context_provider_ &&
            gpu_preferences_.gr_context_type == gpu::GrContextType::kVulkan;
   }
+  bool is_using_dawn() const {
+    return !!dawn_context_provider_ &&
+           gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn;
+  }
 
   SkSurface* output_sk_surface() const {
     return scoped_output_device_paint_->sk_surface();
@@ -235,6 +241,7 @@
   std::unique_ptr<gpu::SharedImageRepresentationFactory>
       shared_image_representation_factory_;
   VulkanContextProvider* const vulkan_context_provider_;
+  DawnContextProvider* const dawn_context_provider_;
   const RendererSettings renderer_settings_;
   // This is only used to lazily create DirectContextProviderDelegate for
   // readback using GLRendererCopier.
diff --git a/components/viz/service/gl/DEPS b/components/viz/service/gl/DEPS
index a24294a..4402b88 100644
--- a/components/viz/service/gl/DEPS
+++ b/components/viz/service/gl/DEPS
@@ -15,6 +15,7 @@
   "+media/gpu",
   "+media/mojo",
   "+mojo/public/cpp",
+  "+skia/buildflags.h",
   "+services/viz/privileged/mojom",
   "+ui/gl",
 ]
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index d38dfac5..8ac4e0e 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -50,6 +50,7 @@
 #include "media/gpu/ipc/service/media_gpu_channel_manager.h"
 #include "media/mojo/services/mojo_video_encode_accelerator_provider.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "skia/buildflags.h"
 #include "third_party/skia/include/gpu/GrContext.h"
 #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
@@ -89,6 +90,10 @@
 #include "ui/base/cocoa/quartz_util.h"
 #endif
 
+#if BUILDFLAG(SKIA_USE_DAWN)
+#include "components/viz/common/gpu/dawn_context_provider.h"
+#endif
+
 namespace viz {
 
 namespace {
@@ -180,6 +185,19 @@
   }
 #endif
 
+#if BUILDFLAG(SKIA_USE_DAWN)
+  if (gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn) {
+    dawn_context_provider_ = DawnContextProvider::Create();
+    if (dawn_context_provider_) {
+      gpu_info_.oop_rasterization_supported = true;
+      gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+          gpu::kGpuFeatureStatusEnabled;
+    } else {
+      DLOG(WARNING) << "Failed to create Dawn context provider.";
+    }
+  }
+#endif
+
 #if BUILDFLAG(USE_VAAPI)
   image_decode_accelerator_worker_ =
       media::VaapiImageDecodeAcceleratorWorker::Create();
@@ -330,7 +348,7 @@
       gpu_memory_buffer_factory_.get(), gpu_feature_info_,
       std::move(activity_flags), std::move(default_offscreen_surface),
       image_decode_accelerator_worker_.get(), vulkan_context_provider(),
-      metal_context_provider_.get());
+      metal_context_provider_.get(), dawn_context_provider());
 
   media_gpu_channel_manager_.reset(
       new media::MediaGpuChannelManager(gpu_channel_manager_.get()));
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h
index 7919309..50d2003 100644
--- a/components/viz/service/gl/gpu_service_impl.h
+++ b/components/viz/service/gl/gpu_service_impl.h
@@ -38,6 +38,7 @@
 #include "mojo/public/cpp/bindings/shared_remote.h"
 #include "services/viz/privileged/mojom/gl/gpu_host.mojom.h"
 #include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
+#include "skia/buildflags.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -69,6 +70,7 @@
 
 class VulkanContextProvider;
 class MetalContextProvider;
+class DawnContextProvider;
 
 // This runs in the GPU process, and communicates with the gpu host (which is
 // the window server) over the mojom APIs. This is responsible for setting up
@@ -268,6 +270,16 @@
   VulkanContextProvider* vulkan_context_provider() { return nullptr; }
 #endif
 
+#if BUILDFLAG(SKIA_USE_DAWN)
+  bool is_using_dawn() const { return !!dawn_context_provider_; }
+  DawnContextProvider* dawn_context_provider() {
+    return dawn_context_provider_.get();
+  }
+#else
+  bool is_using_dawn() const { return false; }
+  DawnContextProvider* dawn_context_provider() { return nullptr; }
+#endif
+
   void set_oopd_enabled() { oopd_enabled_ = true; }
 
  private:
@@ -344,6 +356,9 @@
   scoped_refptr<VulkanContextProvider> vulkan_context_provider_;
 #endif
   std::unique_ptr<MetalContextProvider> metal_context_provider_;
+#if BUILDFLAG(SKIA_USE_DAWN)
+  std::unique_ptr<DawnContextProvider> dawn_context_provider_;
+#endif
 
   std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
 
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.cc b/content/browser/accessibility/accessibility_tree_formatter_base.cc
index 0340968f..90ac4e5 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_base.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_base.cc
@@ -52,10 +52,8 @@
     formatter = Create();
   base::string16 accessibility_contents_utf16;
   formatter->SetPropertyFilters(property_filters);
-  std::unique_ptr<base::DictionaryValue> dict =
-      static_cast<AccessibilityTreeFormatterBase*>(formatter.get())
-          ->BuildAccessibilityTree(ax_mgr->GetRoot());
-  formatter->FormatAccessibilityTree(*dict, &accessibility_contents_utf16);
+  formatter->FormatAccessibilityTree(ax_mgr->GetRoot(),
+                                     &accessibility_contents_utf16);
   return accessibility_contents_utf16;
 }
 
@@ -97,11 +95,12 @@
   return false;
 }
 
-AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase() = default;
+AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase()
+    : show_ids_(false) {}
 
-AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() = default;
+AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() {}
 
-void AccessibilityTreeFormatterBase::FormatAccessibilityTreeForTesting(
+void AccessibilityTreeFormatterBase::FormatAccessibilityTree(
     BrowserAccessibility* root,
     base::string16* contents) {
   std::unique_ptr<base::DictionaryValue> dict = BuildAccessibilityTree(root);
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.h b/content/browser/accessibility/accessibility_tree_formatter_base.h
index 56e7244e..7b1f6b5 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_base.h
+++ b/content/browser/accessibility/accessibility_tree_formatter_base.h
@@ -66,14 +66,13 @@
   virtual std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
       BrowserAccessibility* root) = 0;
 
-  void FormatAccessibilityTreeForTesting(BrowserAccessibility* root,
-                                         base::string16* contents);
-
   // AccessibilityTreeFormatter overrides.
   void AddDefaultFilters(
       std::vector<PropertyFilter>* property_filters) override;
   std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree(
       const base::DictionaryValue& dict) override;
+  void FormatAccessibilityTree(BrowserAccessibility* root,
+                               base::string16* contents) override;
   void FormatAccessibilityTree(const base::DictionaryValue& tree_node,
                                base::string16* contents) override;
   void SetPropertyFilters(
@@ -150,7 +149,7 @@
   std::vector<NodeFilter> node_filters_;
 
   // Whether or not node ids should be included in the dump.
-  bool show_ids_ = false;
+  bool show_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatterBase);
 };
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index cd80daa..af04bfe 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -38,7 +38,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/accessibility_notification_waiter.h"
-#include "content/public/test/browser_accessibility.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/content_browser_test_utils_internal.h"
@@ -129,9 +128,9 @@
   DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
 };
 
-AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() = default;
+AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {}
 
-AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() = default;
+AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {}
 
 base::string16 AccessibilityWinBrowserTest::PrintAXTree() const {
   std::unique_ptr<AccessibilityTreeFormatter> formatter(
@@ -142,8 +141,11 @@
       L"*", AccessibilityTreeFormatter::PropertyFilter::ALLOW)});
 
   base::string16 str;
-  TestBrowserAccessibility::FormatAccessibilityTree(
-      formatter.get(), GetRootAccessibilityNode(shell()->web_contents()), &str);
+  formatter->FormatAccessibilityTree(
+      static_cast<WebContentsImpl*>(shell()->web_contents())
+          ->GetRootBrowserAccessibilityManager()
+          ->GetRoot(),
+      &str);
   return str;
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index f67d71a..22302d7 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -525,7 +525,8 @@
     }
   }
 
-  if (text.empty() && (ui::IsLink(GetRole()) || ui::IsImage(GetRole())) &&
+  if (text.empty() &&
+      (ui::IsLink(GetRole()) || ui::IsImageOrVideo(GetRole())) &&
       !HasExplicitlyEmptyName()) {
     base::string16 url = GetString16Attribute(ax::mojom::StringAttribute::kUrl);
     text = ui::AXUrlBaseText(url);
@@ -1700,7 +1701,7 @@
 }
 
 base::string16 BrowserAccessibilityAndroid::GetTargetUrl() const {
-  if (ui::IsImage(GetRole()) || ui::IsLink(GetRole()))
+  if (ui::IsImageOrVideo(GetRole()) || ui::IsLink(GetRole()))
     return GetString16Attribute(ax::mojom::StringAttribute::kUrl);
 
   return {};
@@ -1723,7 +1724,7 @@
 }
 
 bool BrowserAccessibilityAndroid::HasImage() const {
-  if (ui::IsImage(GetRole()))
+  if (ui::IsImageOrVideo(GetRole()))
     return true;
 
   for (auto it = InternalChildrenBegin(); it != InternalChildrenEnd(); ++it) {
@@ -1749,7 +1750,7 @@
   for (auto it = InternalChildrenBegin(); it != InternalChildrenEnd(); ++it) {
     BrowserAccessibility* child = it.get();
     if (child->GetRole() != ax::mojom::Role::kStaticText &&
-        !ui::IsImage(child->GetRole())) {
+        !ui::IsImageOrVideo(child->GetRole())) {
       return false;
     }
   }
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 8a61098..a93abd7 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1590,19 +1590,10 @@
     return E_NOINTERFACE;
   }
 
-  int32_t ia_role = accessibility->MSAARole();
+  ax::mojom::Role role = accessibility->owner()->GetRole();
+
   if (iid == IID_IAccessibleImage) {
-    if (ia_role != ROLE_SYSTEM_GRAPHIC) {
-      *object = nullptr;
-      return E_NOINTERFACE;
-    }
-  } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) {
-    if (!ui::IsTableLike(accessibility->owner()->GetRole())) {
-      *object = nullptr;
-      return E_NOINTERFACE;
-    }
-  } else if (iid == IID_IAccessibleTableCell) {
-    if (!ui::IsCellOrTableHeader(accessibility->owner()->GetRole())) {
+    if (!ui::IsImage(role)) {
       *object = nullptr;
       return E_NOINTERFACE;
     }
@@ -1612,7 +1603,7 @@
       return E_NOINTERFACE;
     }
   } else if (iid == IID_ISimpleDOMDocument) {
-    if (ia_role != ROLE_SYSTEM_DOCUMENT) {
+    if (!ui::IsDocument(role)) {
       *object = nullptr;
       return E_NOINTERFACE;
     }
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index 55b6b10..d7078fd9 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -31,7 +31,6 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/accessibility_notification_waiter.h"
-#include "content/public/test/browser_accessibility.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
@@ -134,9 +133,11 @@
       PropertyFilter(base::ASCIIToUTF16("*"), PropertyFilter::ALLOW));
   formatter->SetPropertyFilters(property_filters);
   formatter->set_show_ids(true);
+  WebContentsImpl* web_contents =
+      static_cast<WebContentsImpl*>(shell()->web_contents());
   base::string16 ax_tree_dump;
-  TestBrowserAccessibility::FormatAccessibilityTree(
-      formatter.get(), GetRootAccessibilityNode(shell()->web_contents()),
+  formatter->FormatAccessibilityTree(
+      web_contents->GetRootBrowserAccessibilityManager()->GetRoot(),
       &ax_tree_dump);
   return ax_tree_dump;
 }
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.h b/content/browser/accessibility/dump_accessibility_browsertest_base.h
index 5577b91..cbea701b 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.h
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_
 #define CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_
 
-#include <memory>
 #include <string>
 #include <vector>
 
@@ -17,8 +16,6 @@
 
 namespace content {
 
-class BrowserAccessibility;
-
 // Base class for an accessibility browsertest that takes an HTML file as
 // input, loads it into a tab, dumps some accessibility data in text format,
 // then compares that text to an expectation file in the same directory.
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 50b8c8808..85c4bf68 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -23,7 +23,6 @@
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/accessibility_notification_waiter.h"
-#include "content/public/test/browser_accessibility.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "ui/accessibility/accessibility_switches.h"
@@ -148,8 +147,10 @@
     formatter->SetPropertyFilters(property_filters_);
     formatter->SetNodeFilters(node_filters_);
     base::string16 actual_contents_utf16;
-    TestBrowserAccessibility::FormatAccessibilityTree(
-        formatter.get(), GetRootAccessibilityNode(shell()->web_contents()),
+    WebContentsImpl* web_contents =
+        static_cast<WebContentsImpl*>(shell()->web_contents());
+    formatter->FormatAccessibilityTree(
+        web_contents->GetRootBrowserAccessibilityManager()->GetRoot(),
         &actual_contents_utf16);
     std::string actual_contents = base::UTF16ToUTF8(actual_contents_utf16);
     return base::SplitString(actual_contents, "\n", base::KEEP_WHITESPACE,
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
index 41b49ab..6229835 100644
--- a/content/browser/accessibility/one_shot_accessibility_tree_search.cc
+++ b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -294,7 +294,7 @@
 
 bool AccessibilityGraphicPredicate(BrowserAccessibility* start,
                                    BrowserAccessibility* node) {
-  return ui::IsImage(node->GetRole());
+  return ui::IsImageOrVideo(node->GetRole());
 }
 
 bool AccessibilityHeadingPredicate(BrowserAccessibility* start,
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index adecb5d..5d17142c 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -327,6 +327,34 @@
   base::Optional<SkColor> color_;
 };
 
+class DOMContentLoadedObserver : public WebContentsObserver {
+ public:
+  explicit DOMContentLoadedObserver(RenderFrameHostImpl* render_frame_host)
+      : WebContentsObserver(
+            WebContents::FromRenderFrameHost(render_frame_host)),
+        render_frame_host_(render_frame_host) {}
+
+  void DOMContentLoaded(RenderFrameHost* render_frame_host) override {
+    if (render_frame_host_ == render_frame_host)
+      run_loop_.Quit();
+  }
+
+  void Wait() {
+    if (render_frame_host_->dom_content_loaded())
+      run_loop_.Quit();
+    run_loop_.Run();
+  }
+
+ private:
+  RenderFrameHostImpl* render_frame_host_;
+  base::RunLoop run_loop_;
+};
+
+void WaitForDOMContentLoaded(RenderFrameHostImpl* rfh) {
+  DOMContentLoadedObserver observer(rfh);
+  observer.Wait();
+}
+
 }  // namespace
 
 // Navigate from A to B and go back.
@@ -1445,6 +1473,10 @@
 
   // The navigation finishes while the image is still loading.
   navigation_manager.WaitForNavigationFinished();
+  // Wait for the document to load DOM to ensure that kLoading is not
+  // one of the reasons why the document wasn't cached.
+  WaitForDOMContentLoaded(current_frame_host());
+
   RenderFrameDeletedObserver delete_observer_rfh_a(current_frame_host());
 
   // 2) Navigate away.
@@ -3652,6 +3684,32 @@
   EXPECT_TRUE(observer.did_fire());
 }
 
+// Check that back-forward cache is disabled when PermissionService is used.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, PermissionServiceContext) {
+  content::BackForwardCacheDisabledTester tester;
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  const GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  // 1) Navigate to A.
+  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  auto* rfh = current_frame_host();
+  int process_id = rfh->GetProcess()->GetID();
+  int frame_routing_id = rfh->GetRoutingID();
+
+  // 2) Invoke PermissionService.
+  EXPECT_TRUE(ExecJs(rfh, R"(
+          navigator.permissions.query({ name: "geolocation" })
+          )"));
+
+  // 3) Navigate to B.
+  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+
+  // 4) Check that back-forward cache is disabled for A.
+  EXPECT_TRUE(tester.IsDisabledForFrameWithReason(process_id, frame_routing_id,
+                                                  "PermissionServiceContext"));
+}
+
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                        SetsThemeColorWhenRestoredFromCache) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index b2759ee9..81209f6 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -1303,8 +1303,7 @@
   modified_request_headers_.Clear();
   removed_request_headers_.clear();
 
-  // TODO(zetamoo): Refactor NavigationThrottleRunner to accept one argument.
-  throttle_runner_ = base::WrapUnique(new NavigationThrottleRunner(this, this));
+  throttle_runner_ = base::WrapUnique(new NavigationThrottleRunner(this));
 
 #if defined(OS_ANDROID)
   navigation_handle_proxy_ = std::make_unique<NavigationHandleProxy>(this);
@@ -1823,8 +1822,7 @@
   }
 
   // https://mikewest.github.io/corpp/#process-navigation-response
-  if (base::FeatureList::IsEnabled(
-          network::features::kCrossOriginEmbedderPolicy) &&
+  if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation) &&
       render_frame_host_) {
     auto cross_origin_embedder_policy =
         network::mojom::CrossOriginEmbedderPolicy::kNone;
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 7ee3b27..f3e8b9b 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -72,10 +72,11 @@
 // ResourceDispatcherHost (that lives on the IO thread).
 // TODO(clamy): Describe the interactions between the UI and IO thread during
 // the navigation following its refactoring.
-class CONTENT_EXPORT NavigationRequest : public NavigationHandle,
-                                         public NavigationURLLoaderDelegate,
-                                         NavigationThrottleRunner::Delegate,
-                                         private RenderProcessHostObserver {
+class CONTENT_EXPORT NavigationRequest
+    : public NavigationHandle,
+      public NavigationURLLoaderDelegate,
+      public NavigationThrottleRunner::Delegate,
+      private RenderProcessHostObserver {
  public:
   // Keeps track of the various stages of a NavigationRequest.
   enum NavigationState {
diff --git a/content/browser/frame_host/navigation_throttle_runner.cc b/content/browser/frame_host/navigation_throttle_runner.cc
index 972ba307..f426a33 100644
--- a/content/browser/frame_host/navigation_throttle_runner.cc
+++ b/content/browser/frame_host/navigation_throttle_runner.cc
@@ -58,9 +58,8 @@
 
 }  // namespace
 
-NavigationThrottleRunner::NavigationThrottleRunner(Delegate* delegate,
-                                                   NavigationHandle* handle)
-    : delegate_(delegate), handle_(handle) {}
+NavigationThrottleRunner::NavigationThrottleRunner(Delegate* delegate)
+    : delegate_(delegate) {}
 
 NavigationThrottleRunner::~NavigationThrottleRunner() = default;
 
@@ -91,43 +90,48 @@
   std::vector<std::unique_ptr<NavigationThrottle>> testing_throttles =
       std::move(throttles_);
 
-  throttles_ = NavigationRequest::From(handle_)
-                   ->GetDelegate()
-                   ->CreateThrottlesForNavigation(handle_);
+  // The NavigationRequest associated with the NavigationThrottles this
+  // NavigationThrottleRunner manages.
+  // Unit tests that do not use NavigationRequest should never call
+  // RegisterNavigationThrottles as this function expects |delegate_| to be a
+  // NavigationRequest.
+  NavigationRequest* request = static_cast<NavigationRequest*>(delegate_);
+
+  throttles_ = request->GetDelegate()->CreateThrottlesForNavigation(request);
 
   // Enforce rules for WebUI navigations.
-  AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(handle_));
+  AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(request));
 
   // Check for renderer-inititated main frame navigations to blocked URL schemes
   // (data, filesystem). This is done early as it may block the main frame
   // navigation altogether.
   AddThrottle(
-      BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(handle_));
+      BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(request));
 
-  AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(handle_));
-  AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(handle_));
+  AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(request));
+  AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(request));
 
   // Check for mixed content. This is done after the AncestorThrottle and the
   // FormSubmissionThrottle so that when folks block mixed content with a CSP
   // policy, they don't get a warning. They'll still get a warning in the
   // console about CSP blocking the load.
   AddThrottle(
-      MixedContentNavigationThrottle::CreateThrottleForNavigation(handle_));
+      MixedContentNavigationThrottle::CreateThrottleForNavigation(request));
 
   // Handle Origin Policy (if enabled)
-  AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(handle_));
+  AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(request));
 
   // Block certain requests that are not permitted for portals.
-  AddThrottle(PortalNavigationThrottle::MaybeCreateThrottleFor(handle_));
+  AddThrottle(PortalNavigationThrottle::MaybeCreateThrottleFor(request));
 
   for (auto& throttle :
-       devtools_instrumentation::CreateNavigationThrottles(handle_)) {
+       devtools_instrumentation::CreateNavigationThrottles(request)) {
     AddThrottle(std::move(throttle));
   }
 
   // Delay navigation for an ablation study (if needed).
   AddThrottle(HistoryNavigationAblationStudyNavigationThrottle::
-                  MaybeCreateForNavigation(handle_));
+                  MaybeCreateForNavigation(request));
 
   // Insert all testing NavigationThrottles last.
   throttles_.insert(throttles_.end(),
@@ -161,7 +165,7 @@
       return;
     }
     TRACE_EVENT_ASYNC_STEP_INTO0(
-        "navigation", "NavigationHandle", handle_,
+        "navigation", "NavigationHandle", delegate_,
         base::StringPrintf("%s: %s: %d", GetEventName(current_event_),
                            throttles_[i]->GetNameForLogging(),
                            result.action()));
diff --git a/content/browser/frame_host/navigation_throttle_runner.h b/content/browser/frame_host/navigation_throttle_runner.h
index fc388d82..b4772a45 100644
--- a/content/browser/frame_host/navigation_throttle_runner.h
+++ b/content/browser/frame_host/navigation_throttle_runner.h
@@ -36,7 +36,7 @@
         NavigationThrottle::ThrottleCheckResult result) = 0;
   };
 
-  NavigationThrottleRunner(Delegate* delegate, NavigationHandle* handle);
+  NavigationThrottleRunner(Delegate* delegate);
   ~NavigationThrottleRunner();
 
   // Will call the appropriate NavigationThrottle function based on |event| on
@@ -70,14 +70,6 @@
 
   Delegate* delegate_;
 
-  // The NavigationHandle associated with the NavigationThrottles this
-  // NavigationThrottleRunner manages.
-  // Note: |handle_| is not defined as a NavigationRequest* so that a
-  // MockNavigationHandle can be used in unit_tests. Unit tests that use a
-  // MockNavigationHandle should never call RegisterNavigationThrottles as this
-  // function expects |handle_| to be a NavigationRequest instead.
-  NavigationHandle* handle_;
-
   // A list of Throttles registered for this navigation.
   std::vector<std::unique_ptr<NavigationThrottle>> throttles_;
 
diff --git a/content/browser/frame_host/navigation_throttle_runner_unittest.cc b/content/browser/frame_host/navigation_throttle_runner_unittest.cc
index 01e6492..fc86076 100644
--- a/content/browser/frame_host/navigation_throttle_runner_unittest.cc
+++ b/content/browser/frame_host/navigation_throttle_runner_unittest.cc
@@ -60,7 +60,7 @@
 
   void SetUp() override {
     RenderViewHostTestHarness::SetUp();
-    runner_ = std::make_unique<NavigationThrottleRunner>(this, &handle_);
+    runner_ = std::make_unique<NavigationThrottleRunner>(this);
   }
 
   void Resume() { runner_->CallResumeForTesting(); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 311644f..c7c0091 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2352,12 +2352,13 @@
   return top_document_url;
 }
 
-void RenderFrameHostImpl::SetOriginOfNewFrame(
+void RenderFrameHostImpl::SetOriginAndNetworkIsolationKeyOfNewFrame(
     const url::Origin& new_frame_creator) {
   // This method should only be called for *new* frames, that haven't committed
   // a navigation yet.
   DCHECK(!has_committed_any_navigation_);
   DCHECK(GetLastCommittedOrigin().opaque());
+  DCHECK(network_isolation_key_.IsEmpty());
 
   // Calculate and set |new_frame_origin|.
   bool new_frame_should_be_sandboxed =
@@ -2367,6 +2368,8 @@
   url::Origin new_frame_origin = new_frame_should_be_sandboxed
                                      ? new_frame_creator.DeriveNewOpaqueOrigin()
                                      : new_frame_creator;
+  network_isolation_key_ = net::NetworkIsolationKey(
+      ComputeTopFrameOrigin(new_frame_origin), new_frame_origin);
   SetLastCommittedOrigin(new_frame_origin);
 }
 
@@ -2391,9 +2394,11 @@
   frame_tree_node_->render_manager()->CreateProxiesForChildFrame(child.get());
 
   // When the child is added, it hasn't committed any navigation yet - its
-  // initial empty document should inherit the origin of its parent (the origin
-  // may change after the first commit).  See also https://crbug.com/932067.
-  child->current_frame_host()->SetOriginOfNewFrame(GetLastCommittedOrigin());
+  // initial empty document should inherit the origin and network isolation key
+  // of its parent (the origin may change after the first commit). See also
+  // https://crbug.com/932067.
+  child->current_frame_host()->SetOriginAndNetworkIsolationKeyOfNewFrame(
+      GetLastCommittedOrigin());
 
   children_.push_back(std::move(child));
   return children_.back().get();
@@ -4369,14 +4374,16 @@
   RenderFrameHostImpl* main_frame = new_window->GetMainFrame();
 
   // When the popup is created, it hasn't committed any navigation yet - its
-  // initial empty document should inherit the origin of its opener (the origin
-  // may change after the first commit).  See also https://crbug.com/932067.
+  // initial empty document should inherit the origin and network isolation key
+  // of its opener (the origin may change after the first commit). See also
+  // https://crbug.com/932067.
   //
   // Note that that origin of the new frame might depend on sandbox flags.
   // Checking sandbox flags of the new frame should be safe at this point,
   // because the flags should be already inherited by the CreateNewWindow call
   // above.
-  main_frame->SetOriginOfNewFrame(GetLastCommittedOrigin());
+  main_frame->SetOriginAndNetworkIsolationKeyOfNewFrame(
+      GetLastCommittedOrigin());
 
   if (main_frame->waiting_for_init_) {
     // Need to check |waiting_for_init_| as some paths inside CreateNewWindow
@@ -5303,6 +5310,7 @@
     network_isolation_key_ = net::NetworkIsolationKey(
         ComputeTopFrameOrigin(frame_origin), frame_origin);
   }
+  DCHECK(network_isolation_key_.IsFullyPopulated());
 
   std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
       subresource_loader_factories;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 6665ae1f..f8924d67 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1730,10 +1730,12 @@
   // Update this frame's last committed origin.
   void SetLastCommittedOrigin(const url::Origin& origin);
 
-  // Set the |last_committed_origin_| of |this| frame, inheriting the origin
-  // from |new_frame_creator| as appropriate (e.g. depending on whether |this|
-  // frame should be sandboxed / should have an opaque origin instead).
-  void SetOriginOfNewFrame(const url::Origin& new_frame_creator);
+  // Set the |last_committed_origin_| and |network_isolation_key_| of |this|
+  // frame, inheriting the origin from |new_frame_creator| as appropriate
+  // (e.g. depending on whether |this| frame should be sandboxed / should have
+  // an opaque origin instead).
+  void SetOriginAndNetworkIsolationKeyOfNewFrame(
+      const url::Origin& new_frame_creator);
 
   // Called when a navigation commits succesfully to |url|. This will update
   // |last_committed_site_url_| with the site URL corresponding to |url|.
@@ -2462,7 +2464,9 @@
 
   // Network isolation key to be used for subresources from the currently
   // committed navigation. This is specific to a document and should be reset on
-  // every document commit.
+  // every cross-document commit. When a new frame is created, the new frame
+  // inherits the network isolation key from the creator frame, similarly to the
+  // last committed origin.
   net::NetworkIsolationKey network_isolation_key_;
 
   // Hold onto hashes of the last |kMaxCookieSameSiteDeprecationUrls| cookie
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index 8f7ee167..04a8a76f5 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -1852,6 +1852,151 @@
   EXPECT_EQ(url::Origin::Create(kMainFrameURL), child->current_origin());
 }
 
+namespace {
+void CheckURLOriginAndNetworkIsolationKey(
+    FrameTreeNode* node,
+    GURL url,
+    url::Origin origin,
+    net::NetworkIsolationKey network_isolation_key) {
+  EXPECT_EQ(url, node->current_url());
+  EXPECT_EQ(origin, node->current_origin());
+  EXPECT_EQ(network_isolation_key,
+            node->current_frame_host()->network_isolation_key());
+}
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+                       NetworkIsolationKeyInitialEmptyDocumentIframe) {
+  GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
+  url::Origin main_frame_origin = url::Origin::Create(main_frame_url);
+  net::NetworkIsolationKey expected_main_frame_key =
+      net::NetworkIsolationKey(main_frame_origin, main_frame_origin);
+
+  GURL subframe_url_one("about:blank");
+  GURL subframe_url_two("about:blank#foo");
+  GURL subframe_url_three(
+      embedded_test_server()->GetURL("foo.com", "/title2.html"));
+  url::Origin subframe_origin_three = url::Origin::Create(subframe_url_three);
+  net::NetworkIsolationKey expected_subframe_key_three =
+      net::NetworkIsolationKey(main_frame_origin, subframe_origin_three);
+
+  // Main frame navigation.
+  ASSERT_TRUE(NavigateToURL(shell(), main_frame_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+  CheckURLOriginAndNetworkIsolationKey(root, main_frame_url, main_frame_origin,
+                                       expected_main_frame_key);
+
+  // Create iframe.
+  ASSERT_TRUE(ExecuteScript(shell(), R"(
+      var f = document.createElement('iframe');
+      f.id = 'myiframe';
+      document.body.append(f);
+  )"));
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  ASSERT_EQ(1u, root->child_count());
+  FrameTreeNode* child = root->child_at(0u);
+  CheckURLOriginAndNetworkIsolationKey(
+      child, subframe_url_one, main_frame_origin, expected_main_frame_key);
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            child->current_frame_host()->GetProcess());
+
+  // Same-document navigation of iframe.
+  ASSERT_TRUE(ExecuteScript(shell(), R"(
+      let iframe = document.querySelector('#myiframe');
+      iframe.contentWindow.location.hash = 'foo';
+  )"));
+
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  CheckURLOriginAndNetworkIsolationKey(
+      child, subframe_url_two, main_frame_origin, expected_main_frame_key);
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            child->current_frame_host()->GetProcess());
+
+  // Cross-document navigation of iframe.
+  TestFrameNavigationObserver commit_observer(child->current_frame_host());
+  std::string subframe_script_three = JsReplace(
+      "iframe = document.querySelector('#myiframe');"
+      "iframe.contentWindow.location.href = $1;",
+      subframe_url_three);
+  ASSERT_TRUE(ExecuteScript(shell(), subframe_script_three));
+  commit_observer.WaitForCommit();
+
+  CheckURLOriginAndNetworkIsolationKey(child, subframe_url_three,
+                                       subframe_origin_three,
+                                       expected_subframe_key_three);
+  if (AreAllSitesIsolatedForTesting()) {
+    EXPECT_NE(root->current_frame_host()->GetProcess(),
+              child->current_frame_host()->GetProcess());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+                       NetworkIsolationKeyInitialEmptyDocumentPopup) {
+  GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
+  url::Origin main_frame_origin = url::Origin::Create(main_frame_url);
+  net::NetworkIsolationKey expected_main_frame_key =
+      net::NetworkIsolationKey(main_frame_origin, main_frame_origin);
+
+  GURL popup_url_one("about:blank");
+  GURL popup_url_two("about:blank#foo");
+  GURL popup_url_three(
+      embedded_test_server()->GetURL("foo.com", "/title2.html"));
+  url::Origin popup_origin_three = url::Origin::Create(popup_url_three);
+  net::NetworkIsolationKey expected_popup_key_three =
+      net::NetworkIsolationKey(popup_origin_three, popup_origin_three);
+
+  // Main frame navigation.
+  ASSERT_TRUE(NavigateToURL(shell(), main_frame_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+  CheckURLOriginAndNetworkIsolationKey(root, main_frame_url, main_frame_origin,
+                                       expected_main_frame_key);
+
+  // Create popup.
+  WebContentsAddedObserver popup_observer;
+  ASSERT_TRUE(ExecuteScript(shell(), "var w = window.open();"));
+  WebContents* popup = popup_observer.GetWebContents();
+
+  FrameTreeNode* popup_frame =
+      static_cast<RenderFrameHostImpl*>(popup->GetMainFrame())
+          ->frame_tree_node();
+  CheckURLOriginAndNetworkIsolationKey(
+      popup_frame, popup_url_one, main_frame_origin, expected_main_frame_key);
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            popup_frame->current_frame_host()->GetProcess());
+
+  // Same-document navigation of popup.
+  ASSERT_TRUE(ExecuteScript(shell(), "w.location.hash = 'foo';"));
+  EXPECT_TRUE(WaitForLoadStop(popup));
+
+  CheckURLOriginAndNetworkIsolationKey(
+      popup_frame, popup_url_two, main_frame_origin, expected_main_frame_key);
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            popup_frame->current_frame_host()->GetProcess());
+
+  // Cross-document navigation of popup.
+  TestFrameNavigationObserver commit_observer(
+      popup_frame->current_frame_host());
+  ASSERT_TRUE(ExecuteScript(
+      shell(), JsReplace("w.location.href = $1;", popup_url_three)));
+  commit_observer.WaitForCommit();
+
+  CheckURLOriginAndNetworkIsolationKey(popup_frame, popup_url_three,
+                                       popup_origin_three,
+                                       expected_popup_key_three);
+  if (AreAllSitesIsolatedForTesting()) {
+    EXPECT_NE(root->current_frame_host()->GetProcess(),
+              popup_frame->current_frame_host()->GetProcess());
+  }
+}
+
 // Verify that if the UMA histograms are correctly recording if interface
 // provider requests are getting dropped because they racily arrive from the
 // previously active document (after the next navigation already committed).
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc
index c3ab8129..d41f739 100644
--- a/content/browser/permissions/permission_service_context.cc
+++ b/content/browser/permissions/permission_service_context.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "content/browser/permissions/permission_controller_impl.h"
 #include "content/browser/permissions/permission_service_impl.h"
+#include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/permission_controller.h"
@@ -149,6 +150,14 @@
   if (render_frame_host != render_frame_host_)
     return;
 
+  if (!services_.empty() || !subscriptions_.empty()) {
+    // |services_| and |subscriptions_| are destroyed here, so the page
+    // functionality might be broken if we restore the page from back-forward
+    // cache. Disable back-forward cache for this frame to ensure that this
+    // would not happen.
+    content::BackForwardCache::DisableForRenderFrameHost(
+        render_frame_host_, "PermissionServiceContext");
+  }
   services_.Clear();
   subscriptions_.clear();
 }
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 24f6c1c..b00ee2c 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -5598,9 +5598,8 @@
   EXPECT_NEAR(point.y(), params.y, kHitTestTolerance);
 }
 
-#if defined(OS_ANDROID) || defined(OS_WIN)
+#if defined(OS_ANDROID)
 // High DPI tests don't work properly on Android, which has fixed scale factor.
-// Windows is disabled because of https://crbug.com/545547.
 #define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
 #else
 #define MAYBE_CreateContextMenuTest CreateContextMenuTest
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index b50158e..49f725c3 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1050,9 +1050,21 @@
     return TestResourceLoadHelper(url, sub_frame, worker);
   }
 
+  // Loads 3p.com/script on |popup| opened from page |url| and returns whether
+  // the script was cached or not.
+  bool TestResourceLoadFromPopup(const GURL& url, const GURL& popup) {
+    DCHECK(popup.is_valid());
+    return TestResourceLoadHelper(url, popup, GURL(), true);
+  }
+
+  // Loads 3p.com/script on page |url|. If |new_frame| is valid, it is loaded
+  // from a new frame with that url; otherwise, it is loaded from the main
+  // frame. This new frame is a popup if |use_popup|; otherwise, it is a
+  // subframe. The load is optionally performed by |worker| if it's valid.
   bool TestResourceLoadHelper(const GURL& url,
-                              const GURL& sub_frame,
-                              const GURL& worker) {
+                              const GURL& new_frame,
+                              const GURL& worker,
+                              bool use_popup = false) {
     DCHECK(url.is_valid());
 
     // Clear the in-memory cache held by the current process:
@@ -1063,9 +1075,6 @@
         shell()->web_contents()->GetMainFrame(), "test");
     EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL(kChromeUIGpuHost)));
 
-    // Observe network requests.
-    ResourceLoadObserver observer(shell());
-
     // In the case of a redirect, the observed URL will be different from
     // what NavigateToURL(...) expects.
     if (base::StartsWith(url.path(), "/redirect", base::CompareCase::SENSITIVE))
@@ -1078,11 +1087,23 @@
     RenderFrameHostImpl* main_frame =
         static_cast<RenderFrameHostImpl*>(host_to_load_resource);
 
-    // If there is supposed to be a subframe, create it.
-    if (sub_frame.is_valid()) {
-      host_to_load_resource = CreateSubframe(sub_frame);
+    Shell* shell_to_observe = shell();
+
+    if (new_frame.is_valid()) {
+      // If there is supposed to be a subframe or popup, create it.
+      if (use_popup) {
+        shell_to_observe = OpenPopup(main_frame, new_frame, "");
+        host_to_load_resource =
+            static_cast<WebContentsImpl*>(shell_to_observe->web_contents())
+                ->GetMainFrame();
+      } else {
+        host_to_load_resource = CreateSubframe(new_frame);
+      }
     }
 
+    // Observe network requests.
+    ResourceLoadObserver observer(shell_to_observe);
+
     GURL resource = GenURL("3p.com", "/script");
 
     // If there is supposed to be a worker to load this resource, create it.
@@ -1104,14 +1125,16 @@
     RenderFrameHostImpl* frame_host =
         static_cast<RenderFrameHostImpl*>(host_to_load_resource);
     url::Origin frame_origin;
-    if (sub_frame.is_empty()) {
+    if (new_frame.is_empty()) {
       frame_origin = top_frame_origin;
     } else {
-      frame_origin = url::Origin::Create(sub_frame);
-      // TODO(crbug.com/888079) in about:blank currently committed origin is
-      // different from the origin at the time of CommitNavigation.
-      if (!frame_origin.opaque()) {
-        // Modify to take redirects into account.
+      frame_origin = url::Origin::Create(new_frame);
+      if (use_popup && !frame_origin.opaque()) {
+        // The popup is in a new WebContents, so its top_frame_origin is also
+        // new unless it is blank.
+        top_frame_origin = frame_origin;
+      } else {
+        // Take redirects and initially empty subframes/popups into account.
         frame_origin = frame_host->GetLastCommittedOrigin();
       }
     }
@@ -1403,6 +1426,19 @@
   // (a.com, a.com) which is already in the cache.
   GURL blank_url(url::kAboutBlankURL);
   EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), blank_url));
+
+  // Load the resource from a popup window that points to about:blank. The
+  // resource is cached because the resource load is using the original main
+  // frame's URLLoaderFactory and the original main frame's factory has the NIK
+  // set to (a.com, a.com) which is already in the cache.
+  EXPECT_TRUE(
+      TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"), blank_url));
+
+  // Load the resource from a popup window that points to a new origin. The
+  // resource is not cached because the resource load is using a NIK set to
+  // (g.com, g.com).
+  EXPECT_FALSE(TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"),
+                                         GenURL("g.com", "/title1.html")));
 }
 
 IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestDisabled,
diff --git a/content/public/browser/accessibility_tree_formatter.h b/content/public/browser/accessibility_tree_formatter.h
index 21077c5..55c3c9f2 100644
--- a/content/public/browser/accessibility_tree_formatter.h
+++ b/content/public/browser/accessibility_tree_formatter.h
@@ -27,6 +27,8 @@
 
 namespace content {
 
+class BrowserAccessibility;
+
 class AccessibilityTestExpectationsLocator {
  public:
   // Suffix of the expectation file corresponding to html file.
@@ -125,6 +127,9 @@
   virtual std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree(
       const base::DictionaryValue& dict) = 0;
 
+  // Dumps a BrowserAccessibility tree into a string.
+  virtual void FormatAccessibilityTree(BrowserAccessibility* root,
+                                       base::string16* contents) = 0;
   virtual void FormatAccessibilityTree(const base::DictionaryValue& tree_node,
                                        base::string16* contents) = 0;
 
diff --git a/content/public/test/browser_accessibility.h b/content/public/test/browser_accessibility.h
deleted file mode 100644
index 5a85afe..0000000
--- a/content/public/test/browser_accessibility.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_
-#define CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_
-
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-
-namespace content {
-
-class AccessibilityTreeFormatter;
-
-// A class that exposes BrowserAccessibility for testing in a controlled manner.
-// Additional methods can be added to expose methods from BrowserAccessibility,
-// as long as the methods do not expose non-public content/ classes.
-class TestBrowserAccessibility : public ui::AXPlatformNodeDelegate {
- public:
-  // Dumps a BrowserAccessibility tree into a string.
-  static void FormatAccessibilityTree(AccessibilityTreeFormatter* formatter,
-                                      TestBrowserAccessibility* root,
-                                      base::string16* contents);
-
-  ~TestBrowserAccessibility() override;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index c244b17..76736796 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -89,7 +89,6 @@
 #include "content/public/test/test_fileapi_operation_waiter.h"
 #include "content/public/test/test_launcher.h"
 #include "content/public/test/test_navigation_observer.h"
-#include "content/test/browser_accessibility.h"
 #include "content/test/did_commit_navigation_interceptor.h"
 #include "ipc/ipc_security_test_util.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -2027,42 +2026,39 @@
   return manager->SnapshotAXTreeForTesting();
 }
 
-TestBrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents) {
+BrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents) {
   WebContentsImpl* web_contents_impl =
       static_cast<WebContentsImpl*>(web_contents);
   BrowserAccessibilityManager* manager =
       web_contents_impl->GetRootBrowserAccessibilityManager();
-  return manager ? ToTestBrowserAccessibility(manager->GetRoot()) : nullptr;
+  return manager ? manager->GetRoot() : nullptr;
 }
 
 FindAccessibilityNodeCriteria::FindAccessibilityNodeCriteria() = default;
 
 FindAccessibilityNodeCriteria::~FindAccessibilityNodeCriteria() = default;
 
-TestBrowserAccessibility* FindAccessibilityNode(
+BrowserAccessibility* FindAccessibilityNode(
     WebContents* web_contents,
     const FindAccessibilityNodeCriteria& criteria) {
-  TestBrowserAccessibility* root = GetRootAccessibilityNode(web_contents);
+  BrowserAccessibility* root = GetRootAccessibilityNode(web_contents);
   CHECK(root);
   return FindAccessibilityNodeInSubtree(root, criteria);
 }
 
-TestBrowserAccessibility* FindAccessibilityNodeInSubtree(
-    TestBrowserAccessibility* node,
+BrowserAccessibility* FindAccessibilityNodeInSubtree(
+    BrowserAccessibility* node,
     const FindAccessibilityNodeCriteria& criteria) {
-  BrowserAccessibility* node_internal = FromTestBrowserAccessibility(node);
   if ((!criteria.name ||
-       node_internal->GetStringAttribute(ax::mojom::StringAttribute::kName) ==
+       node->GetStringAttribute(ax::mojom::StringAttribute::kName) ==
            criteria.name.value()) &&
-      (!criteria.role || node_internal->GetRole() == criteria.role.value())) {
+      (!criteria.role || node->GetRole() == criteria.role.value())) {
     return node;
   }
 
-  for (unsigned int i = 0; i < node_internal->PlatformChildCount(); ++i) {
-    TestBrowserAccessibility* child =
-        ToTestBrowserAccessibility(node_internal->PlatformGetChild(i));
-    TestBrowserAccessibility* result =
-        FindAccessibilityNodeInSubtree(child, criteria);
+  for (unsigned int i = 0; i < node->PlatformChildCount(); ++i) {
+    BrowserAccessibility* result =
+        FindAccessibilityNodeInSubtree(node->PlatformGetChild(i), criteria);
     if (result)
       return result;
   }
@@ -2072,7 +2068,7 @@
 #if defined(OS_WIN)
 template <typename T>
 Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode(
-    TestBrowserAccessibility* browser_accessibility) {
+    BrowserAccessibility* browser_accessibility) {
   Microsoft::WRL::ComPtr<T> result;
   EXPECT_HRESULT_SUCCEEDED(
       browser_accessibility->GetNativeViewAccessible()->QueryInterface(
@@ -2082,7 +2078,7 @@
 
 void UiaGetPropertyValueVtArrayVtUnknownValidate(
     PROPERTYID property_id,
-    TestBrowserAccessibility* target_browser_accessibility,
+    BrowserAccessibility* target_browser_accessibility,
     const std::vector<std::string>& expected_names) {
   ASSERT_NE(nullptr, target_browser_accessibility);
 
@@ -3158,7 +3154,7 @@
 // exposing them in the header.
 class EvictionStateWaiter : public DelegatedFrameHost::Observer {
  public:
-  explicit EvictionStateWaiter(DelegatedFrameHost* delegated_frame_host)
+  EvictionStateWaiter(DelegatedFrameHost* delegated_frame_host)
       : delegated_frame_host_(delegated_frame_host) {
     delegated_frame_host_->AddObserverForTesting(this);
   }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index eeb3447..cdb6bc7 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -89,6 +89,7 @@
 
 namespace content {
 
+class BrowserAccessibility;
 class BrowserContext;
 struct FrameVisualProperties;
 class FrameTreeNode;
@@ -99,7 +100,6 @@
 class RenderWidgetHost;
 class RenderWidgetHostView;
 class ScopedAllowRendererCrashes;
-class TestBrowserAccessibility;
 class WebContents;
 
 // Navigates |web_contents| to |url|, blocking until the navigation finishes.
@@ -909,7 +909,7 @@
 ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents);
 
 // Returns the root accessibility node for the given WebContents.
-TestBrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents);
+BrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents);
 
 // Finds an accessibility node matching the given criteria.
 struct FindAccessibilityNodeCriteria {
@@ -918,18 +918,18 @@
   base::Optional<ax::mojom::Role> role;
   base::Optional<std::string> name;
 };
-TestBrowserAccessibility* FindAccessibilityNode(
+BrowserAccessibility* FindAccessibilityNode(
     WebContents* web_contents,
     const FindAccessibilityNodeCriteria& criteria);
-TestBrowserAccessibility* FindAccessibilityNodeInSubtree(
-    TestBrowserAccessibility* node,
+BrowserAccessibility* FindAccessibilityNodeInSubtree(
+    BrowserAccessibility* node,
     const FindAccessibilityNodeCriteria& criteria);
 
 #if defined(OS_WIN)
 // Retrieve the specified interface from an accessibility node.
 template <typename T>
 Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode(
-    TestBrowserAccessibility* browser_accessibility);
+    BrowserAccessibility* browser_accessibility);
 
 // Call GetPropertyValue with the given UIA property id with variant type
 // VT_ARRAY | VT_UNKNOWN  on the target browser accessibility node to retrieve
@@ -937,7 +937,7 @@
 // automation elements with the expected names.
 void UiaGetPropertyValueVtArrayVtUnknownValidate(
     PROPERTYID property_id,
-    TestBrowserAccessibility* target_browser_accessibility,
+    BrowserAccessibility* target_browser_accessibility,
     const std::vector<std::string>& expected_names);
 #endif
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index a2a157c..58de9ee 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1073,11 +1073,13 @@
     return;
 
   GetChannel()->AddListenerTaskRunner(
-      routing_id, frame->GetTaskRunner(blink::TaskType::kInternalFreezableIPC));
+      routing_id,
+      frame->GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
 
   unfreezable_message_filter_->AddListenerUnfreezableTaskRunner(
       routing_id,
-      frame->GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
+      frame->GetTaskRunner(
+          blink::TaskType::kInternalNavigationAssociatedUnfreezable));
 
   scoped_refptr<PendingFrameCreate> create(it->second);
   frame->BindFrame(it->second->browser_info(), it->second->TakeFrameReceiver());
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 950424b..f496c51 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -99,7 +99,6 @@
     "../public/test/background_sync_test_util.h",
     "../public/test/blink_test_environment.cc",
     "../public/test/blink_test_environment.h",
-    "../public/test/browser_accessibility.h",
     "../public/test/browser_side_navigation_test_utils.cc",
     "../public/test/browser_side_navigation_test_utils.h",
     "../public/test/browser_task_environment.cc",
@@ -233,8 +232,6 @@
     "../public/test/web_contents_tester.h",
     "appcache_test_helper.cc",
     "appcache_test_helper.h",
-    "browser_accessibility.cc",
-    "browser_accessibility.h",
     "content_browser_sanity_checker.cc",
     "content_browser_sanity_checker.h",
     "content_test_suite.cc",
diff --git a/content/test/browser_accessibility.cc b/content/test/browser_accessibility.cc
deleted file mode 100644
index 61bd0f2..0000000
--- a/content/test/browser_accessibility.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/test/browser_accessibility.h"
-
-#include "content/browser/accessibility/accessibility_tree_formatter_base.h"
-
-namespace content {
-
-// static
-void TestBrowserAccessibility::FormatAccessibilityTree(
-    AccessibilityTreeFormatter* formatter,
-    TestBrowserAccessibility* root,
-    base::string16* contents) {
-  auto* formatter_internal =
-      static_cast<AccessibilityTreeFormatterBase*>(formatter);
-  BrowserAccessibility* root_internal = FromTestBrowserAccessibility(root);
-  formatter_internal->FormatAccessibilityTreeForTesting(root_internal,
-                                                        contents);
-}
-
-TestBrowserAccessibility* ToTestBrowserAccessibility(
-    BrowserAccessibility* browser_accessibility) {
-  return reinterpret_cast<TestBrowserAccessibility*>(browser_accessibility);
-}
-
-BrowserAccessibility* FromTestBrowserAccessibility(
-    TestBrowserAccessibility* test_browser_accessibility) {
-  return reinterpret_cast<BrowserAccessibility*>(test_browser_accessibility);
-}
-
-}  // namespace content
diff --git a/content/test/browser_accessibility.h b/content/test/browser_accessibility.h
deleted file mode 100644
index cba2d37..0000000
--- a/content/test/browser_accessibility.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_TEST_BROWSER_ACCESSIBILITY_H_
-#define CONTENT_TEST_BROWSER_ACCESSIBILITY_H_
-
-#include "content/public/test/browser_accessibility.h"
-
-namespace content {
-
-class BrowserAccessibility;
-
-// Helper functions that are implementation details that should not be exposed
-// via content/public/test/browser_accessibility.h.
-TestBrowserAccessibility* ToTestBrowserAccessibility(
-    BrowserAccessibility* browser_accessibility);
-BrowserAccessibility* FromTestBrowserAccessibility(
-    TestBrowserAccessibility* test_browser_accessibility);
-
-}  // namespace content
-
-#endif  // CONTENT_TEST_BROWSER_ACCESSIBILITY_H_
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 21297a3..27caa3e 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -178,31 +178,7 @@
 crbug.com/974380 [ mac ] Pixel_OffscreenCanvasUnaccelerated2DGPUCompositingWorker [ Skip ]
 crbug.com/974383 [ mac ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ]
 
-# Fails on Intel
-crbug.com/991289 [ linux skia-renderer intel ] Pixel_CSS3DBlueBox [ Skip ]
-
 # Fails when the browser features SkiaRenderer & Vulkan are enabled on Android
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_2DCanvasWebGL [ Failure ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_BackgroundImage [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_Canvas2DRedBox [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_Canvas2DUntagged [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasAccelerated2D [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasAccelerated2DWorker [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferToImageBitmapWorker [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebGLDefault [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebGLDefaultWorker [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebglResizeOnWorker [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_AA_Alpha [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_AA_NoAlpha [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_NoAA_Alpha [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Skip ]
-crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ]
-crbug.com/985070 [ android android-chromium skia-renderer use-vulkan qualcomm-adreno-(tm)-540 ] Pixel_CanvasLowLatencyWebGL [ Skip ]
 crbug.com/991289 [ android skia-renderer use-vulkan ] Pixel_CSS3DBlueBox [ Skip ]
 crbug.com/991291 [ android android-chromium skia-renderer use-vulkan ] Pixel_Video_Context_Loss_VP9 [ Skip ]
 crbug.com/991291 [ android skia-renderer use-vulkan ] Pixel_Video_MP4 [ Skip ]
@@ -214,10 +190,6 @@
 
 # Fails when the browser features SkiaRenderer & GL are enabled on Android.
 # The more specific matching criteria is to prevent collisions with other expectations.
-crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_BackgroundImage [ Skip ]
-crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ]
-crbug.com/969864 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
 crbug.com/1008456 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_Video_Context_Loss_VP9 [ Skip ]
 crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4 [ Skip ]
 crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ Skip ]
@@ -225,7 +197,6 @@
 crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Rot_270 [ Skip ]
 crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Rot_90 [ Skip ]
 crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_VP9 [ Skip ]
-crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ]
 
 # Fails on Android SkiaRenderer, both GL and Vulkan
 crbug.com/1008450 [ android skia-renderer ] Pixel_Video_BackdropFilter [ Skip ]
diff --git a/google_apis/gaia/core_account_id.cc b/google_apis/gaia/core_account_id.cc
index 0fc8c41..2661218 100644
--- a/google_apis/gaia/core_account_id.cc
+++ b/google_apis/gaia/core_account_id.cc
@@ -22,9 +22,11 @@
 
 CoreAccountId::CoreAccountId(const std::string& id) : id(id) {}
 
+#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
 CoreAccountId::operator std::string() const {
   return id;
 }
+#endif
 
 bool CoreAccountId::empty() const {
   return id.empty();
diff --git a/google_apis/gaia/core_account_id.h b/google_apis/gaia/core_account_id.h
index 0558754..886d228 100644
--- a/google_apis/gaia/core_account_id.h
+++ b/google_apis/gaia/core_account_id.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "build/build_config.h"
+
 // Represent the id of an account for interaction with GAIA. It is
 // currently implicitly convertible to and from std::string to allow
 // progressive migration of the code (see https://crbug.com/959157
@@ -22,6 +24,7 @@
   CoreAccountId& operator=(const CoreAccountId&);
   CoreAccountId& operator=(CoreAccountId&&) noexcept;
 
+#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
   // Those implicit constructor and conversion operator allow to
   // progressively migrate the code to use this struct. Removing
   // them is tracked by https://crbug.com/959161
@@ -29,6 +32,11 @@
   CoreAccountId(std::string&& id);
   CoreAccountId(const std::string& id);
   operator std::string() const;
+#else
+  explicit CoreAccountId(const char* id);
+  explicit CoreAccountId(std::string&& id);
+  explicit CoreAccountId(const std::string& id);
+#endif
 
   // Checks if the account is valid or not.
   // TODO(triploblastic): Possibly rename of remove this after
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index d9196676..6d276672 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -374,7 +374,10 @@
   }
 
   if (skia_use_dawn) {
-    deps += [ "//components/viz/common:dawn_context_provider" ]
+    deps += [
+      "//components/viz/common:dawn_context_provider",
+      "//third_party/dawn/src/dawn:libdawn",
+    ]
   }
 
   if (is_android) {
diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc
index 7f62b05c..cf85ba5 100644
--- a/gpu/command_buffer/service/service_utils.cc
+++ b/gpu/command_buffer/service/service_utils.cc
@@ -12,6 +12,7 @@
 #include "gpu/command_buffer/service/context_group.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/config/gpu_finch_features.h"
+#include "skia/buildflags.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/gl/gl_utils.h"
 
@@ -179,8 +180,10 @@
           << "GrContextType is Metal, but Metal is not enabled.";
       gpu_preferences.gr_context_type = GrContextType::kMetal;
 #endif
+#if BUILDFLAG(SKIA_USE_DAWN)
     } else if (value == switches::kGrContextTypeDawn) {
       gpu_preferences.gr_context_type = GrContextType::kDawn;
+#endif
     } else {
       NOTREACHED() << "Invalid GrContextType.";
       gpu_preferences.gr_context_type = GrContextType::kGL;
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc
index 769a9d90..8d2c5e13 100644
--- a/gpu/command_buffer/service/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -80,7 +80,8 @@
       shared_image_manager_(shared_image_manager),
       memory_tracker_(std::make_unique<MemoryTypeTracker>(memory_tracker)),
       using_vulkan_(context_state && context_state->GrContextIsVulkan()),
-      using_metal_(context_state && context_state->GrContextIsMetal()) {
+      using_metal_(context_state && context_state->GrContextIsMetal()),
+      using_dawn_(context_state && context_state->GrContextIsDawn()) {
   bool use_gl = gl::GetGLImplementation() != gl::kGLImplementationNone;
   if (use_gl) {
     gl_backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>(
@@ -164,13 +165,14 @@
   }
 
   // Currently we only perform data uploads via two paths,
-  // |gl_backing_factory_| for GL and |wrapped_sk_image_factory_| for Vulkan.
+  // |gl_backing_factory_| for GL and |wrapped_sk_image_factory_| for Vulkan and
+  // Dawn.
   // TODO(ericrk): Make this generic in the future.
   bool allow_legacy_mailbox = false;
   SharedImageBackingFactory* factory = nullptr;
   if (backing_factory_for_testing_) {
     factory = backing_factory_for_testing_;
-  } else if (!using_vulkan_) {
+  } else if (!using_vulkan_ && !using_dawn_) {
     allow_legacy_mailbox = true;
     factory = gl_backing_factory_.get();
   } else {
diff --git a/gpu/command_buffer/service/shared_image_factory.h b/gpu/command_buffer/service/shared_image_factory.h
index 87ded985..5dc0255 100644
--- a/gpu/command_buffer/service/shared_image_factory.h
+++ b/gpu/command_buffer/service/shared_image_factory.h
@@ -121,6 +121,7 @@
   std::unique_ptr<MemoryTypeTracker> memory_tracker_;
   const bool using_vulkan_;
   const bool using_metal_;
+  const bool using_dawn_;
 
   // The set of SharedImages which have been created (and are being kept alive)
   // by this factory.
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index f142405..7a05f31 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -18,6 +18,7 @@
 #include "gpu/command_buffer/service/shared_image_backing.h"
 #include "gpu/command_buffer/service/shared_image_representation.h"
 #include "gpu/command_buffer/service/skia_utils.h"
+#include "skia/buildflags.h"
 #include "third_party/skia/include/core/SkPromiseImageTexture.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/core/SkSurfaceProps.h"
@@ -201,6 +202,14 @@
           tracing_id_ = reinterpret_cast<uint64_t>(image_info.fImage);
         break;
       }
+#if BUILDFLAG(SKIA_USE_DAWN)
+      case GrBackendApi::kDawn: {
+        GrDawnImageInfo image_info;
+        if (backend_texture.getDawnImageInfo(&image_info))
+          tracing_id_ = reinterpret_cast<uint64_t>(image_info.fTexture.Get());
+        break;
+      }
+#endif
       default:
         NOTREACHED();
         return false;
diff --git a/ios/chrome/browser/crash_report/crash_restore_helper.mm b/ios/chrome/browser/crash_report/crash_restore_helper.mm
index e1118f9..efa4575 100644
--- a/ios/chrome/browser/crash_report/crash_restore_helper.mm
+++ b/ios/chrome/browser/crash_report/crash_restore_helper.mm
@@ -13,7 +13,7 @@
 #include "components/infobars/core/infobar.h"
 #include "components/infobars/core/infobar_manager.h"
 #include "components/sessions/core/tab_restore_service.h"
-#include "components/sessions/ios/ios_live_tab.h"
+#include "components/sessions/ios/ios_restore_live_tab.h"
 #include "components/strings/grit/components_chromium_strings.h"
 #include "components/strings/grit/components_google_chrome_strings.h"
 #include "components/strings/grit/components_strings.h"
@@ -326,12 +326,10 @@
 
   web::WebState::CreateParams params(_browserState);
   for (CRWSessionStorage* session in sessions) {
-    std::unique_ptr<web::WebState> webState =
-        web::WebState::CreateWithStorageSession(params, session);
+    auto live_tab = std::make_unique<sessions::RestoreIOSLiveTab>(session);
     // Add all tabs at the 0 position as the position is relative to an old
     // tabModel.
-    tabRestoreService->CreateHistoricalTab(
-        sessions::IOSLiveTab::GetForWebState(webState.get()), 0);
+    tabRestoreService->CreateHistoricalTab(live_tab.get(), 0);
   }
   return;
 }
diff --git a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
index c1a404d..418b641e8 100644
--- a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
+++ b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -33,10 +33,12 @@
       std::unique_ptr<dom_distiller::DistillerFactory> distiller_factory,
       std::unique_ptr<dom_distiller::DistillerPageFactory>
           distiller_page_factory,
-      std::unique_ptr<dom_distiller::DistilledPagePrefs> distilled_page_prefs)
+      std::unique_ptr<dom_distiller::DistilledPagePrefs> distilled_page_prefs,
+      std::unique_ptr<dom_distiller::DistillerUIHandle> distiller_ui_handle)
       : DomDistillerService(std::move(distiller_factory),
                             std::move(distiller_page_factory),
-                            std::move(distilled_page_prefs)) {}
+                            std::move(distilled_page_prefs),
+                            std::move(distiller_ui_handle)) {}
 
   ~DomDistillerKeyedService() override {}
 
@@ -88,7 +90,8 @@
 
   return std::make_unique<DomDistillerKeyedService>(
       std::move(distiller_factory), std::move(distiller_page_factory),
-      std::move(distilled_page_prefs));
+      std::move(distilled_page_prefs),
+      /* distiller_ui_handle */ nullptr);
 }
 
 web::BrowserState* DomDistillerServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h
index f14dc1b..17b6026 100644
--- a/ios/chrome/browser/signin/authentication_service.h
+++ b/ios/chrome/browser/signin/authentication_service.h
@@ -139,7 +139,7 @@
   // is only updated when the app is in foreground and used to detect
   // if any change occurred while the app was in background.
   // See HaveAccountsChangesWhileInBackground().
-  std::vector<std::string> GetLastKnownAccountsFromForeground();
+  std::vector<CoreAccountId> GetLastKnownAccountsFromForeground();
 
   // Returns the cached MDM infos associated with |identity|. If the cache
   // is stale for |identity|, the entry might be removed.
@@ -222,7 +222,7 @@
   bool is_reloading_credentials_ = false;
 
   // Map between account IDs and their associated MDM error.
-  mutable std::map<std::string, NSDictionary*> cached_mdm_infos_;
+  mutable std::map<CoreAccountId, NSDictionary*> cached_mdm_infos_;
 
   ScopedObserver<ios::ChromeIdentityService,
                  ios::ChromeIdentityService::Observer>
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm
index 2fa22201..7487758 100644
--- a/ios/chrome/browser/signin/authentication_service.mm
+++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -54,8 +54,9 @@
 constexpr char kFakeAccountIdForRemovedAccount[] = "0000000000000";
 
 // Returns the account id associated with |identity|.
-std::string ChromeIdentityToAccountID(signin::IdentityManager* identity_manager,
-                                      ChromeIdentity* identity) {
+CoreAccountId ChromeIdentityToAccountID(
+    signin::IdentityManager* identity_manager,
+    ChromeIdentity* identity) {
   std::string gaia_id = base::SysNSStringToUTF8([identity gaiaID]);
   auto maybe_account =
       identity_manager
@@ -152,7 +153,7 @@
   // Clear signin errors on the accounts that had a specific MDM device status.
   // This will trigger services to fetch data for these accounts again.
   using std::swap;
-  std::map<std::string, NSDictionary*> cached_mdm_infos;
+  std::map<CoreAccountId, NSDictionary*> cached_mdm_infos;
   swap(cached_mdm_infos_, cached_mdm_infos);
 
   if (!cached_mdm_infos.empty()) {
@@ -201,7 +202,7 @@
   // Load accounts from preference before synchronizing the accounts with
   // the system, otherwiser we would never detect any changes to the list
   // of accounts.
-  std::vector<std::string> last_foreground_accounts =
+  std::vector<CoreAccountId> last_foreground_accounts =
       GetLastKnownAccountsFromForeground();
   std::sort(last_foreground_accounts.begin(), last_foreground_accounts.end());
 
@@ -214,7 +215,7 @@
 
   std::vector<CoreAccountInfo> current_accounts_info =
       identity_manager_->GetAccountsWithRefreshTokens();
-  std::vector<std::string> current_accounts;
+  std::vector<CoreAccountId> current_accounts;
   for (const CoreAccountInfo& account_info : current_accounts_info)
     current_accounts.push_back(account_info.account_id);
   std::sort(current_accounts.begin(), current_accounts.end());
@@ -239,11 +240,11 @@
     return;
   }
 
-  std::vector<std::string> account_ids = GetLastKnownAccountsFromForeground();
+  std::vector<CoreAccountId> account_ids = GetLastKnownAccountsFromForeground();
   std::vector<base::Value> accounts_pref_value;
-  for (const std::string& account_id : account_ids) {
+  for (const auto& account_id : account_ids) {
     if (identity_manager_->HasAccountWithRefreshToken(account_id)) {
-      accounts_pref_value.emplace_back(account_id);
+      accounts_pref_value.emplace_back(account_id.id);
     } else {
       // The account for |email| was removed since the last application cold
       // start. Insert |kFakeAccountIdForRemovedAccount| to ensure
@@ -268,16 +269,16 @@
                      base::Value(std::move(accounts_pref_value)));
 }
 
-std::vector<std::string>
+std::vector<CoreAccountId>
 AuthenticationService::GetLastKnownAccountsFromForeground() {
   const base::Value* accounts_pref =
       pref_service_->GetList(prefs::kSigninLastAccounts);
 
-  std::vector<std::string> accounts;
+  std::vector<CoreAccountId> accounts;
   for (const auto& value : accounts_pref->GetList()) {
     DCHECK(value.is_string());
     DCHECK(!value.GetString().empty());
-    accounts.push_back(value.GetString());
+    accounts.push_back(CoreAccountId(value.GetString()));
   }
   return accounts;
 }
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm
index 8aa0116b..f799280 100644
--- a/ios/chrome/browser/signin/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -65,6 +65,10 @@
       ProfileSyncServiceFactory::GetForBrowserState(browser_state));
 }
 
+CoreAccountId GetAccountId(ChromeIdentity* identity) {
+  return CoreAccountId(base::SysNSStringToUTF8([identity gaiaID]));
+}
+
 }  // namespace
 
 class AuthenticationServiceTest : public PlatformTest {
@@ -112,7 +116,7 @@
     authentication_service()->StoreKnownAccountsWhileInForeground();
   }
 
-  std::vector<std::string> GetLastKnownAccountsFromForeground() {
+  std::vector<CoreAccountId> GetLastKnownAccountsFromForeground() {
     return authentication_service()->GetLastKnownAccountsFromForeground();
   }
 
@@ -134,14 +138,13 @@
   }
 
   void SetCachedMDMInfo(ChromeIdentity* identity, NSDictionary* user_info) {
-    authentication_service()
-        ->cached_mdm_infos_[base::SysNSStringToUTF8([identity gaiaID])] =
+    authentication_service()->cached_mdm_infos_[GetAccountId(identity)] =
         user_info;
   }
 
   bool HasCachedMDMInfo(ChromeIdentity* identity) {
     return authentication_service()->cached_mdm_infos_.count(
-               base::SysNSStringToUTF8([identity gaiaID])) > 0;
+               GetAccountId(identity)) > 0;
   }
 
   AuthenticationService* authentication_service() {
@@ -249,7 +252,7 @@
 
 TEST_F(AuthenticationServiceTest, StoreAndGetAccountsInPrefs) {
   // Profile starts empty.
-  std::vector<std::string> accounts = GetLastKnownAccountsFromForeground();
+  std::vector<CoreAccountId> accounts = GetLastKnownAccountsFromForeground();
   EXPECT_TRUE(accounts.empty());
 
   // Sign in.
@@ -261,8 +264,8 @@
   StoreKnownAccountsWhileInForeground();
   accounts = GetLastKnownAccountsFromForeground();
   ASSERT_EQ(2u, accounts.size());
-  EXPECT_EQ("foo2ID", accounts[0]);
-  EXPECT_EQ("fooID", accounts[1]);
+  EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0]);
+  EXPECT_EQ(CoreAccountId("fooID"), accounts[1]);
 }
 
 TEST_F(AuthenticationServiceTest,
@@ -281,8 +284,8 @@
       identity_manager()->GetAccountsWithRefreshTokens();
   std::sort(accounts.begin(), accounts.end(), account_compare_func);
   ASSERT_EQ(2u, accounts.size());
-  EXPECT_EQ("foo2ID", accounts[0].account_id);
-  EXPECT_EQ("fooID", accounts[1].account_id);
+  EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0].account_id);
+  EXPECT_EQ(CoreAccountId("fooID"), accounts[1].account_id);
 
   // Simulate a switching to background and back to foreground, triggering a
   // credentials reload.
@@ -294,9 +297,9 @@
   accounts = identity_manager()->GetAccountsWithRefreshTokens();
   std::sort(accounts.begin(), accounts.end(), account_compare_func);
   ASSERT_EQ(3u, accounts.size());
-  EXPECT_EQ("foo2ID", accounts[0].account_id);
-  EXPECT_EQ("foo3ID", accounts[1].account_id);
-  EXPECT_EQ("fooID", accounts[2].account_id);
+  EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0].account_id);
+  EXPECT_EQ(CoreAccountId("foo3ID"), accounts[1].account_id);
+  EXPECT_EQ(CoreAccountId("fooID"), accounts[2].account_id);
 }
 
 TEST_F(AuthenticationServiceTest, HaveAccountsChanged_Default) {
@@ -429,7 +432,7 @@
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   signin::UpdatePersistentErrorOfRefreshTokenForAccount(
-      identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error);
+      identity_manager(), GetAccountId(identity(0)), error);
 
   // MDM error for |identity_| is being cleared and the error state of refresh
   // token will be updated.
@@ -482,7 +485,7 @@
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   signin::UpdatePersistentErrorOfRefreshTokenForAccount(
-      identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error);
+      identity_manager(), GetAccountId(identity(0)), error);
 
   NSDictionary* user_info1 = @{ @"foo" : @1 };
   ON_CALL(*identity_service(), GetMDMDeviceStatus(user_info1))
@@ -518,7 +521,7 @@
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   signin::UpdatePersistentErrorOfRefreshTokenForAccount(
-      identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error);
+      identity_manager(), GetAccountId(identity(0)), error);
 
   NSDictionary* user_info1 = @{ @"foo" : @1 };
   ON_CALL(*identity_service(), GetMDMDeviceStatus(user_info1))
@@ -576,7 +579,7 @@
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   signin::UpdatePersistentErrorOfRefreshTokenForAccount(
-      identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error);
+      identity_manager(), GetAccountId(identity(0)), error);
 
   NSDictionary* user_info = [NSDictionary dictionary];
   SetCachedMDMInfo(identity(0), user_info);
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index e24f8db..08034bb 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -336,9 +336,9 @@
 - (BOOL)shouldHandleMergeCaseForIdentity:(ChromeIdentity*)identity
                             browserState:
                                 (ios::ChromeBrowserState*)browserState {
-  std::string lastSignedInAccountId =
-      browserState->GetPrefs()->GetString(prefs::kGoogleServicesLastAccountId);
-  std::string currentSignedInAccountId =
+  CoreAccountId lastSignedInAccountId(
+      browserState->GetPrefs()->GetString(prefs::kGoogleServicesLastAccountId));
+  CoreAccountId currentSignedInAccountId =
       IdentityManagerFactory::GetForBrowserState(browserState)
           ->PickAccountIdForAccount(
               base::SysNSStringToUTF8([identity gaiaID]),
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 832f6888..469025fa 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -259,7 +259,7 @@
   int consent_confirmation_id = showAccountsSettings
                                     ? openSettingsStringId
                                     : [self acceptSigninButtonStringId];
-  std::string account_id =
+  CoreAccountId account_id =
       IdentityManagerFactory::GetForBrowserState(self.browserState)
           ->PickAccountIdForAccount(
               base::SysNSStringToUTF8([_selectedIdentity gaiaID]),
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index c1e3bacc..2e39d51 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -229,7 +229,6 @@
     "//ios/chrome/test:block_cleanup_test",
     "//ios/chrome/test:test_support",
     "//ios/net",
-    "//ios/testing:ocmock_support",
     "//ios/web/public",
     "//ios/web/public/deprecated",
     "//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm
index 1918b7f..a36f392 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm
@@ -16,7 +16,6 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_navigation_manager.h"
 #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_web_state.h"
-#import "ios/testing/ocmock_complex_type_helper.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
index 347a6c8..2fcfcdc 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -33,7 +33,6 @@
 #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h"
 #include "ios/chrome/test/block_cleanup_test.h"
 #include "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
-#import "ios/testing/ocmock_complex_type_helper.h"
 #include "ios/web/public/test/web_task_environment.h"
 #import "ios/web/public/web_state.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -53,37 +52,12 @@
            notifyToolbar:(BOOL)notifyToolbar;
 @end
 
-@interface BVCTestTabModel : OCMockComplexTypeHelper
-- (instancetype)init NS_DESIGNATED_INITIALIZER;
-@property(nonatomic, assign) ios::ChromeBrowserState* browserState;
-@property(nonatomic, readonly) WebStateList* webStateList;
-@end
-
-@implementation BVCTestTabModel {
-  FakeWebStateListDelegate _webStateListDelegate;
-  std::unique_ptr<WebStateList> _webStateList;
-}
-
-- (instancetype)init {
-  if ((self = [super
-           initWithRepresentedObject:[OCMockObject
-                                         niceMockForClass:[TabModel class]]])) {
-    _webStateList = std::make_unique<WebStateList>(&_webStateListDelegate);
-  }
-  return self;
-}
-
-- (WebStateList*)webStateList {
-  return _webStateList.get();
-}
-@end
-
 #pragma mark -
 
 namespace {
 class BrowserViewControllerTest : public BlockCleanupTest {
  public:
-  BrowserViewControllerTest() {}
+  BrowserViewControllerTest() : web_state_list_(&web_state_list_delegate_) {}
 
  protected:
   void SetUp() override {
@@ -102,8 +76,13 @@
     chrome_browser_state_ = test_cbs_builder.Build();
 
     // Set up mock TabModel.
-    id tabModel = [[BVCTestTabModel alloc] init];
-    [tabModel setBrowserState:chrome_browser_state_.get()];
+    id tabModel = [OCMockObject niceMockForClass:[TabModel class]];
+    OCMStub([tabModel webStateList]).andReturn(&web_state_list_);
+    OCMStub([tabModel browserState])
+        .andReturn(
+            // As OCMock compare types as string, the cast is required otherwise
+            // it will complain that the value has an incompatible type.
+            static_cast<ios::ChromeBrowserState*>(chrome_browser_state_.get()));
 
     // Enable web usage for the mock TabModel's WebStateList.
     WebStateListWebUsageEnabler* enabler =
@@ -190,6 +169,8 @@
   web::WebTaskEnvironment task_environment_;
   IOSChromeScopedTestingLocalState local_state_;
   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
+  FakeWebStateListDelegate web_state_list_delegate_;
+  WebStateList web_state_list_;
   TabModel* tabModel_;
   std::unique_ptr<Browser> browser_;
   BrowserViewControllerHelper* bvcHelper_;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
index b6343fc..30805d6a 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -84,7 +84,6 @@
 // Whether the table view is being edited by the swipe-to-delete button.
 @property(nonatomic, readonly, getter=isEditingWithSwipe) BOOL editingWithSwipe;
 // Whether to remove empty sections after editing is reset to NO.
-// TODO (crbug.com/1010836): remove when dropping iOS 12.
 @property(nonatomic, assign) BOOL needsSectionCleanupAfterEditing;
 
 @end
@@ -140,7 +139,6 @@
   if (!editing) {
     self.editingWithToolbarButtons = NO;
     if (self.needsSectionCleanupAfterEditing) {
-      [self removeEmptySections];
       self.needsSectionCleanupAfterEditing = NO;
     }
   }
@@ -244,22 +242,15 @@
      forRowAtIndexPath:(NSIndexPath*)indexPath {
   DCHECK_EQ(editingStyle, UITableViewCellEditingStyleDelete);
   base::RecordAction(base::UserMetricsAction("MobileReadingListDeleteEntry"));
-
-  if (@available(iOS 13, *)) {
-    [self deleteItemsAtIndexPaths:@[ indexPath ]
-                       endEditing:YES
-              removeEmptySections:YES];
-  } else {
-    // On IOS 12, the UIKit animation for the swipe-to-delete gesture throws an
-    // exception if the section of the deleted item is removed before the
-    // animation is finished. To prevent this from happening, record that
-    // cleanup is needed and remove the section when self.tableView.editing is
-    // reset to NO when the animation finishes.
-    self.needsSectionCleanupAfterEditing = YES;
-    [self deleteItemsAtIndexPaths:@[ indexPath ]
-                       endEditing:NO
-              removeEmptySections:NO];
-  }
+  // The UIKit animation for the swipe-to-delete gesture throws an exception if
+  // the section of the deleted item is removed before the animation is
+  // finished.  To prevent this from happening, record that cleanup is needed
+  // and remove the section when self.tableView.editing is reset to NO when the
+  // animation finishes.
+  self.needsSectionCleanupAfterEditing = YES;
+  [self deleteItemsAtIndexPaths:@[ indexPath ]
+                     endEditing:NO
+            removeEmptySections:NO];
 }
 
 #pragma mark - UITableViewDelegate
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 7f99aaab..20598217 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -206,6 +206,7 @@
     "//ios/web/js_messaging:unittests",
     "//ios/web/security:unittests",
     "//ios/web/session:unittests",
+    "//ios/web/test:packed_resources",
     "//ios/web/web_view:unittests",
   ]
 
@@ -345,11 +346,10 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
-    "public/test/crw_mock_web_state_delegate.h",
-    "public/test/crw_mock_web_state_delegate.mm",
+    "public/test/crw_fake_web_state_delegate.h",
+    "public/test/crw_fake_web_state_delegate.mm",
   ]
   deps = [
-    "//ios/testing:ocmock_support",
     "//ios/web",
   ]
 }
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.h b/ios/web/public/test/crw_fake_web_state_delegate.h
similarity index 88%
rename from ios/web/public/test/crw_mock_web_state_delegate.h
rename to ios/web/public/test/crw_fake_web_state_delegate.h
index 429e6b7..2e4df225 100644
--- a/ios/web/public/test/crw_mock_web_state_delegate.h
+++ b/ios/web/public/test/crw_fake_web_state_delegate.h
@@ -2,15 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
-#define IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
+#ifndef IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_
+#define IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_
 
-#import "ios/testing/ocmock_complex_type_helper.h"
 #import "ios/web/public/web_state_delegate_bridge.h"
 
 // Stub implementation for CRWWebStateDelegate protocol.
-@interface CRWMockWebStateDelegate
-    : OCMockComplexTypeHelper<CRWWebStateDelegate>
+@interface CRWFakeWebStateDelegate : NSObject <CRWWebStateDelegate>
+
 // web::WebState::OpenURLParams in |webState:openURLWithParams:| call.
 @property(nonatomic, readonly)
     const web::WebState::OpenURLParams* openURLParams;
@@ -51,4 +50,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
+#endif  // IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.mm b/ios/web/public/test/crw_fake_web_state_delegate.mm
similarity index 97%
rename from ios/web/public/test/crw_mock_web_state_delegate.mm
rename to ios/web/public/test/crw_fake_web_state_delegate.mm
index b99a58d..5895391 100644
--- a/ios/web/public/test/crw_mock_web_state_delegate.mm
+++ b/ios/web/public/test/crw_fake_web_state_delegate.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/test/crw_mock_web_state_delegate.h"
+#import "ios/web/public/test/crw_fake_web_state_delegate.h"
 
 #import "ios/web/public/ui/context_menu_params.h"
 #import "ios/web/public/web_state.h"
@@ -11,7 +11,7 @@
 #error "This file requires ARC support."
 #endif
 
-@implementation CRWMockWebStateDelegate {
+@implementation CRWFakeWebStateDelegate {
   // Backs up the property with the same name.
   std::unique_ptr<web::WebState::OpenURLParams> _openURLParams;
   // Backs up the property with the same name.
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
index 86d08f74..f5af0987 100644
--- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -10,10 +10,11 @@
 
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
-#import "ios/web/public/test/crw_mock_web_state_delegate.h"
+#import "ios/web/public/test/crw_fake_web_state_delegate.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #import "ios/web/public/ui/context_menu_params.h"
 #include "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
 #import "third_party/ocmock/gtest_support.h"
 #include "ui/base/page_transition_types.h"
 
@@ -25,6 +26,7 @@
 // any optional methods.
 @interface TestEmptyWebStateDelegate : NSObject<CRWWebStateDelegate>
 @end
+
 @implementation TestEmptyWebStateDelegate
 @end
 
@@ -36,10 +38,7 @@
   void SetUp() override {
     PlatformTest::SetUp();
 
-    id originalMockDelegate =
-        [OCMockObject niceMockForProtocol:@protocol(CRWWebStateDelegate)];
-    delegate_ = [[CRWMockWebStateDelegate alloc]
-        initWithRepresentedObject:originalMockDelegate];
+    delegate_ = [[CRWFakeWebStateDelegate alloc] init];
     empty_delegate_ = [[TestEmptyWebStateDelegate alloc] init];
 
     bridge_.reset(new WebStateDelegateBridge(delegate_));
@@ -47,11 +46,10 @@
   }
 
   void TearDown() override {
-    EXPECT_OCMOCK_VERIFY((OCMockObject*)delegate_);
     PlatformTest::TearDown();
   }
 
-  CRWMockWebStateDelegate* delegate_;
+  CRWFakeWebStateDelegate* delegate_;
   id empty_delegate_;
   std::unique_ptr<WebStateDelegateBridge> bridge_;
   std::unique_ptr<WebStateDelegateBridge> empty_delegate_bridge_;
diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc
index 373b3c0..317fc621 100644
--- a/media/audio/virtual_audio_input_stream.cc
+++ b/media/audio/virtual_audio_input_stream.cc
@@ -17,9 +17,9 @@
 VirtualAudioInputStream::VirtualAudioInputStream(
     const AudioParameters& params,
     const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
-    const AfterCloseCallback& after_close_cb)
+    AfterCloseCallback after_close_cb)
     : worker_task_runner_(worker_task_runner),
-      after_close_cb_(after_close_cb),
+      after_close_cb_(std::move(after_close_cb)),
       callback_(NULL),
       params_(params),
       mixer_(params_, params_, false),
@@ -123,9 +123,7 @@
   // here.  The callback is moved to a stack-local first since |this| could be
   // destroyed during Run().
   if (after_close_cb_) {
-    const AfterCloseCallback cb = after_close_cb_;
-    after_close_cb_.Reset();
-    cb.Run(this);
+    std::move(after_close_cb_).Run(this);
   }
 }
 
diff --git a/media/audio/virtual_audio_input_stream.h b/media/audio/virtual_audio_input_stream.h
index aaceaa34..03e8fc33114 100644
--- a/media/audio/virtual_audio_input_stream.h
+++ b/media/audio/virtual_audio_input_stream.h
@@ -34,7 +34,7 @@
 class MEDIA_EXPORT VirtualAudioInputStream : public AudioInputStream {
  public:
   // Callback invoked just after VirtualAudioInputStream is closed.
-  typedef base::Callback<void(VirtualAudioInputStream* vais)>
+  typedef base::OnceCallback<void(VirtualAudioInputStream* vais)>
       AfterCloseCallback;
 
   // Construct a target for audio loopback which mixes multiple data streams
@@ -44,7 +44,7 @@
   VirtualAudioInputStream(
       const AudioParameters& params,
       const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
-      const AfterCloseCallback& after_close_cb);
+      AfterCloseCallback after_close_cb);
 
   ~VirtualAudioInputStream() override;
 
diff --git a/media/audio/virtual_audio_output_stream.cc b/media/audio/virtual_audio_output_stream.cc
index 7bba9df..2575b1c 100644
--- a/media/audio/virtual_audio_output_stream.cc
+++ b/media/audio/virtual_audio_output_stream.cc
@@ -14,10 +14,14 @@
 namespace media {
 
 VirtualAudioOutputStream::VirtualAudioOutputStream(
-    const AudioParameters& params, VirtualAudioInputStream* target,
-    const AfterCloseCallback& after_close_cb)
-    : params_(params), target_input_stream_(target),
-      after_close_cb_(after_close_cb), callback_(NULL), volume_(1.0f) {
+    const AudioParameters& params,
+    VirtualAudioInputStream* target,
+    AfterCloseCallback after_close_cb)
+    : params_(params),
+      target_input_stream_(target),
+      after_close_cb_(std::move(after_close_cb)),
+      callback_(nullptr),
+      volume_(1.0f) {
   DCHECK(params_.IsValid());
   DCHECK(target);
 
@@ -59,9 +63,7 @@
   // here.  The callback is moved to a stack-local first since |this| could be
   // destroyed during Run().
   if (after_close_cb_) {
-    const AfterCloseCallback cb = after_close_cb_;
-    after_close_cb_.Reset();
-    cb.Run(this);
+    std::move(after_close_cb_).Run(this);
   }
 }
 
diff --git a/media/audio/virtual_audio_output_stream.h b/media/audio/virtual_audio_output_stream.h
index 706097b..57fbedf 100644
--- a/media/audio/virtual_audio_output_stream.h
+++ b/media/audio/virtual_audio_output_stream.h
@@ -26,14 +26,14 @@
       public AudioConverter::InputCallback {
  public:
   // Callback invoked just after VirtualAudioOutputStream is closed.
-  typedef base::Callback<void(VirtualAudioOutputStream* vaos)>
+  typedef base::OnceCallback<void(VirtualAudioOutputStream* vaos)>
       AfterCloseCallback;
 
   // Construct an audio loopback pathway to the given |target| (not owned).
   // |target| must outlive this instance.
   VirtualAudioOutputStream(const AudioParameters& params,
                            VirtualAudioInputStream* target,
-                           const AfterCloseCallback& after_close_cb);
+                           AfterCloseCallback after_close_cb);
 
   ~VirtualAudioOutputStream() override;
 
diff --git a/media/audio/virtual_audio_output_stream_unittest.cc b/media/audio/virtual_audio_output_stream_unittest.cc
index 320b789..0c1d424 100644
--- a/media/audio/virtual_audio_output_stream_unittest.cc
+++ b/media/audio/virtual_audio_output_stream_unittest.cc
@@ -34,7 +34,7 @@
       : VirtualAudioInputStream(
             kParams,
             worker_task_runner,
-            base::Bind(&base::DeletePointer<VirtualAudioInputStream>)) {}
+            base::BindOnce(&base::DeletePointer<VirtualAudioInputStream>)) {}
   ~MockVirtualAudioInputStream() override = default;
 
   MOCK_METHOD2(AddInputProvider,
@@ -92,9 +92,8 @@
                      base::Unretained(input_stream)));
 
   VirtualAudioOutputStream* const output_stream = new VirtualAudioOutputStream(
-      kParams,
-      input_stream,
-      base::Bind(&base::DeletePointer<VirtualAudioOutputStream>));
+      kParams, input_stream,
+      base::BindOnce(&base::DeletePointer<VirtualAudioOutputStream>));
 
   EXPECT_CALL(*input_stream, AddInputProvider(output_stream, _)).Times(kCycles);
   EXPECT_CALL(*input_stream, RemoveInputProvider(output_stream, _))
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc
index 2988da43..9e13371 100644
--- a/media/capture/video/chromeos/camera_device_delegate.cc
+++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -591,6 +591,8 @@
     still_capture_stream->height = blob_height;
     still_capture_stream->format =
         cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_BLOB;
+    // Set usage flag to allow HAL adapter to identify a still capture stream.
+    still_capture_stream->usage = cros::mojom::GRALLOC_USAGE_STILL_CAPTURE;
     still_capture_stream->data_space = 0;
     still_capture_stream->rotation =
         cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
@@ -620,6 +622,9 @@
       reprocessing_stream_output->height = max_yuv_height;
       reprocessing_stream_output->format =
           cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
+      // Set usage flag to allow HAL adapter to identify a still capture stream.
+      reprocessing_stream_output->usage =
+          cros::mojom::GRALLOC_USAGE_STILL_CAPTURE;
       reprocessing_stream_output->data_space = 0;
       reprocessing_stream_output->rotation =
           cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
diff --git a/media/capture/video/chromeos/mojom/camera3.mojom b/media/capture/video/chromeos/mojom/camera3.mojom
index 801ad08..15a2ab0 100644
--- a/media/capture/video/chromeos/mojom/camera3.mojom
+++ b/media/capture/video/chromeos/mojom/camera3.mojom
@@ -18,6 +18,15 @@
 const uint32 GRALLOC_USAGE_HW_COMPOSER = 0x00000800;
 const uint32 GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000;
 const uint32 GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000;
+// A private gralloc usage flag to force allocation of YUV420 buffer.  This
+// usage flag is only valid when allocating HAL_PIXEL_FORMAT_YCbCr_420_888
+// flexible YUV buffers.
+const uint32 GRALLOC_USAGE_FORCE_I420 = 0x10000000;
+// Setting this flag means this stream is intended for still capture. We're
+// using the usage flag as an indicator for an output stream that can be split
+// into a new HAL request for Zero-Shutter Lag (ZSL). See crrev.com/c/1877636
+// for the CL that does the aforementioned things.
+const uint32 GRALLOC_USAGE_STILL_CAPTURE = 0x20000000;
 
 [Extensible]
 enum HalPixelFormat {
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc
index f13d089..bfee794 100644
--- a/media/capture/video/chromeos/request_manager.cc
+++ b/media/capture/video/chromeos/request_manager.cc
@@ -255,6 +255,18 @@
   AddOrUpdateMetadataEntry(settings, std::move(e));
 }
 
+void RequestManager::SetZeroShutterLag(cros::mojom::CameraMetadataPtr* settings,
+                                       bool enabled) {
+  std::vector<uint8_t> control_enable_zsl = {static_cast<uint8_t>(enabled)};
+  cros::mojom::CameraMetadataEntryPtr e =
+      cros::mojom::CameraMetadataEntry::New();
+  e->tag = cros::mojom::CameraMetadataTag::ANDROID_CONTROL_ENABLE_ZSL;
+  e->type = cros::mojom::EntryType::TYPE_BYTE;
+  e->count = 1;
+  e->data = control_enable_zsl;
+  AddOrUpdateMetadataEntry(settings, std::move(e));
+}
+
 void RequestManager::PrepareCaptureRequest() {
   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
 
@@ -441,6 +453,7 @@
     *settings = std::move(take_photo_settings_queue_.front());
     SetJpegOrientation(settings);
   }
+  SetZeroShutterLag(settings, true);
   take_photo_settings_queue_.pop();
   return true;
 }
diff --git a/media/capture/video/chromeos/request_manager.h b/media/capture/video/chromeos/request_manager.h
index 4afd5af..6efa94a 100644
--- a/media/capture/video/chromeos/request_manager.h
+++ b/media/capture/video/chromeos/request_manager.h
@@ -220,6 +220,10 @@
   void SetSensorTimestamp(cros::mojom::CameraMetadataPtr* settings,
                           uint64_t shutter_timestamp);
 
+  // Puts availability of Zero Shutter Lag into the metadata.
+  void SetZeroShutterLag(cros::mojom::CameraMetadataPtr* settings,
+                         bool enabled);
+
   // Prepares a capture request by mixing repeating request with one-shot
   // request if it exists. If there are reprocess requests in the queue, just
   // build the reprocess capture request without mixing the repeating request.
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 81cc982b..ff23df07 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -1045,6 +1045,22 @@
                stream->traffic_annotation());
 }
 
+bool SpdySession::GreasedFramesEnabled() const {
+  return greased_http2_frame_.has_value();
+}
+
+void SpdySession::EnqueueGreasedFrame(const base::WeakPtr<SpdyStream>& stream) {
+  if (availability_state_ == STATE_DRAINING)
+    return;
+
+  EnqueueWrite(
+      stream->priority(),
+      static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type),
+      std::make_unique<GreasedBufferProducer>(
+          stream, &greased_http2_frame_.value(), buffered_spdy_framer_.get()),
+      stream, stream->traffic_annotation());
+}
+
 int SpdySession::ConfirmHandshake(CompletionOnceCallback callback) {
   int rv = ERR_IO_PENDING;
   if (!in_confirm_handshake_) {
@@ -2698,6 +2714,15 @@
                std::make_unique<SimpleBufferProducer>(std::move(buffer)),
                base::WeakPtr<SpdyStream>(),
                kSpdySessionCommandsTrafficAnnotation);
+  if (greased_http2_frame_ && frame_type == spdy::SpdyFrameType::SETTINGS) {
+    EnqueueWrite(
+        priority,
+        static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type),
+        std::make_unique<GreasedBufferProducer>(base::WeakPtr<SpdyStream>(),
+                                                &greased_http2_frame_.value(),
+                                                buffered_spdy_framer_.get()),
+        base::WeakPtr<SpdyStream>(), kSpdySessionCommandsTrafficAnnotation);
+  }
 }
 
 void SpdySession::EnqueueWrite(
@@ -2711,15 +2736,6 @@
 
   write_queue_.Enqueue(priority, frame_type, std::move(producer), stream,
                        traffic_annotation);
-  if (greased_http2_frame_ && (frame_type == spdy::SpdyFrameType::SETTINGS ||
-                               frame_type == spdy::SpdyFrameType::HEADERS)) {
-    write_queue_.Enqueue(
-        priority,
-        static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type),
-        std::make_unique<GreasedBufferProducer>(
-            stream, &greased_http2_frame_.value(), buffered_spdy_framer_.get()),
-        stream, traffic_annotation);
-  }
   MaybePostWriteLoop();
 }
 
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 750e983..6e9ed3fe 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -400,6 +400,14 @@
                           spdy::SpdyFrameType frame_type,
                           std::unique_ptr<SpdyBufferProducer> producer);
 
+  // Returns true if this session is configured to send greased HTTP/2 frames.
+  // For more details on greased frames, see
+  // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
+  bool GreasedFramesEnabled() const;
+
+  // Send greased frame, that is, a frame of reserved type.
+  void EnqueueGreasedFrame(const base::WeakPtr<SpdyStream>& stream);
+
   // Runs the handshake to completion to confirm the handshake with the server.
   // If ERR_IO_PENDING is returned, then when the handshake is confirmed,
   // |callback| will be called.
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 9b45f47..a185381 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -6004,7 +6004,7 @@
   EXPECT_FALSE(session_);
 }
 
-TEST_F(SpdySessionTest, GreaseFrameType) {
+TEST_F(SpdySessionTest, GreaseFrameTypeAfterSettings) {
   const uint8_t type = 0x0b;
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
@@ -6032,63 +6032,107 @@
       CombineFrames({&preface, &settings_frame});
 
   // Greased frame sent on stream 0 after initial SETTINGS frame.
-  const char kRawFrameData0[] = {
+  const char kRawFrameData[] = {
       0x00, 0x00, 0x03,        // length
       0x0b,                    // type
       0xcc,                    // flags
       0x00, 0x00, 0x00, 0x00,  // stream ID
       'f',  'o',  'o'          // payload
   };
-  spdy::SpdySerializedFrame grease0(const_cast<char*>(kRawFrameData0),
-                                    base::size(kRawFrameData0),
-                                    /* owns_buffer = */ false);
-  spdy::SpdySerializedFrame req(
-      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
-
-  // Greased frame sent on stream 1 after request.
-  const char kRawFrameData1[] = {
-      0x00, 0x00, 0x03,        // length
-      0x0b,                    // type
-      0xcc,                    // flags
-      0x00, 0x00, 0x00, 0x01,  // stream ID
-      'f',  'o',  'o'          // payload
-  };
-  spdy::SpdySerializedFrame grease1(const_cast<char*>(kRawFrameData1),
-                                    base::size(kRawFrameData1),
-                                    /* owns_buffer = */ false);
+  spdy::SpdySerializedFrame grease(const_cast<char*>(kRawFrameData),
+                                   base::size(kRawFrameData),
+                                   /* owns_buffer = */ false);
 
   MockWrite writes[] = {CreateMockWrite(combined_frame, 0),
-                        CreateMockWrite(grease0, 1), CreateMockWrite(req, 2),
-                        CreateMockWrite(grease1, 3)};
+                        CreateMockWrite(grease, 1)};
 
-  spdy::SpdySerializedFrame resp(
-      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
-  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
-
-  MockRead reads[] = {CreateMockRead(resp, 4), CreateMockRead(body, 5),
-                      MockRead(ASYNC, 0, 6)};
+  MockRead reads[] = {MockRead(ASYNC, 0, 2)};
 
   SequencedSocketData data(reads, writes);
   session_deps_.socket_factory->AddSocketDataProvider(&data);
   AddSSLSocketData();
-
   CreateNetworkSession();
 
   SpdySessionPoolPeer pool_peer(spdy_session_pool_);
   pool_peer.SetEnableSendingInitialData(true);
 
   CreateSpdySession();
+  base::RunLoop().RunUntilIdle();
 
-  base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
+  EXPECT_TRUE(data.AllWriteDataConsumed());
+  EXPECT_TRUE(data.AllReadDataConsumed());
+}
+
+TEST_F(SpdySessionTest, GreaseFrameTypeOnRequestStream) {
+  const uint8_t type = 0x0b;
+  const uint8_t flags = 0xcc;
+  const std::string payload("foo");
+  session_deps_.greased_http2_frame =
+      base::Optional<net::SpdySessionPool::GreasedHttp2Frame>(
+          {type, flags, payload});
+
+  // No greased frame is sent after a HEADERS frame with END_STREAM set.
+  spdy::SpdySerializedFrame req1(
+      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
+
+  // A greased frame is sent between the HEADERS and the DATA frame.
+  spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
+      kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
+  const char kRawFrameData[] = {
+      0x00, 0x00, 0x03,        // length
+      0x0b,                    // type
+      0xcc,                    // flags
+      0x00, 0x00, 0x00, 0x03,  // stream ID
+      'f',  'o',  'o'          // payload
+  };
+  spdy::SpdySerializedFrame grease(const_cast<char*>(kRawFrameData),
+                                   base::size(kRawFrameData),
+                                   /* owns_buffer = */ false);
+  spdy::SpdySerializedFrame request_body(
+      spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
+
+  MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
+                        CreateMockWrite(grease, 2),
+                        CreateMockWrite(request_body, 3)};
+
+  spdy::SpdySerializedFrame resp1(
+      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+  spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
+  spdy::SpdySerializedFrame resp2(
+      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
+  spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
+
+  MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(body1, 5),
+                      CreateMockRead(resp2, 6), CreateMockRead(body2, 7),
+                      MockRead(ASYNC, 0, 8)};
+
+  SequencedSocketData data(reads, writes);
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
+  AddSSLSocketData();
+  CreateNetworkSession();
+  CreateSpdySession();
+
+  base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
       SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY,
       NetLogWithSource());
-  test::StreamDelegateDoNothing delegate(stream);
-  stream->SetDelegate(&delegate);
+  test::StreamDelegateDoNothing delegate1(stream1);
+  stream1->SetDelegate(&delegate1);
 
-  stream->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
-                             NO_MORE_DATA_TO_SEND);
+  stream1->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
+                              NO_MORE_DATA_TO_SEND);
 
-  EXPECT_THAT(delegate.WaitForClose(), IsOk());
+  base::WeakPtr<SpdyStream> stream2 = CreateStreamSynchronously(
+      SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY,
+      NetLogWithSource());
+  test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
+  stream2->SetDelegate(&delegate2);
+
+  stream2->SendRequestHeaders(
+      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize),
+      MORE_DATA_TO_SEND);
+
+  EXPECT_THAT(delegate1.WaitForClose(), IsOk());
+  EXPECT_THAT(delegate2.WaitForClose(), IsOk());
 
   base::RunLoop().RunUntilIdle();
 
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 8df8a74d..3cc8b2e6 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -867,6 +867,10 @@
         &SpdyStream::OnWriteBufferConsumed, GetWeakPtr(), payload_size));
   }
 
+  if (session_->GreasedFramesEnabled()) {
+    session_->EnqueueGreasedFrame(GetWeakPtr());
+  }
+
   session_->EnqueueStreamWrite(
       GetWeakPtr(), spdy::SpdyFrameType::DATA,
       std::make_unique<SimpleBufferProducer>(std::move(data_buffer)));
diff --git a/services/network/cross_origin_resource_policy.cc b/services/network/cross_origin_resource_policy.cc
index 02e62e4..da99aad 100644
--- a/services/network/cross_origin_resource_policy.cc
+++ b/services/network/cross_origin_resource_policy.cc
@@ -43,7 +43,7 @@
   if (header_value == "same-site")
     return CrossOriginResourcePolicy::kSameSite;
 
-  if (base::FeatureList::IsEnabled(features::kCrossOriginEmbedderPolicy) &&
+  if (base::FeatureList::IsEnabled(features::kCrossOriginIsolation) &&
       header_value == "cross-origin") {
     return CrossOriginResourcePolicy::kCrossOrigin;
   }
@@ -126,7 +126,7 @@
   // COEP https://mikewest.github.io/corpp/#corp-check
   if ((policy == kNoHeader || policy == kParsingError) &&
       embedder_policy == mojom::CrossOriginEmbedderPolicy::kRequireCorp) {
-    DCHECK(base::FeatureList::IsEnabled(features::kCrossOriginEmbedderPolicy));
+    DCHECK(base::FeatureList::IsEnabled(features::kCrossOriginIsolation));
     policy = kSameOrigin;
   }
 
diff --git a/services/network/cross_origin_resource_policy_unittest.cc b/services/network/cross_origin_resource_policy_unittest.cc
index 8ac408b..f4952f2 100644
--- a/services/network/cross_origin_resource_policy_unittest.cc
+++ b/services/network/cross_origin_resource_policy_unittest.cc
@@ -70,14 +70,14 @@
 
 TEST(CrossOriginResourcePolicyTest, CrossSiteHeaderWithCOEP) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(features::kCrossOriginEmbedderPolicy);
+  feature_list.InitAndEnableFeature(features::kCrossOriginIsolation);
   EXPECT_EQ(CrossOriginResourcePolicy::kCrossOrigin,
             ParseHeader("Cross-Origin-Resource-Policy: cross-origin"));
 }
 
 TEST(CrossOriginResourcePolicyTest, CrossSiteHeaderWithoutCOEP) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndDisableFeature(features::kCrossOriginEmbedderPolicy);
+  feature_list.InitAndDisableFeature(features::kCrossOriginIsolation);
   EXPECT_EQ(CrossOriginResourcePolicy::kParsingError,
             ParseHeader("Cross-Origin-Resource-Policy: cross-origin"));
 }
@@ -125,7 +125,7 @@
 
 TEST(CrossOriginResourcePolicyTest, WithCOEP) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(features::kCrossOriginEmbedderPolicy);
+  feature_list.InitAndEnableFeature(features::kCrossOriginIsolation);
 
   ResourceResponseInfo corp_none;
   ResourceResponseInfo corp_same_origin;
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index bc9a4bb..f1153a9b 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -96,9 +96,12 @@
     "ProactivelyThrottleLowPriorityRequests",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// This is for Cross-Origin-Opener-Policy (COOP) and
+// Cross-Origin-Embedder-Policy (COEP).
+// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
 // https://github.com/mikewest/corpp
-const base::Feature kCrossOriginEmbedderPolicy{
-    "CrossOriginEmbedderPolicy", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kCrossOriginIsolation{"CrossOriginIsolation",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
 // When kBlockNonSecureExternalRequests is enabled, requests initiated from a
 // pubic network may only target a private network if the initiating context
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 87fc8bf..4cb8acf8 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -41,7 +41,7 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kProactivelyThrottleLowPriorityRequests;
 COMPONENT_EXPORT(NETWORK_CPP)
-extern const base::Feature kCrossOriginEmbedderPolicy;
+extern const base::Feature kCrossOriginIsolation;
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kBlockNonSecureExternalRequests;
 COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 99da57ad..83f7628 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -497,6 +497,7 @@
     "//third_party/libwebp:libwebp_webp",
   ]
   public_deps = [
+    ":buildflags",
     ":skia_core_and_effects",
   ]
   if (skia_use_dawn) {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index f479590..34dae91 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -6752,6 +6752,7 @@
       {
         "args": [
           "--use-vulkan=native",
+          "--gr-context-type=vulkan",
           "--disable-vulkan-fallback-to-gl-for-testing",
           "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index de79137..62828bc 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3862,6 +3862,7 @@
       'vulkan_content_browsertests': {
         'args': [
           '--use-vulkan=native',
+          '--gr-context-type=vulkan',
           '--disable-vulkan-fallback-to-gl-for-testing',
           '--enable-features=UseSkiaRenderer',
           '--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter',
diff --git a/third_party/blink/common/http/structured_header.cc b/third_party/blink/common/http/structured_header.cc
index 6cf1ffd..329349f9 100644
--- a/third_party/blink/common/http/structured_header.cc
+++ b/third_party/blink/common/http/structured_header.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/base64.h"
+#include "base/containers/flat_set.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 
@@ -20,38 +21,56 @@
 #define LCALPHA "abcdefghijklmnopqrstuvwxyz"
 #define UCALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.9
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.7
 constexpr char kTokenChars[] = DIGIT UCALPHA LCALPHA "_-.:%*/";
 // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.1
-constexpr char kKeyChars[] = DIGIT LCALPHA "_-";
+constexpr char kKeyChars09[] = DIGIT LCALPHA "_-";
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.1
+constexpr char kKeyChars13[] = DIGIT LCALPHA "_-*";
 #undef DIGIT
 #undef LCALPHA
 #undef UCALPHA
 
 // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.8
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.6
 bool IsPrintableASCII(char c) {
   return ' ' <= c && c <= '~';  // 0x20 (' ') to 0x7E ('~')
 }
 
-// Parser for (a subset of) Structured Headers for HTTP defined in [SH].
-// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09
+// Parser for (a subset of) Structured Headers for HTTP defined in [SH09] and
+// [SH13]. [SH09] compatibility is retained for use by Web Packaging, and can be
+// removed once that spec is updated, and users have migrated to new headers.
+// [SH09] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09
+// [SH13] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13
 class StructuredHeaderParser {
  public:
-  explicit StructuredHeaderParser(const base::StringPiece& str) : input_(str) {
-    // [SH] 4.2. Step 1. Discard any leading OWS from input_string.
+  enum DraftVersion {
+    kDraft09,
+    kDraft13,
+  };
+  explicit StructuredHeaderParser(const base::StringPiece& str,
+                                  DraftVersion version)
+      : input_(str), version_(version) {
+    // [SH09] 4.2 Step 1.
+    // [SH13] 4.2 Step 2.
+    // Discard any leading OWS from input_string.
     SkipWhitespaces();
   }
 
   // Callers should call this after ReadSomething(), to check if parser has
   // consumed all the input successfully.
   bool FinishParsing() {
-    // [SH] 4.2 Step 7. Discard any leading OWS from input_string.
+    // [SH09] 4.2 Step 7. [SH13] 4.2 Step 6.
+    // Discard any leading OWS from input_string.
     SkipWhitespaces();
-    // [SH] 4.2 Step 8. If input_string is not empty, fail parsing.
+    // [SH09] 4.2 Step 8. [SH13] 4.2 Step 7.
+    // If input_string is not empty, fail parsing.
     return input_.empty();
   }
 
-  // Parses a List of Lists ([SH] 4.2.4).
+  // Parses a List of Lists ([SH09] 4.2.4).
   base::Optional<ListOfLists> ReadListOfLists() {
+    DCHECK_EQ(version_, kDraft09);
     ListOfLists result;
     while (true) {
       std::vector<Item> inner_list;
@@ -74,7 +93,26 @@
     return result;
   }
 
-  // Parses an Item ([SH] 4.2.7).
+  // Parses a List ([SH13] 4.2.1).
+  base::Optional<List> ReadList() {
+    DCHECK_EQ(version_, kDraft13);
+    List members;
+    while (!input_.empty()) {
+      base::Optional<ParameterizedMember> member(ReadParameterizedMember());
+      if (!member)
+        return base::nullopt;
+      members.push_back(std::move(*member));
+      SkipWhitespaces();
+      if (!ConsumeChar(','))
+        break;
+      SkipWhitespaces();
+      if (input_.empty())
+        return base::nullopt;
+    }
+    return members;
+  }
+
+  // Parses an Item ([SH09] 4.2.7, [SH13] 4.2.3).
   // Currently only limited types (non-negative integers, strings, tokens and
   // byte sequences) are supported.
   // TODO(1011101): Add support for other types.
@@ -96,8 +134,9 @@
     }
   }
 
-  // Parses a Parameterised List ([SH] 4.2.5).
+  // Parses a Parameterised List ([SH09] 4.2.5).
   base::Optional<ParameterisedList> ReadParameterisedList() {
+    DCHECK_EQ(version_, kDraft09);
     ParameterisedList items;
     while (true) {
       base::Optional<ParameterisedIdentifier> item =
@@ -113,8 +152,9 @@
   }
 
  private:
-  // Parses a Parameterised Identifier ([SH] 4.2.6).
+  // Parses a Parameterised Identifier ([SH09] 4.2.6).
   base::Optional<ParameterisedIdentifier> ReadParameterisedIdentifier() {
+    DCHECK_EQ(version_, kDraft09);
     base::Optional<Item> primary_identifier = ReadToken();
     if (!primary_identifier)
       return base::nullopt;
@@ -147,13 +187,84 @@
                                    std::move(parameters));
   }
 
-  // Parses a Key ([SH] 4.2.2).
+  // Parses a Parameterized Member ([SH13] 4.2.1.1).
+  base::Optional<ParameterizedMember> ReadParameterizedMember() {
+    DCHECK_EQ(version_, kDraft13);
+    std::vector<Item> member;
+    bool member_is_inner_list = ConsumeChar('(');
+    if (member_is_inner_list) {
+      base::Optional<std::vector<Item>> inner_list = ReadInnerList();
+      if (!inner_list)
+        return base::nullopt;
+      member = std::move(*inner_list);
+    } else {
+      base::Optional<Item> item = ReadItem();
+      if (!item)
+        return base::nullopt;
+      member.push_back(std::move(*item));
+    }
+
+    ParameterizedMember::Parameters parameters;
+    base::flat_set<std::string> keys;
+
+    SkipWhitespaces();
+    while (ConsumeChar(';')) {
+      SkipWhitespaces();
+
+      base::Optional<std::string> name = ReadKey();
+      if (!name)
+        return base::nullopt;
+      bool is_duplicate_key = !keys.insert(*name).second;
+      if (is_duplicate_key) {
+        DVLOG(1) << "ReadParameterizedMember: duplicated parameter: " << *name;
+        return base::nullopt;
+      }
+
+      Item value;
+      if (ConsumeChar('=')) {
+        auto item = ReadItem();
+        if (!item)
+          return base::nullopt;
+        value = std::move(*item);
+      }
+      parameters.emplace_back(std::move(*name), std::move(value));
+      SkipWhitespaces();
+    }
+    return ParameterizedMember(std::move(member), member_is_inner_list,
+                               std::move(parameters));
+  }
+
+  // Parses an Inner List ([SH13] 4.2.1.2).
+  // Note that the initial '(' character should already have been consumed by
+  // the caller to determine that this is in fact an inner list.
+  base::Optional<std::vector<Item>> ReadInnerList() {
+    DCHECK_EQ(version_, kDraft13);
+    std::vector<Item> inner_list;
+    while (true) {
+      SkipWhitespaces();
+      if (ConsumeChar(')')) {
+        return inner_list;
+      }
+      auto item = ReadItem();
+      if (!item)
+        return base::nullopt;
+      inner_list.push_back(std::move(*item));
+      if (input_.empty() || (input_.front() != ' ' && input_.front() != ')'))
+        return base::nullopt;
+    }
+    NOTREACHED();
+    return base::nullopt;
+  }
+
+  // Parses a Key ([SH09] 4.2.2, [SH13] 4.2.1.3).
   base::Optional<std::string> ReadKey() {
     if (input_.empty() || !base::IsAsciiLower(input_.front())) {
       LogParseError("ReadKey", "lcalpha");
       return base::nullopt;
     }
-    size_t len = input_.find_first_not_of(kKeyChars);
+    const char* allowed_chars =
+        (version_ == kDraft09 ? kKeyChars09 : kKeyChars13);
+    size_t len = input_.find_first_not_of(allowed_chars);
     if (len == base::StringPiece::npos)
       len = input_.size();
     std::string key(input_.substr(0, len));
@@ -161,7 +272,7 @@
     return key;
   }
 
-  // Parses a Token ([SH] 4.2.10).
+  // Parses a Token ([SH09] 4.2.10, [SH13] 4.2.6).
   base::Optional<Item> ReadToken() {
     if (input_.empty() || !base::IsAsciiAlpha(input_.front())) {
       LogParseError("ReadToken", "ALPHA");
@@ -175,7 +286,7 @@
     return Item(std::move(token), Item::kTokenType);
   }
 
-  // Parses a Number ([SH] 4.2.8).
+  // Parses a Number ([SH09] 4.2.8, [SH13] 4.2.4).
   // Currently only supports non-negative integers.
   base::Optional<Item> ReadNumber() {
     size_t i = 0;
@@ -198,7 +309,7 @@
     return Item(n);
   }
 
-  // Parses a String ([SH] 4.2.9).
+  // Parses a String ([SH09] 4.2.9, [SH13] 4.2.5).
   base::Optional<Item> ReadString() {
     std::string s;
     if (!ConsumeChar('"')) {
@@ -237,7 +348,7 @@
     return s;
   }
 
-  // Parses a Byte Sequence ([SH] 4.2.11).
+  // Parses a Byte Sequence ([SH09] 4.2.11, [SH13] 4.2.7).
   base::Optional<Item> ReadByteSequence() {
     if (!ConsumeChar('*')) {
       LogParseError("ReadByteSequence", "'*'");
@@ -281,6 +392,8 @@
   }
 
   base::StringPiece input_;
+  DraftVersion version_;
+
   DISALLOW_COPY_AND_ASSIGN(StructuredHeaderParser);
 };
 
@@ -314,6 +427,22 @@
   }
 }
 
+ParameterizedMember::ParameterizedMember(const ParameterizedMember&) = default;
+ParameterizedMember& ParameterizedMember::operator=(
+    const ParameterizedMember&) = default;
+ParameterizedMember::ParameterizedMember(std::vector<Item> id,
+                                         bool member_is_inner_list,
+                                         const Parameters& ps)
+    : member(std::move(id)),
+      member_is_inner_list(member_is_inner_list),
+      params(ps) {}
+ParameterizedMember::ParameterizedMember(std::vector<Item> id,
+                                         const Parameters& ps)
+    : member(std::move(id)), member_is_inner_list(true), params(ps) {}
+ParameterizedMember::ParameterizedMember(Item id, const Parameters& ps)
+    : member({std::move(id)}), member_is_inner_list(false), params(ps) {}
+ParameterizedMember::~ParameterizedMember() = default;
+
 ParameterisedIdentifier::ParameterisedIdentifier(
     const ParameterisedIdentifier&) = default;
 ParameterisedIdentifier& ParameterisedIdentifier::operator=(
@@ -323,7 +452,7 @@
 ParameterisedIdentifier::~ParameterisedIdentifier() = default;
 
 base::Optional<Item> ParseItem(const base::StringPiece& str) {
-  StructuredHeaderParser parser(str);
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
   base::Optional<Item> item = parser.ReadItem();
   if (item && parser.FinishParsing())
     return item;
@@ -332,7 +461,7 @@
 
 base::Optional<ParameterisedList> ParseParameterisedList(
     const base::StringPiece& str) {
-  StructuredHeaderParser parser(str);
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
   base::Optional<ParameterisedList> param_list = parser.ReadParameterisedList();
   if (param_list && parser.FinishParsing())
     return param_list;
@@ -340,12 +469,20 @@
 }
 
 base::Optional<ListOfLists> ParseListOfLists(const base::StringPiece& str) {
-  StructuredHeaderParser parser(str);
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
   base::Optional<ListOfLists> list_of_lists = parser.ReadListOfLists();
   if (list_of_lists && parser.FinishParsing())
     return list_of_lists;
   return base::nullopt;
 }
 
+base::Optional<List> ParseList(const base::StringPiece& str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft13);
+  base::Optional<List> list = parser.ReadList();
+  if (list && parser.FinishParsing())
+    return list;
+  return base::nullopt;
+}
+
 }  // namespace http_structured_header
 }  // namespace blink
diff --git a/third_party/blink/common/http/structured_header_unittest.cc b/third_party/blink/common/http/structured_header_unittest.cc
index 4e9848e..8c4598e 100644
--- a/third_party/blink/common/http/structured_header_unittest.cc
+++ b/third_party/blink/common/http/structured_header_unittest.cc
@@ -10,6 +10,27 @@
 
 namespace blink {
 namespace http_structured_header {
+namespace {
+
+// Helpers to make test cases clearer
+
+Item Token(std::string value) {
+  return Item(value, Item::kTokenType);
+}
+
+std::pair<std::string, Item> Param(std::string key) {
+  return std::make_pair(key, Item());
+}
+
+std::pair<std::string, Item> Param(std::string key, int64_t value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> Param(std::string key, std::string value) {
+  return std::make_pair(key, Item(value));
+}
+
+}  // namespace
 
 // Test cases are taken from https://github.com/httpwg/structured-header-tests.
 
@@ -20,15 +41,12 @@
     const base::Optional<Item> expected;  // nullopt if parse error is expected
   } cases[] = {
       // Item
-      {"basic token - item", "a_b-c.d3:f%00/*",
-       Item("a_b-c.d3:f%00/*", Item::kTokenType)},
-      {"token with capitals - item", "fooBar",
-       Item("fooBar", Item::kTokenType)},
-      {"token starting with capitals - item", "FooBar",
-       Item("FooBar", Item::kTokenType)},
+      {"basic token - item", "a_b-c.d3:f%00/*", Token("a_b-c.d3:f%00/*")},
+      {"token with capitals - item", "fooBar", Token("fooBar")},
+      {"token starting with capitals - item", "FooBar", Token("FooBar")},
       {"bad token - item", "abc$%!", base::nullopt},
-      {"leading whitespace", " foo", Item("foo", Item::kTokenType)},
-      {"trailing whitespace", "foo ", Item("foo", Item::kTokenType)},
+      {"leading whitespace", " foo", Token("foo")},
+      {"trailing whitespace", "foo ", Token("foo")},
       // Number
       {"basic integer", "42", Item(42)},
       {"zero integer", "0", Item(0)},
@@ -73,16 +91,74 @@
       {"abruptly ending string quote", "\"foo \\", base::nullopt},
   };
   for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
     base::Optional<Item> result = ParseItem(c.raw);
-    if (c.expected) {
-      EXPECT_TRUE(result.has_value()) << c.name;
-      EXPECT_EQ(*result, c.expected) << c.name;
-    } else {
-      EXPECT_FALSE(result.has_value()) << c.name;
-    }
+    EXPECT_EQ(result, c.expected);
   }
 }
 
+// For Structured Headers Draft 13
+TEST(StructuredHeaderTest, ParseList) {
+  struct ListTestCase {
+    const char* name;
+    const char* raw;
+    const base::Optional<List> expected;  // nullopt if parse error is expected.
+  } cases[] = {
+      // Basic lists
+      {"basic list", "1, 42", {{{Item(1), {}}, {Item(42), {}}}}},
+      {"empty list", "", List()},
+      {"single item list", "42", {{{Item(42), {}}}}},
+      {"no whitespace list", "1, 42", {{{Item(1), {}}, {Item(42), {}}}}},
+      {"trailing comma list", "1, 42,", base::nullopt},
+      {"empty item list", "1,,42", base::nullopt},
+      // Lists of lists
+      {"basic list of lists",
+       "(1 2), (42 43)",
+       {{{{Item(1), Item(2)}, {}}, {{Item(42), Item(43)}, {}}}}},
+      {"single item list of lists",
+       "(42)",
+       {{{std::vector<Item>{Item(42)}, {}}}}},
+      {"empty item list of lists", "()", {{{std::vector<Item>(), {}}}}},
+      {"empty middle item list of lists",
+       "(1),(),(42)",
+       {{{std::vector<Item>{Item(1)}, {}},
+         {std::vector<Item>(), {}},
+         {std::vector<Item>{Item(42)}, {}}}}},
+      {"extra whitespace list of lists",
+       "(1  42)",
+       {{{{Item(1), Item(42)}, {}}}}},
+      {"no trailing parenthesis list of lists", "(1 42", base::nullopt},
+      {"no trailing parenthesis middle list of lists", "(1 2, (42 43)",
+       base::nullopt},
+      // Parameterized Lists
+      {"basic parameterised list",
+       "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"",
+       {{{Token("abc_123"), {Param("a", 1), Param("b", 2), Param("cdef_456")}},
+         {Token("ghi"), {Param("q", "9"), Param("r", "w")}}}}},
+      {"single item parameterised list",
+       "text/html;q=1",
+       {{{Token("text/html"), {Param("q", 1)}}}}},
+      {"no whitespace parameterised list",
+       "text/html,text/plain;q=1",
+       {{{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}},
+      {"whitespace before = parameterised list", "text/html, text/plain;q =1",
+       base::nullopt},
+      {"whitespace after = parameterised list", "text/html, text/plain;q= 1",
+       base::nullopt},
+      {"extra whitespace param-list",
+       "text/html  ,  text/plain ;  q=1",
+       {{{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}},
+      {"empty item parameterised list", "text/html,,text/plain;q=1",
+       base::nullopt},
+  };
+  for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
+    base::Optional<List> result = ParseList(c.raw);
+    EXPECT_EQ(result, c.expected);
+  }
+}
+
+// For Structured Headers Draft 9
 TEST(StructuredHeaderTest, ParseListOfLists) {
   struct TestCase {
     const char* name;
@@ -110,21 +186,18 @@
       {"empty inner item list of lists", "1;;2,42", {}},
   };
   for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
     base::Optional<ListOfLists> result = ParseListOfLists(c.raw);
     if (!c.expected.empty()) {
-      EXPECT_TRUE(result.has_value()) << c.name;
-      EXPECT_EQ(*result, c.expected) << c.name;
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(*result, c.expected);
     } else {
-      EXPECT_FALSE(result.has_value()) << c.name;
+      EXPECT_FALSE(result.has_value());
     }
   }
 }
 
-inline bool operator==(const ParameterisedIdentifier& lhs,
-                       const ParameterisedIdentifier& rhs) {
-  return lhs.identifier == rhs.identifier && lhs.params == rhs.params;
-}
-
+// For Structured Headers Draft 9
 TEST(StructuredHeaderTest, ParseParameterisedList) {
   struct TestCase {
     const char* name;
@@ -134,26 +207,23 @@
       {"basic param-list",
        "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"",
        {
-           {Item("abc_123", Item::kTokenType),
-            {{"a", Item(1)}, {"b", Item(2)}, {"cdef_456", {}}}},
-           {Item("ghi", Item::kTokenType),
-            {{"q", Item("9")}, {"r", Item("w")}}},
+           {Token("abc_123"),
+            {Param("a", 1), Param("b", 2), Param("cdef_456")}},
+           {Token("ghi"), {Param("q", "9"), Param("r", "w")}},
        }},
       {"empty param-list", "", {}},
       {"single item param-list",
        "text/html;q=1",
-       {{Item("text/html", Item::kTokenType), {{"q", Item(1)}}}}},
+       {{Token("text/html"), {Param("q", 1)}}}},
       {"empty param-list", "", {}},
       {"no whitespace param-list",
        "text/html,text/plain;q=1",
-       {{Item("text/html", Item::kTokenType), {}},
-        {Item("text/plain", Item::kTokenType), {{"q", Item(1)}}}}},
+       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
       {"whitespace before = param-list", "text/html, text/plain;q =1", {}},
       {"whitespace after = param-list", "text/html, text/plain;q= 1", {}},
       {"extra whitespace param-list",
        "text/html  ,  text/plain ;  q=1",
-       {{Item("text/html", Item::kTokenType), {}},
-        {Item("text/plain", Item::kTokenType), {{"q", Item(1)}}}}},
+       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
       {"duplicate key", "abc;a=1;b=2;a=1", {}},
       {"numeric key", "abc;a=1;1b=2;c=1", {}},
       {"uppercase key", "abc;a=1;B=2;c=1", {}},
@@ -168,16 +238,17 @@
       {"leading comma", ",abc;a=1", {}},
   };
   for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
     base::Optional<ParameterisedList> result = ParseParameterisedList(c.raw);
     if (c.expected.empty()) {
-      EXPECT_FALSE(result.has_value()) << c.name;
+      EXPECT_FALSE(result.has_value());
       continue;
     }
-    EXPECT_TRUE(result.has_value()) << c.name;
-    EXPECT_EQ(result->size(), c.expected.size()) << c.name;
+    EXPECT_TRUE(result.has_value());
+    EXPECT_EQ(result->size(), c.expected.size());
     if (result->size() == c.expected.size()) {
       for (size_t i = 0; i < c.expected.size(); ++i)
-        EXPECT_EQ((*result)[i], c.expected[i]) << c.name;
+        EXPECT_EQ((*result)[i], c.expected[i]);
     }
   }
 }
diff --git a/third_party/blink/public/common/http/structured_header.h b/third_party/blink/public/common/http/structured_header.h
index 73055ec..9adef24c 100644
--- a/third_party/blink/public/common/http/structured_header.h
+++ b/third_party/blink/public/common/http/structured_header.h
@@ -20,6 +20,13 @@
 // This file implements parsing of HTTP structured headers, as defined in
 // https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html.
 //
+// Both drafts 9 and 13 are currently supported. The major difference
+// between the two drafts is in the various list formats: Draft 9 describes
+// Parameterised lists and lists-of-lists, while draft 13 uses a single List
+// syntax, whose members may be inner lists. There should be no ambiguity,
+// however, as the code which calls this parser should be expecting only a
+// single type for a given header.
+//
 // Currently supported data types are:
 //  Item:
 //   integer: 123
@@ -28,6 +35,9 @@
 //   byte sequence: *YWJj*
 //  Parameterised list: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w"
 //  List-of-lists: "foo";"bar", "baz", "bat"; "one"
+//  List: "foo", "bar", "It was the best of times."
+//        ("foo" "bar"), ("baz"), ("bat" "one"), ()
+//        abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w
 //
 // Functions are provided to parse each of these, which are intended to be
 // called with the complete value of an HTTP header (that is, any
@@ -87,6 +97,9 @@
   std::string string_value_;
 };
 
+// Holds a ParameterizedIdentifier (draft 9 only). The contained Item must be a
+// Token, and there may be any number of parameters. Parameter ordering is not
+// significant.
 struct BLINK_COMMON_EXPORT ParameterisedIdentifier {
   using Parameters = std::map<std::string, Item>;
 
@@ -99,8 +112,45 @@
   ~ParameterisedIdentifier();
 };
 
+inline bool operator==(const ParameterisedIdentifier& lhs,
+                       const ParameterisedIdentifier& rhs) {
+  return lhs.identifier == rhs.identifier && lhs.params == rhs.params;
+}
+
+// Holds a ParameterizedMember, which may be either an Inner List, or a single
+// Item, with any number of parameters. Parameter ordering is significant.
+struct BLINK_COMMON_EXPORT ParameterizedMember {
+  using Parameters = std::vector<std::pair<std::string, Item>>;
+
+  std::vector<Item> member;
+  // If false, then |member| should only hold one Item.
+  bool member_is_inner_list;
+
+  Parameters params;
+
+  ParameterizedMember(const ParameterizedMember&);
+  ParameterizedMember& operator=(const ParameterizedMember&);
+  ParameterizedMember(std::vector<Item>, bool, const Parameters&);
+  // Shorthand constructor for a member which is an inner list.
+  ParameterizedMember(std::vector<Item>, const Parameters&);
+  // Shorthand constructor for a member which is a single Item.
+  ParameterizedMember(Item, const Parameters&);
+  ~ParameterizedMember();
+};
+
+inline bool operator==(const ParameterizedMember& lhs,
+                       const ParameterizedMember& rhs) {
+  return lhs.member == rhs.member &&
+         lhs.member_is_inner_list == rhs.member_is_inner_list &&
+         lhs.params == rhs.params;
+}
+
+// Structured Headers Draft 09 Parameterised List.
 using ParameterisedList = std::vector<ParameterisedIdentifier>;
+// Structured Headers Draft 09 List of Lists.
 using ListOfLists = std::vector<std::vector<Item>>;
+// Structured Headers Draft 13 List.
+using List = std::vector<ParameterizedMember>;
 
 // Returns the result of parsing the header value as an Item, if it can be
 // parsed as one, or nullopt if it cannot.
@@ -117,9 +167,16 @@
 // Returns the result of parsing the header value as a List of Lists, if it can
 // be parsed as one, or nullopt if it cannot. Inner list items will be returned
 // as Items.
+// Structured-Headers Draft 09 only.
 BLINK_COMMON_EXPORT base::Optional<ListOfLists> ParseListOfLists(
     const base::StringPiece& str);
 
+// Returns the result of parsing the header value as a general List, if it can
+// be parsed as one, or nullopt if it cannot.
+// Structured-Headers Draft 13 only.
+BLINK_COMMON_EXPORT base::Optional<List> ParseList(
+    const base::StringPiece& str);
+
 }  // namespace http_structured_header
 }  // namespace blink
 
diff --git a/third_party/blink/public/platform/task_type.h b/third_party/blink/public/platform/task_type.h
index 8d00677..a3a275d 100644
--- a/third_party/blink/public/platform/task_type.h
+++ b/third_party/blink/public/platform/task_type.h
@@ -211,10 +211,15 @@
   // Note that the ordering between tasks related to different frames is not
   // always guaranteed - tasks belonging to different frames can be reordered
   // when one of the frames is frozen.
+  // Note: all AssociatedRemotes/AssociatedReceivers should use this task type.
   kInternalNavigationAssociated = 63,
 
-  // Legacy IPCs that are freezable.
-  kInternalFreezableIPC = 64,
+  // Tasks which should run when the frame is frozen, but otherwise should run
+  // in order with other legacy IPC and channel-associated interfaces.
+  // Only tasks related to unfreezing itself should run here, the majority of
+  // the tasks
+  // should use kInternalNavigationAssociated instead.
+  kInternalNavigationAssociatedUnfreezable = 64,
 
   // Task used to split a script loading task for cooperative scheduling
   kInternalContinueScriptLoading = 65,
diff --git a/third_party/blink/public/platform/web_rtc_stats.h b/third_party/blink/public/platform/web_rtc_stats.h
index ec90332e..b332e095 100644
--- a/third_party/blink/public/platform/web_rtc_stats.h
+++ b/third_party/blink/public/platform/web_rtc_stats.h
@@ -18,7 +18,6 @@
 }
 
 namespace webrtc {
-class RTCStats;
 class RTCStatsCollectorCallback;
 class RTCStatsMemberInterface;
 class RTCStatsReport;
@@ -27,47 +26,8 @@
 
 namespace blink {
 
-class WebRTCStats;
 class WebRTCStatsMember;
-
-class BLINK_PLATFORM_EXPORT WebRTCStatsReport {
- public:
-  virtual ~WebRTCStatsReport();
-  // Creates a new report object that is a handle to the same underlying stats
-  // report (the stats are not copied). The new report's iterator is reset,
-  // useful when needing multiple iterators.
-  virtual std::unique_ptr<WebRTCStatsReport> CopyHandle() const = 0;
-
-  // Gets stats object by |id|, or null if no stats with that |id| exists.
-  virtual std::unique_ptr<WebRTCStats> GetStats(WebString id) const = 0;
-  // The next stats object, or null if the end has been reached.
-  virtual std::unique_ptr<WebRTCStats> Next() = 0;
-  // The number of stats objects.
-  virtual size_t Size() const = 0;
-};
-
-BLINK_PLATFORM_EXPORT
-std::unique_ptr<WebRTCStatsReport> CreateRTCStatsReport(
-    const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
-    const WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
-
-class BLINK_PLATFORM_EXPORT WebRTCStats {
- public:
-  virtual ~WebRTCStats();
-
-  virtual WebString Id() const = 0;
-  virtual WebString GetType() const = 0;
-  virtual double Timestamp() const = 0;
-
-  virtual size_t MembersCount() const = 0;
-  virtual std::unique_ptr<WebRTCStatsMember> GetMember(size_t) const = 0;
-};
-
-BLINK_PLATFORM_EXPORT
-std::unique_ptr<WebRTCStats> CreateRTCStats(
-    const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
-    const webrtc::RTCStats* stats,
-    const WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
+class RTCStatsReportPlatform;
 
 class BLINK_PLATFORM_EXPORT WebRTCStatsMember {
  public:
@@ -102,7 +62,7 @@
     const webrtc::RTCStatsMemberInterface* member);
 
 using WebRTCStatsReportCallback =
-    base::OnceCallback<void(std::unique_ptr<WebRTCStatsReport>)>;
+    base::OnceCallback<void(std::unique_ptr<RTCStatsReportPlatform>)>;
 
 BLINK_PLATFORM_EXPORT
 rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback>
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index ebf2ca9..bac8761 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -701,6 +701,12 @@
   virtual bool GetPrintPresetOptionsForPlugin(const WebNode&,
                                               WebPrintPresetOptions*) = 0;
 
+  // Paint Preview ------------------------------------------------------------
+
+  // Captures a full frame paint preview of the WebFrame including subframes.
+  virtual bool CapturePaintPreview(const WebRect& bounds,
+                                   cc::PaintCanvas* canvas) = 0;
+
   // Focus --------------------------------------------------------------
 
   // Advance the focus of the WebView to next text input element from current
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn
index 9e2797f6..0609966 100644
--- a/third_party/blink/renderer/bindings/BUILD.gn
+++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -66,11 +66,16 @@
       invoker.component,
       "--output",
       rebase_path(invoker.output, root_build_dir),
+      "--cached-parser-tables-dir",
+      rebase_path(bindings_scripts_output_dir, root_build_dir),
     ]
 
     if (defined(invoker.deps)) {
       deps = invoker.deps
+    } else {
+      deps = []
     }
+    deps += [ "scripts:cached_lex_yacc_tables" ]
   }
 }
 
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py b/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
index c14b145..e31b171 100644
--- a/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
+++ b/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
@@ -79,10 +79,22 @@
             # Turn off optimization and caching to help debugging
             optimize = False
             outputdir = None
+
+        # Ensure that if we are writing tables, we got a real outputdir.
+        # Because of the way PLY loads the lexer (via import), it can
+        # be loaded from anywhere in sys.path; requiring an outputdir
+        # can help minimize the likelihood of inconsistencies between
+        # scripts.
+        assert debug or outputdir
+
         if outputdir:
             # Need outputdir in path because lex imports the cached lex table
-            # as a Python module
-            sys.path.append(outputdir)
+            # as a Python module. Putting this at the front of sys.path
+            # helps ensures that we get the one in outputdir, and not some
+            # module by the same name that might exist elsewhere in path,
+            # though it won't guarantee it.
+            if sys.path[0] != outputdir:
+                sys.path.insert(0, outputdir)
 
             if rewrite_tables:
                 tablefile_root = os.path.join(outputdir, LEXTAB)
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py b/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
index a0c2054f..23ec694 100644
--- a/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
+++ b/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
@@ -93,6 +93,14 @@
             outputdir = None
             picklefile = None
             write_tables = True
+
+        # Ensure that if we are writing tables, we got a real outputdir.
+        # Because of the way PLY loads the lexer (via import), it can
+        # be loaded from anywhere in sys.path; requiring an outputdir
+        # can help minimize the likelihood of inconsistencies between
+        # scripts.
+        assert debug or not write_tables or outputdir
+
         if outputdir:
             picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle')
             if rewrite_tables:
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py b/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
index 309b463..830637cb 100644
--- a/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
+++ b/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
@@ -16,6 +16,7 @@
     def test_missing_semicolon_between_definitions(self):
         # No semicolon after enum definition.
         text = '''enum TestEnum { "value" } dictionary TestDictionary {};'''
-        parser = BlinkIDLParser()
+        # We use debug=True to not have to worry about generated parser tables.
+        parser = BlinkIDLParser(debug=True)
         parser.ParseText(filename='', data=text)
         self.assertGreater(parser.GetErrors(), 0)
diff --git a/third_party/blink/renderer/bindings/scripts/collect_idl_files.py b/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
index c6922e5..0a72e8a 100644
--- a/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
+++ b/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
@@ -28,6 +28,8 @@
                       help="specify a component name")
     parser.add_option('--output', type='string',
                       help="the output file path")
+    parser.add_option('--cached-parser-tables-dir',
+                      help='location of the generated LEX and YACC files')
     options, args = parser.parse_args()
 
     if options.idl_list_file is None:
@@ -36,6 +38,9 @@
         parser.error("Specify the output file path with --output.")
     if options.component is None:
         parser.error("Specify a component with --component.")
+    if options.cached_parser_tables_dir is None:
+        parser.error("Specify the location of the generated "
+                     "LEX and YACC files with --cached-parser-tables-dir.")
 
     if args:
         parser.error("Unknown arguments {}".format(args))
@@ -47,7 +52,7 @@
     options, _ = parse_options()
 
     filepaths = utilities.read_idl_files_list_from_file(options.idl_list_file)
-    parser = blink_idl_parser.BlinkIDLParser()
+    parser = blink_idl_parser.BlinkIDLParser(outputdir=options.cached_parser_tables_dir)
     ast_group = web_idl.AstGroup(web_idl.Component(options.component))
     for filepath in filepaths:
         ast_group.add_ast_node(blink_idl_parser.parse_file(parser, filepath))
diff --git a/third_party/blink/renderer/bindings/scripts/idl_reader.py b/third_party/blink/renderer/bindings/scripts/idl_reader.py
index 3b0895ed..bbb4ad9 100644
--- a/third_party/blink/renderer/bindings/scripts/idl_reader.py
+++ b/third_party/blink/renderer/bindings/scripts/idl_reader.py
@@ -81,7 +81,7 @@
 
 
 class IdlReader(object):
-    def __init__(self, interfaces_info=None, outputdir=''):
+    def __init__(self, interfaces_info=None, outputdir='', debug=False):
         self.extended_attribute_validator = IDLExtendedAttributeValidator()
         self.interfaces_info = interfaces_info
 
@@ -90,7 +90,7 @@
         else:
             self.interface_dependency_resolver = None
 
-        self.parser = BlinkIDLParser(outputdir=outputdir)
+        self.parser = BlinkIDLParser(outputdir=outputdir, debug=debug)
 
     def read_idl_definitions(self, idl_filename):
         """Returns a dictionary whose key is component and value is an IdlDefinitions object for an IDL file, including all dependencies."""
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
index a253d59..e47045b 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -187,7 +187,7 @@
 }
 
 void MatchedPropertiesCache::RemoveCachedMatchedPropertiesWithDeadEntries(
-    const WeakCallbackInfo& broker) {
+    const WeakCallbackInfo& info) {
   Vector<unsigned> to_remove;
   for (const auto& entry_pair : cache_) {
     // A nullptr value indicates that the entry is currently being created; see
@@ -196,7 +196,7 @@
       continue;
     for (const auto& matched_properties :
          entry_pair.value->matched_properties) {
-      if (!broker.IsHeapObjectAlive(matched_properties)) {
+      if (!info.IsHeapObjectAlive(matched_properties)) {
         to_remove.push_back(entry_pair.key);
         break;
       }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 87752eb..207f2bd 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -783,17 +783,19 @@
                              : ComputedStyle::kNotAtShadowBoundary);
       state.SetStyle(std::move(style));
     } else {
-      // Strictly, we should only allow the root element to inherit from initial
-      // styles, but we allow getComputedStyle() for connected elements outside
-      // the flat tree rooted at an unassigned shadow host child, or Shadow DOM
-      // V0 insertion points.
-      DCHECK(element == GetDocument().documentElement() ||
-             element->IsV0InsertionPoint() ||
-             (IsShadowHost(element->parentNode()) &&
-              !LayoutTreeBuilderTraversal::ParentElement(*element)));
       state.SetStyle(InitialStyleForElement(GetDocument()));
       state.SetParentStyle(ComputedStyle::Clone(*state.Style()));
       state.SetLayoutParentStyle(state.ParentStyle());
+      if (element != GetDocument().documentElement()) {
+        // Strictly, we should only allow the root element to inherit from
+        // initial styles, but we allow getComputedStyle() for connected
+        // elements outside the flat tree rooted at an unassigned shadow host
+        // child, or Shadow DOM V0 insertion points.
+        DCHECK(element->IsV0InsertionPoint() ||
+               (IsShadowHost(element->parentNode()) &&
+                !LayoutTreeBuilderTraversal::ParentElement(*element)));
+        state.Style()->SetIsEnsuredOutsideFlatTree();
+      }
     }
   }
 
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 613335f1..e7d64e18 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -54,6 +54,7 @@
 #include "third_party/blink/renderer/core/css/style_environment_variables.h"
 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
@@ -1797,6 +1798,15 @@
   PropagateWritingModeAndDirectionToHTMLRoot();
 }
 
+void StyleEngine::ClearEnsuredDescendantStyles(Element& element) {
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
+  SelectorFilterRootScope filter_scope(&element);
+  element.ClearNeedsStyleRecalc();
+  element.RecalcDescendantStyles(StyleRecalcChange::kClearEnsured);
+  element.ClearChildNeedsStyleRecalc();
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
+}
+
 void StyleEngine::RebuildLayoutTree() {
   DCHECK(GetDocument().documentElement());
   DCHECK(!InRebuildLayoutTree());
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index 2d5bb11..7148e9400 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -360,6 +360,7 @@
   void UpdateViewportStyle();
   void UpdateStyleAndLayoutTree();
   void RecalcStyle();
+  void ClearEnsuredDescendantStyles(Element& element);
   void RebuildLayoutTree();
   bool InRebuildLayoutTree() const { return in_layout_tree_rebuild_; }
 
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index 14382b61..59a366b2 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2302,4 +2302,71 @@
   EXPECT_FALSE(GetDocument().View()->NeedsLayout());
 }
 
+TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTree) {
+  ScopedFlatTreeStyleRecalcForTest feature_scope(true);
+
+  GetDocument().body()->SetInnerHTMLFromString(
+      R"HTML(<div id="host"><div id="outer"><div id="inner"><div id="innermost"></div></div></div></div>)HTML");
+
+  auto* host = GetDocument().getElementById("host");
+  auto* outer = GetDocument().getElementById("outer");
+  auto* inner = GetDocument().getElementById("inner");
+  auto* innermost = GetDocument().getElementById("innermost");
+
+  host->AttachShadowRootInternal(ShadowRootType::kOpen);
+  UpdateAllLifecyclePhases();
+
+  EXPECT_TRUE(host->GetComputedStyle());
+  // ComputedStyle is not generated outside the flat tree.
+  EXPECT_FALSE(outer->GetComputedStyle());
+  EXPECT_FALSE(inner->GetComputedStyle());
+  EXPECT_FALSE(innermost->GetComputedStyle());
+
+  inner->EnsureComputedStyle();
+  auto* outer_style = outer->GetComputedStyle();
+  auto* inner_style = inner->GetComputedStyle();
+
+  ASSERT_TRUE(outer_style);
+  ASSERT_TRUE(inner_style);
+  EXPECT_FALSE(innermost->GetComputedStyle());
+  EXPECT_TRUE(outer_style->IsEnsuredOutsideFlatTree());
+  EXPECT_TRUE(inner_style->IsEnsuredOutsideFlatTree());
+  EXPECT_EQ(Color::kTransparent, inner_style->VisitedDependentColor(
+                                     GetCSSPropertyBackgroundColor()));
+
+  inner->SetInlineStyleProperty(CSSPropertyID::kBackgroundColor, "green");
+  UpdateAllLifecyclePhases();
+
+  // Old ensured style is not cleared before we re-ensure it.
+  EXPECT_TRUE(inner->NeedsStyleRecalc());
+  EXPECT_EQ(inner_style, inner->GetComputedStyle());
+
+  inner->EnsureComputedStyle();
+
+  // Outer style was not dirty - we still have the same ComputedStyle object.
+  EXPECT_EQ(outer_style, outer->GetComputedStyle());
+  EXPECT_NE(inner_style, inner->GetComputedStyle());
+
+  inner_style = inner->GetComputedStyle();
+  EXPECT_EQ(Color(0, 128, 0), inner_style->VisitedDependentColor(
+                                  GetCSSPropertyBackgroundColor()));
+
+  // Making outer dirty will require that we clear ComputedStyles all the way up
+  // ensuring the style for innermost later because of inheritance.
+  outer->SetInlineStyleProperty(CSSPropertyID::kColor, "green");
+  UpdateAllLifecyclePhases();
+
+  EXPECT_EQ(outer_style, outer->GetComputedStyle());
+  EXPECT_EQ(inner_style, inner->GetComputedStyle());
+  EXPECT_FALSE(innermost->GetComputedStyle());
+
+  auto* innermost_style = innermost->EnsureComputedStyle();
+
+  EXPECT_NE(outer_style, outer->GetComputedStyle());
+  EXPECT_NE(inner_style, inner->GetComputedStyle());
+  ASSERT_TRUE(innermost_style);
+  EXPECT_EQ(Color(0, 128, 0),
+            innermost_style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 99aa1671..ba7f272 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1047,6 +1047,7 @@
       http_refresh_scheduler_(MakeGarbageCollected<HttpRefreshScheduler>(this)),
       well_formed_(false),
       printing_(kNotPrinting),
+      is_painting_preview_(false),
       compatibility_mode_(kNoQuirksMode),
       compatibility_mode_locked_(false),
       last_focus_type_(kWebFocusTypeNone),
@@ -3555,6 +3556,10 @@
   }
 }
 
+void Document::SetIsPaintingPreview(bool is_painting_preview) {
+  is_painting_preview_ = is_painting_preview;
+}
+
 // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#document-open-steps
 void Document::open(Document* entered_document,
                     ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 8261c70a..26b5c756 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -774,6 +774,12 @@
   }
   void SetPrinting(PrintingState);
 
+  bool IsPaintingPreview() const { return is_painting_preview_; }
+  bool IsCapturingLayout() const {
+    return printing_ == kPrinting || is_painting_preview_;
+  }
+  void SetIsPaintingPreview(bool);
+
   enum CompatibilityMode { kQuirksMode, kLimitedQuirksMode, kNoQuirksMode };
 
   void SetCompatibilityMode(CompatibilityMode);
@@ -1840,6 +1846,7 @@
   Member<CSSStyleSheet> elem_sheet_;
 
   PrintingState printing_;
+  bool is_painting_preview_;
 
   CompatibilityMode compatibility_mode_;
   // This is cheaper than making setCompatibilityMode virtual.
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 0483a982..e4952ef 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3054,6 +3054,13 @@
     } else if (ShadowRoot* root = GetShadowRoot()) {
       if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) {
         root->RecalcDescendantStyles(child_change);
+        // Sad panda. This is only to clear ensured ComputedStyles for elements
+        // outside the flat tree for getComputedStyle() in the cases where we
+        // kSubtreeStyleChange. Style invalidation and kLocalStyleChange will
+        // make sure we clear out-of-date ComputedStyles outside the flat tree
+        // in Element::EnsureComputedStyle().
+        if (child_change.RecalcDescendants())
+          RecalcDescendantStyles(StyleRecalcChange::kClearEnsured);
       } else {
         if (child_change.TraverseChild(*root))
           root->RecalcStyle(child_change);
@@ -4943,21 +4950,44 @@
   // layoutObject because it did the layout, will be correct and so that the
   // values returned for the ":selection" pseudo-element will be correct.
   const ComputedStyle* element_style = GetComputedStyle();
-  if (!element_style) {
+  if (!element_style || element_style->IsEnsuredOutsideFlatTree()) {
     if (CanParticipateInFlatTree()) {
-      if (ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this))
+      if (ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this)) {
         parent->EnsureComputedStyle();
+        if (element_style)
+          element_style = GetComputedStyle();
+      }
+      if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) {
+        if (element_style && NeedsStyleRecalc()) {
+          // RecalcStyle() will not traverse into connected elements outside the
+          // flat tree and we may have a dirty element or ancestors if this
+          // element is not in the flat tree. If we don't need a style recalc,
+          // we can just re-use the ComputedStyle from the last
+          // getComputedStyle(). Otherwise, we need to clear the ensured styles
+          // for the uppermost dirty ancestor and all of its descendants. If
+          // this element was not the uppermost dirty element, we would not end
+          // up here because a dirty ancestor would have cleared the
+          // ComputedStyle in the recursive call above and element_style would
+          // have been null.
+          GetDocument().GetStyleEngine().ClearEnsuredDescendantStyles(*this);
+          element_style = nullptr;
+        }
+      }
+    } else {
+      element_style = nullptr;
     }
-    scoped_refptr<ComputedStyle> new_style = nullptr;
-    // TODO(crbug.com/953707): Avoid setting inline style during
-    // HTMLImageElement::CustomStyleForLayoutObject.
-    if (HasCustomStyleCallbacks() && !IsHTMLImageElement(*this))
-      new_style = CustomStyleForLayoutObject();
-    else
-      new_style = OriginalStyleForLayoutObject();
-    element_style = new_style.get();
-    new_style->SetIsEnsuredInDisplayNone();
-    SetComputedStyle(std::move(new_style));
+    if (!element_style) {
+      scoped_refptr<ComputedStyle> new_style = nullptr;
+      // TODO(crbug.com/953707): Avoid setting inline style during
+      // HTMLImageElement::CustomStyleForLayoutObject.
+      if (HasCustomStyleCallbacks() && !IsHTMLImageElement(*this))
+        new_style = CustomStyleForLayoutObject();
+      else
+        new_style = OriginalStyleForLayoutObject();
+      element_style = new_style.get();
+      new_style->SetIsEnsuredInDisplayNone();
+      SetComputedStyle(std::move(new_style));
+    }
   }
 
   if (!pseudo_element_specifier)
diff --git a/third_party/blink/renderer/core/dom/live_node_list_registry.cc b/third_party/blink/renderer/core/dom/live_node_list_registry.cc
index a0599e9..6366cf65 100644
--- a/third_party/blink/renderer/core/dom/live_node_list_registry.cc
+++ b/third_party/blink/renderer/core/dom/live_node_list_registry.cc
@@ -42,10 +42,9 @@
   mask_ = mask;
 }
 
-void LiveNodeListRegistry::ProcessCustomWeakness(
-    const WeakCallbackInfo& broker) {
-  auto* it = std::remove_if(data_.begin(), data_.end(), [broker](Entry entry) {
-    return !broker.IsHeapObjectAlive(entry.first);
+void LiveNodeListRegistry::ProcessCustomWeakness(const WeakCallbackInfo& info) {
+  auto* it = std::remove_if(data_.begin(), data_.end(), [info](Entry entry) {
+    return !info.IsHeapObjectAlive(entry.first);
   });
   if (it == data_.end())
     return;
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index 6e1d0cb..c4eec73 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1303,7 +1303,25 @@
   // early return here is a performance optimization.
   if (parent_dirty)
     return;
-
+  // If we are outside the flat tree and FlatTreeStyleRecalc is enabled, we
+  // should not update the recalc root because we should not traverse those
+  // nodes from StyleEngine::RecalcStyle().
+  if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) {
+    if (const ComputedStyle* current_style = GetComputedStyle()) {
+      if (current_style->IsEnsuredOutsideFlatTree())
+        return;
+    } else {
+      ContainerNode* style_parent = ancestor;
+      while (style_parent && !style_parent->CanParticipateInFlatTree())
+        style_parent = style_parent->GetStyleRecalcParent();
+      if (style_parent) {
+        if (const auto* parent_style = style_parent->GetComputedStyle()) {
+          if (parent_style->IsEnsuredOutsideFlatTree())
+            return;
+        }
+      }
+    }
+  }
   // If we're in a locked subtree, then we should not update the style recalc
   // roots. These would be updated when we commit the lock. If we have locked
   // display locks somewhere in the document, we iterate up the ancestor chain
diff --git a/third_party/blink/renderer/core/dom/node_test.cc b/third_party/blink/renderer/core/dom/node_test.cc
index a249ae1d..2e5694c 100644
--- a/third_party/blink/renderer/core/dom/node_test.cc
+++ b/third_party/blink/renderer/core/dom/node_test.cc
@@ -503,4 +503,28 @@
   EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsStyleRecalc());
 }
 
+TEST_F(NodeTest, UpdateChildDirtyAfterSlottingDirtyNode) {
+  ScopedFlatTreeStyleRecalcForTest scope(true);
+
+  SetBodyContent("<div id=host><span></span></div>");
+
+  auto* host = GetDocument().getElementById("host");
+  auto* span = To<Element>(host->firstChild());
+
+  // Make sure the span is style dirty.
+  span->setAttribute("style", "color:green");
+
+  ShadowRoot& shadow_root =
+      host->AttachShadowRootInternal(ShadowRootType::kOpen);
+  shadow_root.SetInnerHTMLFromString("<div><slot></slot></div>");
+
+  GetDocument().GetSlotAssignmentEngine().RecalcSlotAssignments();
+
+  // Make sure shadow tree div and slot are marked with ChildNeedsStyleRecalc
+  // when the dirty span is slotted in.
+  EXPECT_TRUE(shadow_root.firstChild()->ChildNeedsStyleRecalc());
+  EXPECT_TRUE(shadow_root.firstChild()->firstChild()->ChildNeedsStyleRecalc());
+  EXPECT_TRUE(span->NeedsStyleRecalc());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.cc b/third_party/blink/renderer/core/frame/event_handler_registry.cc
index c15fda7..435d28a 100644
--- a/third_party/blink/renderer/core/frame/event_handler_registry.cc
+++ b/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -340,8 +340,7 @@
       EventHandlerRegistry, &EventHandlerRegistry::ProcessCustomWeakness>(this);
 }
 
-void EventHandlerRegistry::ProcessCustomWeakness(
-    const WeakCallbackInfo& broker) {
+void EventHandlerRegistry::ProcessCustomWeakness(const WeakCallbackInfo& info) {
   Vector<UntracedMember<EventTarget>> dead_targets;
   for (int i = 0; i < kEventHandlerClassCount; ++i) {
     EventHandlerClass handler_class = static_cast<EventHandlerClass>(i);
@@ -349,9 +348,9 @@
     for (const auto& event_target : *targets) {
       Node* node = event_target.key->ToNode();
       LocalDOMWindow* window = event_target.key->ToLocalDOMWindow();
-      if (node && !broker.IsHeapObjectAlive(node)) {
+      if (node && !info.IsHeapObjectAlive(node)) {
         dead_targets.push_back(node);
-      } else if (window && !broker.IsHeapObjectAlive(window)) {
+      } else if (window && !info.IsHeapObjectAlive(window)) {
         dead_targets.push_back(window);
       }
     }
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 24ea8a0..3640a0c 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1287,6 +1287,18 @@
     frame_view->ScheduleAnimation();
 }
 
+bool LocalFrame::ClipsContent() const {
+  // A paint preview shouldn't clip to the viewport if it is the main frame or a
+  // root remote frame.
+  if (GetDocument()->IsPaintingPreview() && IsLocalRoot())
+    return false;
+
+  if (IsMainFrame())
+    return GetSettings()->GetMainFrameClipsContent();
+  // By default clip to viewport.
+  return true;
+}
+
 void LocalFrame::SetViewportIntersectionFromParent(
     const ViewportIntersectionState& intersection_state) {
   // We only schedule an update if the viewport intersection or occlusion state
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index a5e3023a..75cb56b5 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -411,6 +411,9 @@
   void WasHidden();
   void WasShown();
 
+  // Whether the frame clips its content to the frame's size.
+  bool ClipsContent() const;
+
   // For a navigation initiated from this LocalFrame with user gesture, record
   // the UseCounter AdClickNavigation if this frame is an adframe.
   //
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index a716d44..d7005d1 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2342,7 +2342,7 @@
   DCHECK_EQ(target_state, DocumentLifecycle::kPaintClean);
   RunPaintLifecyclePhase();
   DCHECK(ShouldThrottleRendering() ||
-         (frame_->GetDocument()->Printing() &&
+         (frame_->GetDocument()->IsCapturingLayout() &&
           !RuntimeEnabledFeatures::PrintBrowserEnabled()) ||
          Lifecycle().GetState() == DocumentLifecycle::kPaintClean);
 }
@@ -2495,16 +2495,16 @@
 
 void LocalFrameView::RunPaintLifecyclePhase() {
   TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPaintLifecyclePhase");
-  // While printing a document, the paint walk is done by the printing component
-  // into a special canvas. There is no point doing a normal paint step (or
-  // animations update) when in this mode.
+  // While printing or capturing a paint preview of a document, the paint walk
+  // is done into a special canvas. There is no point doing a normal paint step
+  // (or animations update) when in this mode.
   //
   // RuntimeEnabledFeatures::PrintBrowserEnabled is a mode which runs the
   // browser normally, but renders every page as if it were being printed.
   // See crbug.com/667547
-  bool print_mode_enabled = frame_->GetDocument()->Printing() &&
-                            !RuntimeEnabledFeatures::PrintBrowserEnabled();
-  if (!print_mode_enabled)
+  bool is_capturing_layout = frame_->GetDocument()->IsCapturingLayout() &&
+                             !RuntimeEnabledFeatures::PrintBrowserEnabled();
+  if (!is_capturing_layout)
     PaintTree();
 
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -2513,7 +2513,7 @@
     }
   }
 
-  if (!print_mode_enabled) {
+  if (!is_capturing_layout) {
     bool needed_update = !paint_artifact_compositor_ ||
                          paint_artifact_compositor_->NeedsUpdate();
     PushPaintArtifactToCompositor();
@@ -3541,9 +3541,11 @@
   // with CompositeAfterPaint.
   DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
 
-  // Paint the whole rect if "MainFrameClipsContent" is false, meaning that
-  // WebPreferences::record_whole_document is true.
-  if (!frame_->GetSettings()->GetMainFrameClipsContent())
+  // Paint the whole rect if ClipsContent is false, meaning that the whole
+  // document should be recorded. This occurs if:
+  // - A paint preview is being captured.
+  // - WebPreferences::record_whole_document is true.
+  if (!frame_->ClipsContent())
     return;
 
   // By default we consider the bounds of the FrameView to be what is considered
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 4c685ca..cd078c7 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -514,6 +514,60 @@
   WebPrintParams print_params_;
 };
 
+class PaintPreviewContext : public PrintContext {
+ public:
+  PaintPreviewContext(LocalFrame* frame) : PrintContext(frame, false) {}
+  ~PaintPreviewContext() override = default;
+
+  bool Capture(cc::PaintCanvas* canvas, FloatSize size) {
+    // This code is based on ChromePrintContext::SpoolSinglePage()/SpoolPage().
+    // It differs in that it:
+    //   1. Uses a different set of flags for painting and the graphics context.
+    //   2. Paints a single page of |size| rather than a specific page in a
+    //      reformatted document.
+    //   3. Does no scaling.
+    if (!GetFrame()->GetDocument() ||
+        !GetFrame()->GetDocument()->GetLayoutView())
+      return false;
+    GetFrame()->View()->UpdateLifecyclePhasesForPrinting();
+    if (!GetFrame()->GetDocument() ||
+        !GetFrame()->GetDocument()->GetLayoutView())
+      return false;
+    FloatRect bounds(0, 0, size.Width(), size.Height());
+    PaintRecordBuilder builder(nullptr, nullptr, nullptr,
+                               canvas->GetPaintPreviewTracker());
+    builder.Context().SetIsPaintingPreview(true);
+
+    LocalFrameView* frame_view = GetFrame()->View();
+    DCHECK(frame_view);
+    PropertyTreeState property_tree_state =
+        frame_view->GetLayoutView()->FirstFragment().LocalBorderBoxProperties();
+
+    // This calls BeginRecording on |builder| with dimensions specified by the
+    // CullRect.
+    frame_view->PaintContentsOutsideOfLifecycle(
+        builder.Context(),
+        kGlobalPaintNormalPhase | kGlobalPaintFlattenCompositingLayers |
+            kGlobalPaintAddUrlMetadata,
+        CullRect(RoundedIntRect(bounds)));
+    {
+      // Add anchors.
+      ScopedPaintChunkProperties scoped_paint_chunk_properties(
+          builder.Context().GetPaintController(), property_tree_state, builder,
+          DisplayItem::kPrintedContentDestinationLocations);
+      DrawingRecorder line_boundary_recorder(
+          builder.Context(), builder,
+          DisplayItem::kPrintedContentDestinationLocations);
+      OutputLinkedDestinations(builder.Context(), RoundedIntRect(bounds));
+    }
+    canvas->drawPicture(builder.EndRecording(property_tree_state));
+    return true;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PaintPreviewContext);
+};
+
 static WebDocumentLoader* DocumentLoaderForDocLoader(DocumentLoader* loader) {
   return loader ? WebDocumentLoaderImpl::FromDocumentLoader(loader) : nullptr;
 }
@@ -1548,6 +1602,21 @@
   return plugin_container->GetPrintPresetOptionsFromDocument(preset_options);
 }
 
+bool WebLocalFrameImpl::CapturePaintPreview(const WebRect& bounds,
+                                            cc::PaintCanvas* canvas) {
+  FloatSize float_bounds(bounds.width, bounds.height);
+  GetFrame()->GetDocument()->SetIsPaintingPreview(true);
+  ResourceCacheValidationSuppressor validation_suppressor(
+      GetFrame()->GetDocument()->Fetcher());
+  GetFrame()->View()->ForceLayoutForPagination(float_bounds, float_bounds, 1);
+  PaintPreviewContext* paint_preview_context =
+      MakeGarbageCollected<PaintPreviewContext>(GetFrame());
+  bool success = paint_preview_context->Capture(canvas, float_bounds);
+  GetFrame()->GetDocument()->SetIsPaintingPreview(false);
+  GetFrame()->EndPrinting();
+  return success;
+}
+
 bool WebLocalFrameImpl::HasCustomPageSizeStyle(int page_index) {
   return GetFrame()->GetDocument()->StyleForPage(page_index)->PageSizeType() !=
          EPageSizeType::kAuto;
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index ef0067c..e862362 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -297,6 +297,8 @@
   void DispatchAfterPrintEvent() override;
   bool GetPrintPresetOptionsForPlugin(const WebNode&,
                                       WebPrintPresetOptions*) override;
+  bool CapturePaintPreview(const WebRect& bounds,
+                           cc::PaintCanvas* canvas) override;
   void AdvanceFocusInForm(WebFocusType) override;
   bool ShouldSuppressKeyboardForFocusedElement() override;
   WebPerformance Performance() const override;
diff --git a/third_party/blink/renderer/core/inspector/network_resources_data.cc b/third_party/blink/renderer/core/inspector/network_resources_data.cc
index 0530b05..1253713 100644
--- a/third_party/blink/renderer/core/inspector/network_resources_data.cc
+++ b/third_party/blink/renderer/core/inspector/network_resources_data.cc
@@ -143,8 +143,8 @@
 }
 
 void NetworkResourcesData::ResourceData::ProcessCustomWeakness(
-    const WeakCallbackInfo& broker) {
-  if (!cached_resource_ || broker.IsHeapObjectAlive(cached_resource_))
+    const WeakCallbackInfo& info) {
+  if (!cached_resource_ || info.IsHeapObjectAlive(cached_resource_))
     return;
 
   // Mark loaded resources or resources without the buffer as loaded.
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
index b3342cd5..99d7eda9 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -282,9 +282,8 @@
   }
 }
 
-void IntersectionObserver::ProcessCustomWeakness(
-    const WeakCallbackInfo& broker) {
-  if (RootIsImplicit() || (root() && broker.IsHeapObjectAlive(root())))
+void IntersectionObserver::ProcessCustomWeakness(const WeakCallbackInfo& info) {
+  if (RootIsImplicit() || (root() && info.IsHeapObjectAlive(root())))
     return;
   DummyExceptionStateForTesting exception_state;
   disconnect(exception_state);
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index 82387ff4..9a16efd 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -647,8 +647,9 @@
       RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
   }
 
-  if (document.Printing()) {
-    // When printing, frame-level scrollbars are never displayed.
+  if (document.IsCapturingLayout()) {
+    // When capturing layout (e.g. printing), frame-level scrollbars are never
+    // displayed.
     // TODO(szager): Figure out the right behavior when printing an overflowing
     // iframe.  https://bugs.chromium.org/p/chromium/issues/detail?id=777528
     RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index 1be5b7d8..c543aab 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -376,8 +376,8 @@
   // fragmentation context.
   if (is_constrained_by_outer_fragmentation_context_ &&
       column_size.block_size != kIndefiniteSize) {
-    if (const auto* token = BreakToken())
-      column_size.block_size -= token->ConsumedBlockSize();
+    column_size.block_size -= ConsumedBlockSizeInContentBox(
+        border_scrollbar_padding_.block_start, BreakToken());
 
     // Subtract the space already taken in the current fragment (spanners and
     // earlier column rows).
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
index 0070061..e9c066b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -3888,6 +3888,42 @@
   EXPECT_EQ(expectation, dump);
 }
 
+TEST_F(NGColumnLayoutAlgorithmTest, NestedLimitedHeightWithPadding) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      .outer { columns:3; width:320px; height:100px; }
+      .inner { columns:2; height:100px; padding-top:50px; }
+      .outer, .inner { column-gap:10px; column-fill:auto; }
+    </style>
+    <div id="container">
+      <div class="outer">
+        <div class="inner">
+          <div style="width:22px; height:200px;"></div>
+        </div>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x100
+    offset:0,0 size:320x100
+      offset:0,0 size:100x100
+        offset:0,0 size:100x100
+          offset:0,50 size:45x50
+            offset:0,0 size:22x50
+          offset:55,50 size:45x50
+            offset:0,0 size:22x50
+      offset:110,0 size:100x50
+        offset:0,0 size:100x50
+          offset:0,0 size:45x50
+            offset:0,0 size:22x50
+          offset:55,0 size:45x50
+            offset:0,0 size:22x50
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
 TEST_F(NGColumnLayoutAlgorithmTest, NestedUnbalancedInnerAutoHeight) {
   // The fragments generated by an inner multicol are block-size constrained by
   // the outer multicol, so if column-fill is auto, we shouldn't forcefully
@@ -4696,7 +4732,7 @@
         offset:0,0 size:100x50
           offset:1,0 size:98x20
             offset:0,0 size:4x20
-          offset:1,20 size:44x28
+          offset:1,20 size:44x29
             offset:0,0 size:7x20
           offset:55,20 size:44x20
             offset:0,0 size:8x20
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index 330e366..61c2719 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -8,6 +8,7 @@
 #include "base/optional.h"
 #include "third_party/blink/renderer/core/layout/layout_box.h"
 #include "third_party/blink/renderer/core/layout/layout_table_cell.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
@@ -1271,4 +1272,18 @@
   return base::nullopt;
 }
 
+LayoutUnit ConsumedBlockSizeInContentBox(
+    LayoutUnit border_scrollbar_padding_block_start,
+    const NGBlockBreakToken* break_token) {
+  if (!break_token)
+    return LayoutUnit();
+  LayoutUnit consumed_block_size =
+      break_token->ConsumedBlockSize() - border_scrollbar_padding_block_start;
+  // There are no valid break points inside borders and padding, but if the
+  // fragmentainer is actually shorter than the space taken up bby borders
+  // and/or padding, we may end up slicing them into multiple fragmentainers
+  // anyway - in which case the size we just calculated becomes negative.
+  return consumed_block_size.ClampNegativeToZero();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
index 4d69861..dc99463 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -24,6 +24,7 @@
 class Length;
 struct MinMaxSizeInput;
 class NGConstraintSpace;
+class NGBlockBreakToken;
 class NGBlockNode;
 class NGLayoutInputNode;
 
@@ -482,6 +483,12 @@
     const NGBoxStrut& border_scrollbar_padding,
     NGMinMaxSizeType);
 
+// Return the sum of the block-size of the content-boxes in all preceding
+// fragments.
+LayoutUnit ConsumedBlockSizeInContentBox(
+    LayoutUnit border_scrollbar_padding_block_start,
+    const NGBlockBreakToken*);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LENGTH_UTILS_H_
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc
index f8ce906d..3ca2029 100644
--- a/third_party/blink/renderer/core/paint/frame_painter.cc
+++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -76,7 +76,7 @@
   PaintLayerFlags root_layer_paint_flags = 0;
   // This will prevent clipping the root PaintLayer to its visible content
   // rect when root layer scrolling is enabled.
-  if (document->Printing())
+  if (document->IsCapturingLayout())
     root_layer_paint_flags = kPaintLayerPaintingOverflowContents;
 
   PaintLayer* root_layer = layout_view->Layer();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index 16c67f1..9c3a8b9 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -112,8 +112,8 @@
                                     const GraphicsContext& context,
                                     const PaintLayerPaintingInfo& painting_info,
                                     PaintLayerFlags paint_flags) {
-  // Caching is not needed during printing.
-  if (context.Printing())
+  // Caching is not needed during printing or painting previews.
+  if (context.Printing() || context.IsPaintingPreview())
     return false;
 
   if (context.GetPaintController().IsSkippingCache())
@@ -198,8 +198,7 @@
   // of the main frame.
   if (layer.GetLayoutObject().IsLayoutView()) {
     const auto* frame = layer.GetLayoutObject().GetFrame();
-    if (frame && frame->IsMainFrame() &&
-        !frame->GetSettings()->GetMainFrameClipsContent())
+    if (frame && frame->IsMainFrame() && !frame->ClipsContent())
       return true;
   }
   return false;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 3e59e20..cc6a0ea 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1541,8 +1541,7 @@
 static bool CanOmitOverflowClip(const LayoutObject& object) {
   DCHECK(NeedsOverflowClip(object));
 
-  if (object.IsLayoutView() && object.GetFrame()->IsMainFrame() &&
-      !object.GetFrame()->GetSettings()->GetMainFrameClipsContent()) {
+  if (object.IsLayoutView() && !object.GetFrame()->ClipsContent()) {
     return true;
   }
 
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc
index 5d6bed5f..b643cc2 100644
--- a/third_party/blink/renderer/core/paint/view_painter.cc
+++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -48,9 +48,12 @@
   // The background rect always includes at least the visible content size.
   PhysicalRect background_rect(layout_view_.BackgroundRect());
 
-  // When printing, paint the entire unclipped scrolling content area.
-  if (paint_info.IsPrinting())
+  // When printing or painting a preview, paint the entire unclipped scrolling
+  // content area.
+  if (paint_info.IsPrinting() ||
+      !layout_view_.GetFrameView()->GetFrame().ClipsContent()) {
     background_rect.Unite(layout_view_.DocumentRect());
+  }
 
   const DisplayItemClient* background_client = &layout_view_;
 
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
index 35cb079a..cbd7d151 100644
--- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
+++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -1029,5 +1029,12 @@
       include_paths: ["third_party/blink/renderer/platform/wtf/text/atomic_string.h"],
       default_value: "g_null_atom",
     },
+    {
+      name: "IsEnsuredOutsideFlatTree",
+      field_template: "monotonic_flag",
+      default_value: "false",
+      custom_compare: true,
+      inherited: true,
+    },
   ],
 }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index a22d9e8d..d0aa251 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1196,18 +1196,11 @@
 }
 
 void SVGSMILElement::ScheduleEvent(const AtomicString& event_type) {
-  GetDocument()
-      .GetTaskRunner(TaskType::kDOMManipulation)
-      ->PostTask(FROM_HERE, WTF::Bind(&SVGSMILElement::DispatchPendingEvent,
-                                      WrapPersistent(this), event_type));
-}
-
-void SVGSMILElement::DispatchPendingEvent(const AtomicString& event_type) {
   DCHECK(event_type == event_type_names::kEndEvent ||
          event_type == event_type_names::kBeginEvent ||
          event_type == event_type_names::kRepeatEvent ||
          event_type == "repeatn");
-  DispatchEvent(*Event::Create(event_type));
+  EnqueueEvent(*Event::Create(event_type), TaskType::kDOMManipulation);
 }
 
 bool SVGSMILElement::HasValidTarget() const {
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
index 08b8e6d..e9c61565 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -124,7 +124,6 @@
 
   void ScheduleEvent(const AtomicString& event_type);
   void ScheduleRepeatEvents();
-  void DispatchPendingEvent(const AtomicString& event_type);
 
   virtual bool IsSVGDiscardElement() const { return false; }
 
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
index c96d616..aa90abb 100644
--- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
+++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
@@ -33,11 +33,11 @@
 }
 
 void SVGTreeScopeResources::ProcessCustomWeakness(
-    const WeakCallbackInfo& broker) {
+    const WeakCallbackInfo& info) {
   // Unregister and remove any resources that are no longer alive.
   Vector<AtomicString> to_remove;
   for (auto& resource_entry : resources_) {
-    if (broker.IsHeapObjectAlive(resource_entry.value))
+    if (info.IsHeapObjectAlive(resource_entry.value))
       continue;
     resource_entry.value->Unregister();
     to_remove.push_back(resource_entry.key);
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
index 6c69b3d..af65667 100644
--- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
+++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
@@ -72,7 +72,10 @@
   inline const void* DataShared() const;
   inline void* DataMaybeShared();
   inline const void* DataMaybeShared() const;
-  inline unsigned ByteLength() const;
+  inline size_t ByteLengthAsSizeT() const;
+  // This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
+  // instead.
+  inline unsigned ByteLengthAsUnsigned() const;
 
   // Creates a new ArrayBuffer object with copy of bytes in this object
   // ranging from |begin| up to but not including |end|.
@@ -124,7 +127,7 @@
   // TODO(binji): support creating a SharedArrayBuffer by copying another
   // ArrayBuffer?
   DCHECK(!other->IsShared());
-  return ArrayBuffer::Create(other->Data(), other->ByteLength());
+  return ArrayBuffer::Create(other->Data(), other->ByteLengthAsSizeT());
 }
 
 scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source,
@@ -238,7 +241,15 @@
   return contents_.DataMaybeShared();
 }
 
-unsigned ArrayBuffer::ByteLength() const {
+size_t ArrayBuffer::ByteLengthAsSizeT() const {
+  return contents_.DataLength();
+}
+
+// This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
+// instead.
+unsigned ArrayBuffer::ByteLengthAsUnsigned() const {
+  CHECK_LE(contents_.DataLength(),
+           static_cast<size_t>(std::numeric_limits<unsigned>::max()));
   // TODO(dtapuska): Revisit this cast. ArrayBufferContents
   // uses size_t for storing data. Whereas ArrayBuffer IDL is
   // only uint32_t based.
@@ -254,7 +265,7 @@
 }
 
 unsigned ArrayBuffer::ClampIndex(unsigned index) const {
-  return index < ByteLength() ? index : ByteLength();
+  return index < ByteLengthAsUnsigned() ? index : ByteLengthAsUnsigned();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
index 49af984..5b7b548 100644
--- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
+++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
@@ -90,10 +90,10 @@
       return false;
     if (sizeof(T) > 1 && byte_offset % sizeof(T))
       return false;
-    if (byte_offset > buffer->ByteLength())
+    if (byte_offset > buffer->ByteLengthAsUnsigned())
       return false;
-    unsigned remaining_elements =
-        static_cast<unsigned>((buffer->ByteLength() - byte_offset) / sizeof(T));
+    unsigned remaining_elements = static_cast<unsigned>(
+        (buffer->ByteLengthAsUnsigned() - byte_offset) / sizeof(T));
     if (num_elements > remaining_elements)
       return false;
     return true;
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
index 0874012..7935d89 100644
--- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
+++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
@@ -47,7 +47,8 @@
 
 void ArrayPiece::InitWithArrayBuffer(ArrayBuffer* buffer) {
   if (buffer) {
-    InitWithData(buffer->Data(), SafeCast<unsigned>(buffer->ByteLength()));
+    InitWithData(buffer->Data(),
+                 SafeCast<unsigned>(buffer->ByteLengthAsUnsigned()));
     is_detached_ = buffer->IsDetached();
   } else {
     InitNull();
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
index f4da2348..bf7452e 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
@@ -41,8 +41,8 @@
                               ArrayBufferContents& result) {
   DOMArrayBuffer* to_transfer = this;
   if (!IsDetachable(isolate)) {
-    to_transfer =
-        DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLength());
+    to_transfer = DOMArrayBuffer::Create(Buffer()->Data(),
+                                         Buffer()->ByteLengthAsUnsigned());
   }
 
   if (!to_transfer->Buffer()->Transfer(result))
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
index fc2f200..fa42233d 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
@@ -21,7 +21,7 @@
 
   const void* Data() const { return Buffer()->Data(); }
   void* Data() { return Buffer()->Data(); }
-  unsigned ByteLength() const { return Buffer()->ByteLength(); }
+  unsigned ByteLength() const { return Buffer()->ByteLengthAsUnsigned(); }
   bool IsDetached() const { return Buffer()->IsDetached(); }
   bool IsShared() const { return Buffer()->IsShared(); }
 
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
index 026c80d..844ca28 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
+++ b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
@@ -20,7 +20,7 @@
                                         unsigned byte_length) {
     base::CheckedNumeric<uint32_t> checked_max = byte_offset;
     checked_max += byte_length;
-    CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLength());
+    CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsUnsigned());
     return base::AdoptRef(new DataView(buffer, byte_offset, byte_length));
   }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index d3e3af9..9b17ea3c 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1120,7 +1120,19 @@
 }
 
 bool AXNodeObject::IsImage() const {
-  return RoleValue() == ax::mojom::Role::kImage;
+  // Canvas is not currently included so that it is not exposed unless there is
+  // a label, fallback content or something to make it accessible. This decision
+  // may be revisited at a later date.
+  switch (RoleValue()) {
+    case ax::mojom::Role::kDocCover:
+    case ax::mojom::Role::kGraphicsSymbol:
+    case ax::mojom::Role::kImage:
+    case ax::mojom::Role::kImageMap:
+    case ax::mojom::Role::kSvgRoot:
+      return true;
+    default:
+      return false;
+  }
 }
 
 bool AXNodeObject::IsImageButton() const {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 579e707..b70044bc 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -116,6 +116,7 @@
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
index b06e03ce..12e78284 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -50,6 +50,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h"
 #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/rtp_receiver_interface.h"
@@ -214,9 +215,9 @@
                     const blink::WebMediaStreamTrack& track));
 };
 
-void OnStatsDelivered(std::unique_ptr<blink::WebRTCStatsReport>* result,
+void OnStatsDelivered(std::unique_ptr<RTCStatsReportPlatform>* result,
                       scoped_refptr<base::SingleThreadTaskRunner> main_thread,
-                      std::unique_ptr<blink::WebRTCStatsReport> report) {
+                      std::unique_ptr<RTCStatsReportPlatform> report) {
   EXPECT_TRUE(main_thread->BelongsToCurrentThread());
   EXPECT_TRUE(report);
   result->reset(report.release());
@@ -917,7 +918,7 @@
       std::unique_ptr<const webrtc::RTCStats>(stats_defined_members.release()));
 
   pc_handler_->native_peer_connection()->SetGetStatsReport(report);
-  std::unique_ptr<blink::WebRTCStatsReport> result;
+  std::unique_ptr<RTCStatsReportPlatform> result;
   pc_handler_->GetStats(
       base::BindOnce(OnStatsDelivered, &result,
                      blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
@@ -927,7 +928,7 @@
 
   int undefined_stats_count = 0;
   int defined_stats_count = 0;
-  for (std::unique_ptr<blink::WebRTCStats> stats = result->Next(); stats;
+  for (std::unique_ptr<RTCStats> stats = result->Next(); stats;
        stats.reset(result->Next().release())) {
     EXPECT_EQ(stats->GetType().Utf8(), webrtc::RTCTestStats::kType);
     if (stats->Id().Utf8() == "RTCUndefinedStats") {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index cd4b886c..ab04c13 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
 #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/webrtc/api/rtp_parameters.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
index 3620b11..7327a4d5 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
 #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h"
 #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
 #include "third_party/webrtc/api/stats/rtcstats_objects.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index a69b1b5..5789874 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
index 3955125f..f737a21 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
@@ -453,8 +453,9 @@
 
 void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
                                     blink::RTCVoidRequest* request) {
-  internal_->ReplaceTrack(std::move(with_track),
-                          base::BindOnce(&OnReplaceTrackCompleted, request));
+  internal_->ReplaceTrack(
+      std::move(with_track),
+      WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request)));
 }
 
 std::unique_ptr<blink::RtcDtmfSenderHandler> RTCRtpSenderImpl::GetDtmfSender()
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
index affc05fd..292a515 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h"
 #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
 #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
index 995b652..e985bcd 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -7,16 +7,16 @@
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-
 #include "third_party/webrtc/api/stats/rtc_stats.h"
 
 namespace blink {
 
 namespace {
 
-v8::Local<v8::Value> WebRTCStatsToValue(ScriptState* script_state,
-                                        const WebRTCStats* stats) {
+v8::Local<v8::Value> RTCStatsToValue(ScriptState* script_state,
+                                     const RTCStats* stats) {
   V8ObjectBuilder builder(script_state);
 
   builder.AddString("id", stats->Id());
@@ -98,23 +98,23 @@
 class RTCStatsReportIterationSource final
     : public PairIterable<String, v8::Local<v8::Value>>::IterationSource {
  public:
-  RTCStatsReportIterationSource(std::unique_ptr<WebRTCStatsReport> report)
+  RTCStatsReportIterationSource(std::unique_ptr<RTCStatsReportPlatform> report)
       : report_(std::move(report)) {}
 
   bool Next(ScriptState* script_state,
             String& key,
             v8::Local<v8::Value>& value,
             ExceptionState& exception_state) override {
-    std::unique_ptr<WebRTCStats> stats = report_->Next();
+    std::unique_ptr<RTCStats> stats = report_->Next();
     if (!stats)
       return false;
     key = stats->Id();
-    value = WebRTCStatsToValue(script_state, stats.get());
+    value = RTCStatsToValue(script_state, stats.get());
     return true;
   }
 
  private:
-  std::unique_ptr<WebRTCStatsReport> report_;
+  std::unique_ptr<RTCStatsReportPlatform> report_;
 };
 
 }  // namespace
@@ -136,7 +136,7 @@
   return enabled_origin_trials;
 }
 
-RTCStatsReport::RTCStatsReport(std::unique_ptr<WebRTCStatsReport> report)
+RTCStatsReport::RTCStatsReport(std::unique_ptr<RTCStatsReportPlatform> report)
     : report_(std::move(report)) {}
 
 uint32_t RTCStatsReport::size() const {
@@ -153,10 +153,10 @@
                                  const String& key,
                                  v8::Local<v8::Value>& value,
                                  ExceptionState&) {
-  std::unique_ptr<WebRTCStats> stats = report_->GetStats(key);
+  std::unique_ptr<RTCStats> stats = report_->GetStats(key);
   if (!stats)
     return false;
-  value = WebRTCStatsToValue(script_state, stats.get());
+  value = RTCStatsToValue(script_state, stats.get());
   return true;
 }
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
index f6f0e15..cd5eeb3 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
@@ -26,7 +26,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  RTCStatsReport(std::unique_ptr<WebRTCStatsReport>);
+  RTCStatsReport(std::unique_ptr<RTCStatsReportPlatform>);
 
   uint32_t size() const;
 
@@ -40,7 +40,7 @@
                    ExceptionState&) override;
 
  private:
-  std::unique_ptr<WebRTCStatsReport> report_;
+  std::unique_ptr<RTCStatsReportPlatform> report_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
index ba2848d..9d78cde 100644
--- a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
+++ b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 
 namespace blink {
 
@@ -18,17 +19,17 @@
   return base::BindOnce(&TestWebRTCStatsReportObtainer::OnStatsDelivered, this);
 }
 
-blink::WebRTCStatsReport* TestWebRTCStatsReportObtainer::report() const {
+RTCStatsReportPlatform* TestWebRTCStatsReportObtainer::report() const {
   return report_.get();
 }
 
-blink::WebRTCStatsReport* TestWebRTCStatsReportObtainer::WaitForReport() {
+RTCStatsReportPlatform* TestWebRTCStatsReportObtainer::WaitForReport() {
   run_loop_.Run();
   return report_.get();
 }
 
 void TestWebRTCStatsReportObtainer::OnStatsDelivered(
-    std::unique_ptr<blink::WebRTCStatsReport> report) {
+    std::unique_ptr<RTCStatsReportPlatform> report) {
   report_ = std::move(report);
   run_loop_.Quit();
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
index affd519..9d376e05 100644
--- a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
+++ b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
@@ -15,7 +15,7 @@
 
 // The obtainer is a test-only helper class capable of waiting for a GetStats()
 // callback to be called. It takes ownership of and exposes the resulting
-// blink::WebRTCStatsReport.
+// RTCStatsReportPlatform.
 // While WaitForReport() is waiting for the report, tasks posted on the current
 // thread are executed (see base::RunLoop::Run()) making it safe to wait on the
 // same thread that the stats report callback occurs on without blocking the
@@ -27,18 +27,18 @@
 
   blink::WebRTCStatsReportCallback GetStatsCallbackWrapper();
 
-  blink::WebRTCStatsReport* report() const;
-  blink::WebRTCStatsReport* WaitForReport();
+  RTCStatsReportPlatform* report() const;
+  RTCStatsReportPlatform* WaitForReport();
 
  private:
   friend class WTF::ThreadSafeRefCounted<TestWebRTCStatsReportObtainer>;
   friend class CallbackWrapper;
   virtual ~TestWebRTCStatsReportObtainer();
 
-  void OnStatsDelivered(std::unique_ptr<blink::WebRTCStatsReport> report);
+  void OnStatsDelivered(std::unique_ptr<RTCStatsReportPlatform> report);
 
   base::RunLoop run_loop_;
-  std::unique_ptr<blink::WebRTCStatsReport> report_;
+  std::unique_ptr<RTCStatsReportPlatform> report_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
index 531cfd02..d271f3a 100644
--- a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
@@ -1,12 +1,13 @@
 #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
 
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
 
 namespace blink {
 
 void WebRTCStatsReportCallbackResolver(
     ScriptPromiseResolver* resolver,
-    std::unique_ptr<WebRTCStatsReport> report) {
+    std::unique_ptr<RTCStatsReportPlatform> report) {
   DCHECK(ExecutionContext::From(resolver->GetScriptState())->IsContextThread());
   resolver->Resolve(MakeGarbageCollected<RTCStatsReport>(std::move(report)));
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
index ce7de6a8..8aa110b 100644
--- a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
+++ b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
@@ -14,7 +14,7 @@
 namespace blink {
 
 void WebRTCStatsReportCallbackResolver(ScriptPromiseResolver*,
-                                       std::unique_ptr<WebRTCStatsReport>);
+                                       std::unique_ptr<RTCStatsReportPlatform>);
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index 5985cec3..78b20d9 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -107,7 +107,7 @@
     }
 
     vector->Append(static_cast<uint8_t*>(array_buffer->Data()),
-                   array_buffer->ByteLength());
+                   array_buffer->ByteLengthAsUnsigned());
   } else {
     ArrayBufferView* view = buffer_source.GetAsArrayBufferView().View()->View();
     if (!view->Buffer() || view->Buffer()->IsDetached()) {
diff --git a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
index ed27c0a..f871cdb 100644
--- a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
+++ b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
@@ -6,10 +6,6 @@
 
 namespace blink {
 
-WebRTCStatsReport::~WebRTCStatsReport() = default;
-
-WebRTCStats::~WebRTCStats() = default;
-
 WebRTCStatsMember::~WebRTCStatsMember() = default;
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index f2d047a..22074d10 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -306,6 +306,8 @@
   canvas_ = paint_recorder_.beginRecording(bounds);
   if (metafile_)
     canvas_->SetPrintingMetafile(metafile_);
+  if (tracker_)
+    canvas_->SetPaintPreviewTracker(tracker_);
 }
 
 namespace {
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
index 42631cf..ca07051 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
@@ -19,10 +19,6 @@
 class PaintCanvas;
 }
 
-namespace paint_preview {
-class PaintPreviewTracker;
-}
-
 namespace blink {
 class GraphicsContext;
 class PaintController;
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index 39c90da..6b3bd5fd 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -863,8 +863,8 @@
         this);
   }
 
-  void ZapWeakMembers(const WeakCallbackInfo& broker) {
-    if (!broker.IsHeapObjectAlive(weak_bar_))
+  void ZapWeakMembers(const WeakCallbackInfo& info) {
+    if (!info.IsHeapObjectAlive(weak_bar_))
       weak_bar_ = nullptr;
   }
 
@@ -1013,8 +1013,8 @@
         this);
   }
 
-  void ZapWeakMembers(const WeakCallbackInfo& broker) {
-    if (data_ && !broker.IsHeapObjectAlive(data_)) {
+  void ZapWeakMembers(const WeakCallbackInfo& info) {
+    if (data_ && !info.IsHeapObjectAlive(data_)) {
       data_->WillFinalize();
       data_ = nullptr;
       did_call_will_finalize_ = true;
diff --git a/third_party/blink/renderer/platform/heap/visitor.h b/third_party/blink/renderer/platform/heap/visitor.h
index 81ea157..67e195fe 100644
--- a/third_party/blink/renderer/platform/heap/visitor.h
+++ b/third_party/blink/renderer/platform/heap/visitor.h
@@ -80,8 +80,8 @@
 template <typename T, void (T::*method)(const WeakCallbackInfo&)>
 struct WeakCallbackMethodDelegate {
   STATIC_ONLY(WeakCallbackMethodDelegate);
-  static void Trampoline(const WeakCallbackInfo& broker, void* self) {
-    (reinterpret_cast<T*>(self)->*method)(broker);
+  static void Trampoline(const WeakCallbackInfo& info, void* self) {
+    (reinterpret_cast<T*>(self)->*method)(info);
   }
 };
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
index d9c2c3c..216c0f02 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -71,8 +71,8 @@
       MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this);
 }
 
-void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& broker) {
-  if (!resource_ || broker.IsHeapObjectAlive(resource_))
+void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& info) {
+  if (!resource_ || info.IsHeapObjectAlive(resource_))
     return;
   GetMemoryCache()->Remove(resource_.Get());
   resource_.Clear();
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
index bc9f898..9619bce 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -118,13 +118,6 @@
 
 }  // namespace
 
-std::unique_ptr<blink::WebRTCStatsReport> CreateRTCStatsReport(
-    const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
-    const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
-  return std::make_unique<RTCStatsReportPlatform>(std::move(stats_report),
-                                                  exposed_group_ids);
-}
-
 RTCStatsReportPlatform::RTCStatsReportPlatform(
     const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
     const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids)
@@ -138,41 +131,36 @@
 
 RTCStatsReportPlatform::~RTCStatsReportPlatform() {}
 
-std::unique_ptr<blink::WebRTCStatsReport> RTCStatsReportPlatform::CopyHandle()
+std::unique_ptr<RTCStatsReportPlatform> RTCStatsReportPlatform::CopyHandle()
     const {
-  return CreateRTCStatsReport(stats_report_, exposed_group_ids_);
+  return std::make_unique<RTCStatsReportPlatform>(stats_report_,
+                                                  exposed_group_ids_);
 }
 
-std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::GetStats(
+std::unique_ptr<RTCStats> RTCStatsReportPlatform::GetStats(
     blink::WebString id) const {
   const webrtc::RTCStats* stats = stats_report_->Get(id.Utf8());
   if (!stats || !IsWhitelistedStats(*stats))
-    return std::unique_ptr<blink::WebRTCStats>();
-  return CreateRTCStats(stats_report_, stats, exposed_group_ids_);
+    return std::unique_ptr<RTCStats>();
+  return std::make_unique<RTCStats>(stats_report_, stats, exposed_group_ids_);
 }
 
-std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::Next() {
+std::unique_ptr<RTCStats> RTCStatsReportPlatform::Next() {
   while (it_ != end_) {
     const webrtc::RTCStats& next = *it_;
     ++it_;
-    if (IsWhitelistedStats(next))
-      return CreateRTCStats(stats_report_, &next, exposed_group_ids_);
+    if (IsWhitelistedStats(next)) {
+      return std::make_unique<RTCStats>(stats_report_, &next,
+                                        exposed_group_ids_);
+    }
   }
-  return std::unique_ptr<blink::WebRTCStats>();
+  return std::unique_ptr<RTCStats>();
 }
 
 size_t RTCStatsReportPlatform::Size() const {
   return size_;
 }
 
-std::unique_ptr<blink::WebRTCStats> CreateRTCStats(
-    const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
-    const webrtc::RTCStats* stats,
-    const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
-  return std::make_unique<RTCStats>(std::move(stats_owner), stats,
-                                    exposed_group_ids);
-}
-
 RTCStats::RTCStats(
     const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
     const webrtc::RTCStats* stats,
@@ -362,7 +350,7 @@
   DCHECK(report);
   DCHECK(callback_);
   // Make sure the callback is destroyed in the main thread as well.
-  std::move(callback_).Run(CreateRTCStatsReport(
+  std::move(callback_).Run(std::make_unique<RTCStatsReportPlatform>(
       base::WrapRefCounted(report.get()), exposed_group_ids_));
 }
 
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
index 5f20aa1..9e3087c4 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -15,6 +15,8 @@
 
 namespace blink {
 
+class RTCStats;
+
 // Wrapper around a webrtc::RTCStatsReport. Filters out any stats objects that
 // aren't whitelisted. |filter| controls whether to include only standard
 // members (RTCStatsMemberInterface::is_standardized return true) or not
@@ -26,18 +28,25 @@
 // TODO(crbug.com/787254): Switch over the classes below from using WebVector
 // and WebString to WTF::Vector and WTF::String, when their respective parent
 // classes are gone.
-class PLATFORM_EXPORT RTCStatsReportPlatform : public WebRTCStatsReport {
+class PLATFORM_EXPORT RTCStatsReportPlatform {
  public:
   RTCStatsReportPlatform(
       const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
       const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
-  ~RTCStatsReportPlatform() override;
-  std::unique_ptr<blink::WebRTCStatsReport> CopyHandle() const override;
+  virtual ~RTCStatsReportPlatform();
+  // Creates a new report object that is a handle to the same underlying stats
+  // report (the stats are not copied). The new report's iterator is reset,
+  // useful when needing multiple iterators.
+  std::unique_ptr<RTCStatsReportPlatform> CopyHandle() const;
 
-  std::unique_ptr<blink::WebRTCStats> GetStats(
-      blink::WebString id) const override;
-  std::unique_ptr<blink::WebRTCStats> Next() override;
-  size_t Size() const override;
+  // Gets stats object by |id|, or null if no stats with that |id| exists.
+  std::unique_ptr<RTCStats> GetStats(blink::WebString id) const;
+
+  // The next stats object, or null if the end has been reached.
+  std::unique_ptr<RTCStats> Next();
+
+  // The number of stats objects.
+  size_t Size() const;
 
  private:
   const scoped_refptr<const webrtc::RTCStatsReport> stats_report_;
@@ -48,20 +57,20 @@
   const size_t size_;
 };
 
-class PLATFORM_EXPORT RTCStats : public blink::WebRTCStats {
+class PLATFORM_EXPORT RTCStats {
  public:
   RTCStats(
       const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
       const webrtc::RTCStats* stats,
       const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
-  ~RTCStats() override;
+  virtual ~RTCStats();
 
-  blink::WebString Id() const override;
-  blink::WebString GetType() const override;
-  double Timestamp() const override;
+  blink::WebString Id() const;
+  blink::WebString GetType() const;
+  double Timestamp() const;
 
-  size_t MembersCount() const override;
-  std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const override;
+  size_t MembersCount() const;
+  std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const;
 
  private:
   // Reference to keep the report that owns |stats_| alive.
@@ -107,7 +116,7 @@
 // A stats collector callback.
 // It is invoked on the WebRTC signaling thread and will post a task to invoke
 // |callback| on the thread given in the |main_thread| argument.
-// The argument to the callback will be a |blink::WebRTCStatsReport|.
+// The argument to the callback will be a |RTCStatsReportPlatform|.
 class PLATFORM_EXPORT RTCStatsCollectorCallbackImpl
     : public webrtc::RTCStatsCollectorCallback {
  public:
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
index 082c9d6..8e05e2c 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
@@ -45,7 +45,7 @@
   // Only whitelisted stats are counted.
   EXPECT_EQ(report.Size(), 1u);
 
-  std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+  std::unique_ptr<RTCStats> stats = report.Next();
   EXPECT_TRUE(stats);
   EXPECT_EQ(stats->Id(), whitelisted_id);
   EXPECT_FALSE(report.Next());
@@ -89,7 +89,7 @@
   // TestStats has two members, but the non-standard member should be filtered
   // out.
   RTCStatsReportPlatform report(webrtc_report.get(), {});
-  std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+  std::unique_ptr<RTCStats> stats = report.Next();
   ASSERT_NE(nullptr, stats);
   ASSERT_EQ(1u, stats->MembersCount());
   EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
@@ -105,7 +105,7 @@
   RTCStatsReportPlatform report(
       webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
                                webrtc::NonStandardGroupId::kGroupIdForTesting});
-  std::unique_ptr<blink::WebRTCStats> stats = report.GetStats("id");
+  std::unique_ptr<RTCStats> stats = report.GetStats("id");
   ASSERT_NE(nullptr, stats);
   ASSERT_EQ(2u, stats->MembersCount());
   EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
@@ -120,7 +120,7 @@
 
   // Check that filtering options are preserved during copy.
   RTCStatsReportPlatform standard_members_report(webrtc_report.get(), {});
-  std::unique_ptr<blink::WebRTCStatsReport> standard_members_copy =
+  std::unique_ptr<RTCStatsReportPlatform> standard_members_copy =
       standard_members_report.CopyHandle();
 
   ASSERT_EQ(1u, standard_members_report.GetStats("id")->MembersCount());
@@ -129,7 +129,7 @@
   RTCStatsReportPlatform all_members_report(
       webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
                                webrtc::NonStandardGroupId::kGroupIdForTesting});
-  std::unique_ptr<blink::WebRTCStatsReport> all_members_copy =
+  std::unique_ptr<RTCStatsReportPlatform> all_members_copy =
       all_members_report.CopyHandle();
   ASSERT_EQ(2u, all_members_report.GetStats("id")->MembersCount());
   ASSERT_EQ(2u, all_members_copy->GetStats("id")->MembersCount());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 893757d..e6eeceac 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -378,7 +378,7 @@
     },
     {
       name: "CSS3TextBreakAnywhere",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "CSSAdditiveAnimations",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 41d9683..6f1747b5 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -474,7 +474,7 @@
       } else {
         return PausableTaskQueueTraits();
       }
-    case TaskType::kInternalFreezableIPC:
+    case TaskType::kInternalNavigationAssociated:
       return FreezableTaskQueueTraits();
     case TaskType::kInternalIPC:
     // Some tasks in the tests need to run when objects are paused e.g. to hook
@@ -491,7 +491,7 @@
     // time is paused.
     case TaskType::kInternalInspector:
     // Navigation IPCs do not run using virtual time to avoid hanging.
-    case TaskType::kInternalNavigationAssociated:
+    case TaskType::kInternalNavigationAssociatedUnfreezable:
       return DoesNotUseVirtualTimeTaskQueueTraits();
     case TaskType::kDeprecatedNone:
     case TaskType::kMainThreadTaskQueueV8:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
index a21f77a..5902a7a 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -129,8 +129,8 @@
       return "InternalContentCapture";
     case TaskType::kInternalNavigationAssociated:
       return "InternalNavigationAssociated";
-    case TaskType::kInternalFreezableIPC:
-      return "InternalFreezableIPC";
+    case TaskType::kInternalNavigationAssociatedUnfreezable:
+      return "InternalNavigationAssociatedUnfreezable";
     case TaskType::kInternalContinueScriptLoading:
       return "InternalContinueScriptLoading";
     case TaskType::kExperimentalWebScheduling:
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
index 6a24bff..710b1872 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -169,7 +169,7 @@
     case TaskType::kInternalMediaRealTime:
     case TaskType::kInternalUserInteraction:
     case TaskType::kInternalIntersectionObserver:
-    case TaskType::kInternalFreezableIPC:
+    case TaskType::kInternalNavigationAssociated:
     case TaskType::kInternalContinueScriptLoading:
       // UnthrottledTaskRunner is generally discouraged in future.
       // TODO(nhiroki): Identify which tasks can be throttled / suspendable and
@@ -180,7 +180,7 @@
     case TaskType::kInternalIPC:
     case TaskType::kInternalInspector:
     case TaskType::kInternalTest:
-    case TaskType::kInternalNavigationAssociated:
+    case TaskType::kInternalNavigationAssociatedUnfreezable:
       // kWebLocks can be frozen if for entire page, but not for individual
       // frames. See https://crrev.com/c/1687716
     case TaskType::kWebLocks:
diff --git a/third_party/blink/renderer/platform/wtf/hash_table.h b/third_party/blink/renderer/platform/wtf/hash_table.h
index c38ae79f..7019c2c 100644
--- a/third_party/blink/renderer/platform/wtf/hash_table.h
+++ b/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -2053,7 +2053,7 @@
   using ValueType = typename HashTableType::ValueType;
 
   // Used for purely weak and for weak-and-strong tables (ephemerons).
-  static void Process(const typename Allocator::WeakCallbackInfo& broker,
+  static void Process(const typename Allocator::WeakCallbackInfo&,
                       void* parameter) {
     HashTableType* table = reinterpret_cast<HashTableType*>(parameter);
     // During incremental marking, the table may be freed after the callback has
diff --git a/third_party/blink/tools/blinkpy/bindings/bindings_tests.py b/third_party/blink/tools/blinkpy/bindings/bindings_tests.py
index 6db448d8..56983d1 100644
--- a/third_party/blink/tools/blinkpy/bindings/bindings_tests.py
+++ b/third_party/blink/tools/blinkpy/bindings/bindings_tests.py
@@ -105,7 +105,7 @@
         shutil.rmtree(name)
 
 
-def generate_interface_dependencies(runtime_enabled_features):
+def generate_interface_dependencies(runtime_enabled_features, cache_directory):
     def idl_paths_recursive(directory):
         # This is slow, especially on Windows, due to os.walk making
         # excess stat() calls. Faster versions may appear in Python 3.5 or
@@ -127,7 +127,7 @@
         return idl_paths
 
     def collect_interfaces_info(idl_path_list):
-        info_collector = InterfaceInfoCollector()
+        info_collector = InterfaceInfoCollector(cache_directory)
         for idl_path in idl_path_list:
             info_collector.collect_info(idl_path)
         info = info_collector.get_info_as_dict()
@@ -208,6 +208,9 @@
                 continue
             directory_with_component = os.path.join(directory, component)
             for filename in os.listdir(directory_with_component):
+                if filename in ('lextab.py', 'parsetab.pickle'):
+                    # Ignore tempfiles from PLY.
+                    continue
                 files.append(os.path.join(directory_with_component, filename))
         return files
 
@@ -288,7 +291,10 @@
         return features_map
 
     try:
-        generate_interface_dependencies(make_runtime_features_dict())
+        output_dir = os.path.join(output_directory, 'third_party/blink/renderer/bindings/tests/results')
+        if not os.path.exists(output_dir):
+            os.makedirs(output_dir)
+        generate_interface_dependencies(make_runtime_features_dict(), output_directory)
         for component in COMPONENT_DIRECTORY:
             output_dir = os.path.join(output_directory, component)
             if not os.path.exists(output_dir):
@@ -297,7 +303,7 @@
             options = IdlCompilerOptions(
                 output_directory=output_dir,
                 impl_output_directory=output_dir,
-                cache_directory=None,
+                cache_directory=output_dir,
                 target_component=component)
 
             if component == 'core':
@@ -308,7 +314,7 @@
                 partial_interface_options = IdlCompilerOptions(
                     output_directory=partial_interface_output_dir,
                     impl_output_directory=None,
-                    cache_directory=None,
+                    cache_directory=output_dir,
                     target_component='modules')
 
             idl_filenames = []
diff --git a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py
index 484b2e0..bd3ef84 100755
--- a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py
+++ b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py
@@ -65,7 +65,8 @@
     Returns:
       a generator which yields IDL node objects
     """
-    parser = BlinkIDLParser()
+    # We use debug=True to not have to worry about generated parser tables.
+    parser = BlinkIDLParser(debug=True)
     for path in paths:
         definitions = parse_file(parser, path)
         for definition in definitions.GetChildren():
diff --git a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py
index f98971b..f61724b 100755
--- a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py
+++ b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py
@@ -35,7 +35,8 @@
 
 class TestFunctions(unittest.TestCase):
     def setUp(self):
-        parser = BlinkIDLParser()
+        # We use debug=True to not have to worry about generated parser tables.
+        parser = BlinkIDLParser(debug=True)
         path = os.path.join(
             testdata_path, utilities.read_file_to_list(_FILE)[0])
         definitions = parse_file(parser, path)
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
index aa49509d..775c91e 100644
--- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
+++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
@@ -38,8 +38,5 @@
 crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ]
 crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ]
 
-# createImageBitmap fails for HTMLVideoElement
-crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ]
-
 # Crashing third_party/blink/tools/blinkpy/common/message_pool.py
 crbug.com/1018884 compositing/overflow/scrollbar-layer-placement.html [ Skip ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
index d3d8b61b..fdee1c2f 100644
--- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
+++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
@@ -1,6 +1,3 @@
-# Test consistently hitting default timeout.
-Bug(none) css3/filters/effect-reference-subregion.html [ Skip ]
-
 # OffscreenCanvas not rendering.
 crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Skip ]
 crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage.html [ Skip ]
@@ -22,7 +19,4 @@
 # Expected Image Region Rendering Nothing.
 crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-alpha.html [ Skip ]
 crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ]
-crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ]
-
-# createImageBitmap fails for HTMLVideoElement
-crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ]
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index ec3b3fd..fd1607e 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -148,6 +148,10 @@
 [ Linux ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ Skip ]
 [ Win ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ Skip ]
 
+# Mac only test for Gill Sans kerning
+crbug.com/1004945 [ Linux ] fast/text/mac-aat-morx-kern.html [ Skip ]
+crbug.com/1004945 [ Win ] fast/text/mac-aat-morx-kern.html [ Skip ]
+
 # Segoe UI matching is only relevant on Windows
 [ Mac ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ Skip ]
 [ Linux ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 78529ae44..e7f620bb 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -210,6 +210,8 @@
 crbug.com/730267 virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer.html [ Pass Timeout Failure ]
 crbug.com/730267 virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer-filter.html [ Pass Timeout Failure ]
 
+crbug.com/1022460 [ Win ] storage/indexeddb/key-type-array.html [ Pass Crash ]
+
 # Flaky virtual/threaded/fast/scrolling tests
 crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/absolute-position-behind-scrollbar.html [ Failure Pass ]
 crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/fixed-position-behind-scrollbar.html [ Failure Pass ]
@@ -2797,6 +2799,7 @@
 crbug.com/1022141 virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechSynthesis-speak-events.html [ Crash Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ]
 crbug.com/626703 [ Mac ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ]
 crbug.com/626703 [ Win ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ]
@@ -3855,7 +3858,7 @@
 crbug.com/626703 external/wpt/html/cross-origin-embedder-policy/none.https.html [ Failure ]
 crbug.com/626703 external/wpt/html/cross-origin-opener-policy/coop-sandbox.https.html [ Failure ]
 crbug.com/626703 [ Debug ] external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure ]
-crbug.com/626703 [ Debug ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Pass Failure ]
+crbug.com/626703 [ Debug ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Pass Failure ]
 
 # Failure due to on-going off-thread paint worklet project.
 crbug.com/957457 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Crash ]
@@ -5800,7 +5803,7 @@
 # Sheriff 2019-10-11
 crbug.com/1012599 external/wpt/fetch/cross-origin-resource-policy/fetch.https.any.sharedworker.html [ Pass Timeout ]
 crbug.com/1013391 http/tests/devtools/a11y-axe-core/settings/shortcuts-a11y-test.js [ Pass Timeout ]
-crbug.com/1013523 [ Release ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ]
+crbug.com/1013523 [ Release ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ]
 crbug.com/1013523 [ Release Linux Mac ] external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ]
 crbug.com/1010472 [ Linux Mac Debug ] virtual/disable-deferred-rendering/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Timeout Pass ]
 crbug.com/1010472 virtual/disable-deferred-rendering/fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Failure Pass ]
@@ -5820,7 +5823,7 @@
 crbug.com/1014812 virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Pass Timeout Failure ]
 crbug.com/1014950 [ Mac ] http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-no-url-end-to-end.js [ Pass Timeout ]
 crbug.com/1014950 [ Mac ] virtual/threaded/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-no-url-end-to-end.js [ Pass Timeout ]
-crbug.com/1015187 [ Linux Mac ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none.https.html [ Pass Failure ]
+crbug.com/1015187 [ Linux Mac ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none.https.html [ Pass Failure ]
 
 # Sheriff 2019-10-18
 crbug.com/1015859 [ Linux ] http/tests/devtools/a11y-axe-core/performance/landing-page-a11y-test.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 3ed9aef..96e081eb 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -584,9 +584,9 @@
     "args": ["--enable-features=BlinkSchedulerDisableAntiStarvationForPriorities"]
   },
   {
-    "prefix": "cross-origin-embedder-policy",
+    "prefix": "cross-origin-isolation",
     "bases": ["external/wpt/html/cross-origin-embedder-policy"],
-    "args": ["--enable-features=CrossOriginEmbedderPolicy"]
+    "args": ["--enable-features=CrossOriginIsolation"]
   },
   {
     "prefix": "json-modules",
diff --git a/third_party/blink/web_tests/accessibility/image-map1-expected.txt b/third_party/blink/web_tests/accessibility/image-map1-expected.txt
index d7afe984..c777793 100644
--- a/third_party/blink/web_tests/accessibility/image-map1-expected.txt
+++ b/third_party/blink/web_tests/accessibility/image-map1-expected.txt
@@ -2,6 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
+PASS container.role is 'AXRole: AXImageMap'
 PASS container.childAtIndex(0).role is 'AXRole: AXLink'
 PASS container.childAtIndex(0).name is 'Link1'
 PASS container.childAtIndex(1).role is 'AXRole: AXLink'
diff --git a/third_party/blink/web_tests/accessibility/image-map1.html b/third_party/blink/web_tests/accessibility/image-map1.html
index 3e4e4ab1..ec8a37cb 100644
--- a/third_party/blink/web_tests/accessibility/image-map1.html
+++ b/third_party/blink/web_tests/accessibility/image-map1.html
@@ -27,7 +27,12 @@
         if (window.accessibilityController) {
             document.getElementById("body").focus();
 
-            var container = accessibilityController.focusedElement.childAtIndex(0);
+            var body = accessibilityController.accessibleElementById('body');
+            var container = body.childAtIndex(0);
+
+            shouldBe("container.role", "'AXRole: AXImageMap'");
+
+
             shouldBe("container.childAtIndex(0).role", "'AXRole: AXLink'");
             shouldBe("container.childAtIndex(0).name", "'Link1'");
 
diff --git a/third_party/blink/web_tests/accessibility/image-map2-expected.txt b/third_party/blink/web_tests/accessibility/image-map2-expected.txt
index d36e7ab..ddad784 100644
--- a/third_party/blink/web_tests/accessibility/image-map2-expected.txt
+++ b/third_party/blink/web_tests/accessibility/image-map2-expected.txt
@@ -2,9 +2,6 @@
 ----------------------
 
 ------------
-
-AXRole: AXGenericContainer
-------------
 Link1
 AXRole: AXLink
 ------------
diff --git a/third_party/blink/web_tests/accessibility/image-map2.html b/third_party/blink/web_tests/accessibility/image-map2.html
index 1a29b48..7f5c12b 100644
--- a/third_party/blink/web_tests/accessibility/image-map2.html
+++ b/third_party/blink/web_tests/accessibility/image-map2.html
@@ -3,7 +3,7 @@
     if (window.testRunner)
         testRunner.dumpAsText();
 </script>
-<body id="body">
+<body>
 
     <div id="result"></div>
 
@@ -13,18 +13,18 @@
       <area shape="rect" coords="12,74,134,88" href="http://www.apple.com" alt="Link2" />
     </map>
 
-    <img src="resources/cake.png"  border="0" align="left" usemap="#imagemap1" vspace="1">
+    <img id="map" src="resources/cake.png"  border="0" align="left" usemap="#imagemap1" vspace="1">
 
 
     <script>
         if (window.accessibilityController) {
             var result = document.getElementById("result");
 
-            var body = document.getElementById("body");
-            body.focus();
+            var container = accessibilityController.accessibleElementById('map');
+
             result.innerText += "Image map - test 2 - 2 Links (alt tags)\n";
             result.innerText += "----------------------\n";
-            result.innerText += accessibilityController.focusedElement.childAtIndex(0).attributesOfChildren() + "\n\n";
+            result.innerText += container.attributesOfChildren() + "\n\n";
         }
     </script>
 </body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index b55b9035..7b43560 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -46615,6 +46615,30 @@
      {}
     ]
    ],
+   "css/css-flexbox/percentage-heights-008.html": [
+    [
+     "css/css-flexbox/percentage-heights-008.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-flexbox/percentage-heights-009.html": [
+    [
+     "css/css-flexbox/percentage-heights-009.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-flexbox/percentage-size-subitems-001.html": [
     [
      "css/css-flexbox/percentage-size-subitems-001.html",
@@ -46855,18 +46879,6 @@
      {}
     ]
    ],
-   "css/css-flexbox/ttwf-reftest-flex-order.html": [
-    [
-     "css/css-flexbox/ttwf-reftest-flex-order.html",
-     [
-      [
-       "/css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html": [
     [
      "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html",
@@ -52997,6 +53009,450 @@
      {}
     ]
    ],
+   "css/css-intrinsic-size/intrinsic-size-001.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-001.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-002.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-002.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-003.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-003.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-003-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-004.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-004.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-005.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-005.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-006.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-006.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-007.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-007.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-007-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-008.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-008.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-008-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-009.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-009.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-009-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-010.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-010.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-010-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-011.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-011.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-011-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-012.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-012.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-012-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-013.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-013.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-013-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-014.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-014.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-014-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-015.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-015.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-015-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-016.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-016.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-016-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-017.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-017.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-017-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-018.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-018.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-018-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-019.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-019.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-019-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-020.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-020.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-020-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-021.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-021.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-021-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-022.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-022.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-022-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-023.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-023.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-023-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-024.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-024.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-024-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-025.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-025.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-025-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-026.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-026.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-026-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-001.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-auto-001.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-002.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-auto-002.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-003.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-auto-003.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html": [
+    [
+     "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html",
+     [
+      [
+       "/css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-layout-api/auto-block-size/absolute.https.html": [
     [
      "css/css-layout-api/auto-block-size/absolute.https.html",
@@ -70749,6 +71205,42 @@
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/overflow-wrap-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/overflow-wrap-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html": [
     [
      "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html",
@@ -70761,6 +71253,54 @@
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html": [
     [
      "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html",
@@ -70965,6 +71505,54 @@
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html": [
     [
      "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html",
@@ -73689,6 +74277,66 @@
      {}
     ]
    ],
+   "css/css-text/white-space/break-spaces-before-first-char-014.html": [
+    [
+     "css/css-text/white-space/break-spaces-before-first-char-014.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-before-first-char-015.html": [
+    [
+     "css/css-text/white-space/break-spaces-before-first-char-015.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-before-first-char-016.html": [
+    [
+     "css/css-text/white-space/break-spaces-before-first-char-016.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-before-first-char-017.html": [
+    [
+     "css/css-text/white-space/break-spaces-before-first-char-017.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-before-first-char-018.html": [
+    [
+     "css/css-text/white-space/break-spaces-before-first-char-018.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/white-space/break-spaces-tab-001.html": [
     [
      "css/css-text/white-space/break-spaces-tab-001.html",
@@ -73761,6 +74409,126 @@
      {}
     ]
    ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html",
+     [
+      [
+       "/css/css-text/white-space/reference/pre-wrap-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html",
+     [
+      [
+       "/css/css-text/white-space/reference/pre-wrap-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html": [
+    [
+     "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/white-space/control-chars-000.html": [
     [
      "css/css-text/white-space/control-chars-000.html",
@@ -74661,6 +75429,30 @@
      {}
     ]
    ],
+   "css/css-text/white-space/pre-wrap-009.html": [
+    [
+     "css/css-text/white-space/pre-wrap-009.html",
+     [
+      [
+       "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/white-space/pre-wrap-010.html": [
+    [
+     "css/css-text/white-space/pre-wrap-010.html",
+     [
+      [
+       "/css/css-text/white-space/reference/pre-wrap-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/white-space/pre-wrap-011.html": [
     [
      "css/css-text/white-space/pre-wrap-011.html",
@@ -76181,6 +76973,30 @@
      {}
     ]
    ],
+   "css/css-text/word-break/word-break-break-all-inline-009.html": [
+    [
+     "css/css-text/word-break/word-break-break-all-inline-009.html",
+     [
+      [
+       "/css/css-text/word-break/reference/word-break-break-all-010-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/word-break/word-break-break-all-inline-010.html": [
+    [
+     "css/css-text/word-break/word-break-break-all-inline-010.html",
+     [
+      [
+       "/css/css-text/word-break/reference/word-break-break-all-010-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html": [
     [
      "css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html",
@@ -133597,9 +134413,6 @@
    "css/css-flexbox/reference/ttwf-reftest-flex-inline-ref.html": [
     []
    ],
-   "css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html": [
-    []
-   ],
    "css/css-flexbox/reference/ttwf-reftest-flex-wrap-ref.html": [
     []
    ],
@@ -139666,6 +140479,120 @@
    "css/css-inline/parsing/dominant-baseline-valid-expected.txt": [
     []
    ],
+   "css/css-intrinsic-size/intrinsic-size-001-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-002-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-003-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-004-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-005-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-006-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-007-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-008-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-009-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-010-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-011-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-012-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-013-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-014-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-015-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-016-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-017-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-018-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-019-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-020-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-021-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-022-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-023-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-024-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-025-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-026-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html": [
+    []
+   ],
+   "css/css-intrinsic-size/resources/dice.png": [
+    []
+   ],
    "css/css-layout-api/META.yml": [
     []
    ],
@@ -143371,9 +144298,6 @@
    "css/css-text/overflow-wrap/overflow-wrap-004-ref.html": [
     []
    ],
-   "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002-expected.txt": [
-    []
-   ],
    "css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html": [
     []
    ],
@@ -143416,12 +144340,6 @@
    "css/css-text/parsing/hyphens-computed-expected.txt": [
     []
    ],
-   "css/css-text/parsing/overflow-wrap-computed-expected.txt": [
-    []
-   ],
-   "css/css-text/parsing/overflow-wrap-valid-expected.txt": [
-    []
-   ],
    "css/css-text/parsing/text-align-all-valid-expected.txt": [
     []
    ],
@@ -143449,12 +144367,6 @@
    "css/css-text/parsing/text-transform-valid-expected.txt": [
     []
    ],
-   "css/css-text/parsing/word-wrap-computed-expected.txt": [
-    []
-   ],
-   "css/css-text/parsing/word-wrap-valid-expected.txt": [
-    []
-   ],
    "css/css-text/shaping/reference/shaping-000-sanity-ref.html": [
     []
    ],
@@ -162589,6 +163501,9 @@
    "html/webappapis/system-state-and-capabilities/the-navigator-object/navigatorcookies-cookieenabled-false-manual-expected.txt": [
     []
    ],
+   "html/webappapis/the-windoworworkerglobalscope-mixin/README.md": [
+    []
+   ],
    "html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginSharedWorker.js": [
     []
    ],
@@ -171169,30 +172084,6 @@
    "streams/count-queuing-strategy.any.worker-expected.txt": [
     []
    ],
-   "streams/piping/abort.any-expected.txt": [
-    []
-   ],
-   "streams/piping/abort.any.serviceworker-expected.txt": [
-    []
-   ],
-   "streams/piping/abort.any.sharedworker-expected.txt": [
-    []
-   ],
-   "streams/piping/abort.any.worker-expected.txt": [
-    []
-   ],
-   "streams/piping/pipe-through.any-expected.txt": [
-    []
-   ],
-   "streams/piping/pipe-through.any.serviceworker-expected.txt": [
-    []
-   ],
-   "streams/piping/pipe-through.any.sharedworker-expected.txt": [
-    []
-   ],
-   "streams/piping/pipe-through.any.worker-expected.txt": [
-    []
-   ],
    "streams/readable-byte-streams/brand-checks.any-expected.txt": [
     []
    ],
@@ -177025,9 +177916,6 @@
    "webaudio/js/worklet-recorder.js": [
     []
    ],
-   "webaudio/refresh_idl.rb": [
-    []
-   ],
    "webaudio/resources/4ch-440.wav": [
     []
    ],
@@ -207526,6 +208414,12 @@
      {}
     ]
    ],
+   "css/css-flexbox/percentage-padding-001.html": [
+    [
+     "css/css-flexbox/percentage-padding-001.html",
+     {}
+    ]
+   ],
    "css/css-flexbox/position-absolute-001.html": [
     [
      "css/css-flexbox/position-absolute-001.html",
@@ -207682,6 +208576,12 @@
      {}
     ]
    ],
+   "css/css-fonts/generic-family-keywords-001.html": [
+    [
+     "css/css-fonts/generic-family-keywords-001.html",
+     {}
+    ]
+   ],
    "css/css-fonts/idlharness.html": [
     [
      "css/css-fonts/idlharness.html",
@@ -210536,6 +211436,102 @@
      {}
     ]
    ],
+   "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-height-computed.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-height-computed.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-height-valid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-height-valid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-size-computed.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-size-computed.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-size-valid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-size-valid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-width-computed.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-width-computed.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-intrinsic-size/parsing/intrinsic-width-valid.html": [
+    [
+     "css/css-intrinsic-size/parsing/intrinsic-width-valid.html",
+     {}
+    ]
+   ],
    "css/css-layout-api/at-supports-rule.https.html": [
     [
      "css/css-layout-api/at-supports-rule.https.html",
@@ -210620,6 +211616,12 @@
      {}
     ]
    ],
+   "css/css-lists/list-inside-contain.html": [
+    [
+     "css/css-lists/list-inside-contain.html",
+     {}
+    ]
+   ],
    "css/css-lists/nested-list-with-list-style-type-none.html": [
     [
      "css/css-lists/nested-list-with-list-style-type-none.html",
@@ -244847,9 +245849,9 @@
      {}
     ]
    ],
-   "html/dom/usvstring-reflection.html": [
+   "html/dom/usvstring-reflection.https.html": [
     [
-     "html/dom/usvstring-reflection.html",
+     "html/dom/usvstring-reflection.https.html",
      {}
     ]
    ],
@@ -291216,9 +292218,9 @@
      }
     ]
    ],
-   "screen_enumeration/requestDisplays.tentative.https.any.js": [
+   "screen_enumeration/getScreens.tentative.https.any.js": [
     [
-     "screen_enumeration/requestDisplays.tentative.https.any.html",
+     "screen_enumeration/getScreens.tentative.https.any.html",
      {
       "script_metadata": [
        [
@@ -291229,7 +292231,7 @@
      }
     ],
     [
-     "screen_enumeration/requestDisplays.tentative.https.any.serviceworker.html",
+     "screen_enumeration/getScreens.tentative.https.any.serviceworker.html",
      {
       "script_metadata": [
        [
@@ -291240,7 +292242,7 @@
      }
     ],
     [
-     "screen_enumeration/requestDisplays.tentative.https.any.sharedworker.html",
+     "screen_enumeration/getScreens.tentative.https.any.sharedworker.html",
      {
       "script_metadata": [
        [
@@ -291251,7 +292253,7 @@
      }
     ],
     [
-     "screen_enumeration/requestDisplays.tentative.https.any.worker.html",
+     "screen_enumeration/getScreens.tentative.https.any.worker.html",
      {
       "script_metadata": [
        [
@@ -291321,6 +292323,14 @@
      {}
     ]
    ],
+   "scroll-to-text-fragment/scroll-to-text-fragment-api.html": [
+    [
+     "scroll-to-text-fragment/scroll-to-text-fragment-api.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html": [
     [
      "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html",
@@ -296397,6 +297407,64 @@
      }
     ]
    ],
+   "streams/piping/throwing-options.any.js": [
+    [
+     "streams/piping/throwing-options.any.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker,jsshell"
+       ]
+      ]
+     }
+    ],
+    [
+     "streams/piping/throwing-options.any.js",
+     {
+      "jsshell": true,
+      "script_metadata": [
+       [
+        "global",
+        "worker,jsshell"
+       ]
+      ]
+     }
+    ],
+    [
+     "streams/piping/throwing-options.any.serviceworker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker,jsshell"
+       ]
+      ]
+     }
+    ],
+    [
+     "streams/piping/throwing-options.any.sharedworker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker,jsshell"
+       ]
+      ]
+     }
+    ],
+    [
+     "streams/piping/throwing-options.any.worker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker,jsshell"
+       ]
+      ]
+     }
+    ]
+   ],
    "streams/piping/transform-streams.any.js": [
     [
      "streams/piping/transform-streams.any.html",
@@ -300823,6 +301891,12 @@
      {}
     ]
    ],
+   "svg/animations/short-simple-duration-and-fractional-repeatcount.html": [
+    [
+     "svg/animations/short-simple-duration-and-fractional-repeatcount.html",
+     {}
+    ]
+   ],
    "svg/animations/single-values-animation.html": [
     [
      "svg/animations/single-values-animation.html",
@@ -301281,6 +302355,12 @@
      {}
     ]
    ],
+   "svg/animations/switching-animated-target-to-unknown-element.html": [
+    [
+     "svg/animations/switching-animated-target-to-unknown-element.html",
+     {}
+    ]
+   ],
    "svg/animations/syncbase-remove-add-while-running.html": [
     [
      "svg/animations/syncbase-remove-add-while-running.html",
@@ -310041,6 +311121,23 @@
      {}
     ]
    ],
+   "web-animations/idlharness.window.js": [
+    [
+     "web-animations/idlharness.window.html",
+     {
+      "script_metadata": [
+       [
+        "script",
+        "/resources/WebIDLParser.js"
+       ],
+       [
+        "script",
+        "/resources/idlharness.js"
+       ]
+      ]
+     }
+    ]
+   ],
    "web-animations/interfaces/Animatable/animate-no-browsing-context.html": [
     [
      "web-animations/interfaces/Animatable/animate-no-browsing-context.html",
@@ -310095,23 +311192,6 @@
      {}
     ]
    ],
-   "web-animations/interfaces/Animation/idlharness.window.js": [
-    [
-     "web-animations/interfaces/Animation/idlharness.window.html",
-     {
-      "script_metadata": [
-       [
-        "script",
-        "/resources/WebIDLParser.js"
-       ],
-       [
-        "script",
-        "/resources/idlharness.js"
-       ]
-      ]
-     }
-    ]
-   ],
    "web-animations/interfaces/Animation/oncancel.html": [
     [
      "web-animations/interfaces/Animation/oncancel.html",
@@ -310184,23 +311264,6 @@
      {}
     ]
    ],
-   "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js": [
-    [
-     "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.html",
-     {
-      "script_metadata": [
-       [
-        "script",
-        "/resources/WebIDLParser.js"
-       ],
-       [
-        "script",
-        "/resources/idlharness.js"
-       ]
-      ]
-     }
-    ]
-   ],
    "web-animations/interfaces/Document/timeline.html": [
     [
      "web-animations/interfaces/Document/timeline.html",
@@ -310219,23 +311282,6 @@
      {}
     ]
    ],
-   "web-animations/interfaces/DocumentTimeline/idlharness.window.js": [
-    [
-     "web-animations/interfaces/DocumentTimeline/idlharness.window.html",
-     {
-      "script_metadata": [
-       [
-        "script",
-        "/resources/WebIDLParser.js"
-       ],
-       [
-        "script",
-        "/resources/idlharness.js"
-       ]
-      ]
-     }
-    ]
-   ],
    "web-animations/interfaces/DocumentTimeline/style-change-events.html": [
     [
      "web-animations/interfaces/DocumentTimeline/style-change-events.html",
@@ -310266,23 +311312,6 @@
      {}
     ]
    ],
-   "web-animations/interfaces/KeyframeEffect/idlharness.window.js": [
-    [
-     "web-animations/interfaces/KeyframeEffect/idlharness.window.html",
-     {
-      "script_metadata": [
-       [
-        "script",
-        "/resources/WebIDLParser.js"
-       ],
-       [
-        "script",
-        "/resources/idlharness.js"
-       ]
-      ]
-     }
-    ]
-   ],
    "web-animations/interfaces/KeyframeEffect/iterationComposite.html": [
     [
      "web-animations/interfaces/KeyframeEffect/iterationComposite.html",
@@ -373329,6 +374358,18 @@
    "1318933952c99e9bb142f74110cbc388e6dda6c4",
    "reftest"
   ],
+  "css/css-flexbox/percentage-heights-008.html": [
+   "732f94199b5129e8d7a46dba0a6195d996678683",
+   "reftest"
+  ],
+  "css/css-flexbox/percentage-heights-009.html": [
+   "b3de59562bc1ff6b78d9c7b29a5836d47bf8a81b",
+   "reftest"
+  ],
+  "css/css-flexbox/percentage-padding-001.html": [
+   "8bba5d60f5cae1b93df70c1973a473f163020a51",
+   "testharness"
+  ],
   "css/css-flexbox/percentage-size-subitems-001.html": [
    "70f3953052a3a770c6cd15ee169607a00fc452b0",
    "reftest"
@@ -373517,10 +374558,6 @@
    "369de990ff2190ea0e4592d4dfc354a8a8fcae16",
    "support"
   ],
-  "css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html": [
-   "6cddecece8649a168f915e502eae4d00204a74fb",
-   "support"
-  ],
   "css/css-flexbox/reference/ttwf-reftest-flex-wrap-ref.html": [
    "bb3e2b947af42106dec6974664075afb9e8cb7d3",
    "support"
@@ -373805,10 +374842,6 @@
    "275ecd0b6091a1c2d267b5104552c9038b76b681",
    "reftest"
   ],
-  "css/css-flexbox/ttwf-reftest-flex-order.html": [
-   "2edac404b6d1688c1cbe7cc497e82d5e87a918fd",
-   "reftest"
-  ],
   "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html": [
    "f2aefa29e8b5e4461e6a8ae9eb76bc8c1c771698",
    "reftest"
@@ -375085,6 +376118,10 @@
    "8caf2f3d6000a28c548c84a6fbe2d4c8de2ee5b7",
    "testharness"
   ],
+  "css/css-fonts/generic-family-keywords-001.html": [
+   "aa9fb5a6a03bb330d35669f903a1ee7c0f138e18",
+   "testharness"
+  ],
   "css/css-fonts/idlharness-expected.txt": [
    "e1973eefdf8f986be26bdc0ae2751afd4e84775f",
    "support"
@@ -385873,6 +386910,370 @@
    "d51c759dcc5d7f7e2820751e7a5a7f39dcf91bf1",
    "testharness"
   ],
+  "css/css-intrinsic-size/intrinsic-size-001-ref.html": [
+   "d4f0281ae48cd9ab43403fcbfc0c50d8c96e1381",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-001.html": [
+   "43c18a0e670b33162b38f845dd860caee9f4efae",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-002-ref.html": [
+   "ab847fc36e56155a0b3638a24f9ca90077c76b23",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-002.html": [
+   "d7c34558d3b7b3291826ad9c3df4e8f7c4a25fe6",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-003-ref.html": [
+   "6a2d05149894c0e7ecfc5471bab6055bc51f072d",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-003.html": [
+   "da51eb3fc309dc7463a5e5ff06a468efbd0507b6",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-004-ref.html": [
+   "6e710943de9957bcda6ac83985615e35f2154d1e",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-004.html": [
+   "f24ffbecee80ddeaca75ec972b513a68eb0ceba0",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-005-ref.html": [
+   "950f7190cac250124ba5cda419a71126e157d2e0",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-005.html": [
+   "ffbfe8b1ec79b4c13121a0c22b3f2265dd52b9c2",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-006-ref.html": [
+   "d545093e2db58163637e466b233cd15da40d0f7b",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-006.html": [
+   "3540df2734e46bbdecdf4c48b70e9c1d69bb3a16",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-007-ref.html": [
+   "6b3f63685ac07bb0e5f95570744a7b87c56158f6",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-007.html": [
+   "b0ff2c89e8ea7ab6ff961b7076d798ac7aedc268",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-008-ref.html": [
+   "5c6186fd48cf0dfd2ee83fd6ed2819fa6dbb0989",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-008.html": [
+   "27178f67d4929e15cc823d25f81072707fa09aa2",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-009-ref.html": [
+   "223e0c8a33a6832e37dc4b78de4c27b5a3abcc11",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-009.html": [
+   "3d837b9b9bb8b475747a66bb6f5652fb8bade000",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-010-ref.html": [
+   "eaaa0977f139938e2657814fd78d543f2bc5e0db",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-010.html": [
+   "73d23c732c6775ab6948d38ee3dcf59f05da16fa",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-011-ref.html": [
+   "29d1f4e2d1a108dd53c5905e45d9c7923ca9a2ba",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-011.html": [
+   "d050160f7f78fb9596caeb7e48740f8d8cb64944",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-012-ref.html": [
+   "ed9857aa2565762f514fe5fb73173b6a5da6494f",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-012.html": [
+   "a5ba04751cd92e889c3d27892abd7d0413ff35a6",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-013-ref.html": [
+   "9f8334c03d508bc1d91d0163674a28c89c77e034",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-013.html": [
+   "dca4c17f7bd9822ad1db78dee371b928923b8acc",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-014-ref.html": [
+   "66c10824893089e0c78dd5f6f68e167eac7438b6",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-014.html": [
+   "d69f58fd2ec2ee696a4cf65e1cda9832ddad45b9",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-015-ref.html": [
+   "ae65a3b5ca547b19e8bdc7b38099c8206edfa6c4",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-015.html": [
+   "c7a977540dde36d40d7499ea2c3c89f3ba32a653",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-016-ref.html": [
+   "f80510f630624b7bce27483fe9847cd182114fe0",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-016.html": [
+   "2c1c917b4f8221096d905ced69f4e92e5172843a",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-017-ref.html": [
+   "553451a7075559dad575be17e2ce08b62cb67832",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-017.html": [
+   "d9d33477834bcdc00d57cbe2f465dd3538e487bc",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-018-ref.html": [
+   "17261caa8af2b65f80ed331fb38bb5c2e37d5b10",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-018.html": [
+   "e31b0a412eda0ad07c741c032be6f9bb0b848434",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-019-ref.html": [
+   "8e55d7b02f9d1d7352ebdeeca1ee48a1009b49f4",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-019.html": [
+   "571863939c57c1d37f617aca3bbb75da05d858de",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-020-ref.html": [
+   "1ee5ba8376ddc7e6bb74d765755fbe89b9e33b6b",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-020.html": [
+   "c4055bb09d4aff664e7d1fe89b19014f9448a2b3",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-021-ref.html": [
+   "35db43fcf44a3668ae19f0d97ea7a872223fcc9c",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-021.html": [
+   "93e610be7acf8353db9d63ee8cc3192b9ca24e68",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-022-ref.html": [
+   "b0df199283470db4a7ecba4011a3429e8065bb7e",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-022.html": [
+   "5331df38fed841d17d8a7899abe93d5193866249",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-023-ref.html": [
+   "800e4ae706447004c3c8ff5bf8a530216cba1dea",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-023.html": [
+   "aa946e82ac760b784f261b958e834b6540bf00c4",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-024-ref.html": [
+   "02ec85a0084910bb09de2e7871b7ddd7d8a68265",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-024.html": [
+   "f9fdd8848fe8942acb7b3eb3750840a0318426ec",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-025-ref.html": [
+   "60d5cc9cd9aadb99620773ea11eaf9e2081b771b",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-025.html": [
+   "d80b9772e5aef7be64188943ae7a3ab5cd8a74f0",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-026-ref.html": [
+   "2e456b43422c014a10c62fe93c776c43ad59581a",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-026.html": [
+   "fb5412bed8f18cea23b8966f7227a03d743a4f06",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html": [
+   "99e86d0c38fd2b76745b6cbd05224dc5aa0537d6",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-001.html": [
+   "41b89e3d5aae831fed4d76008867f07e12596664",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html": [
+   "70a245469b702bb5b2348ca7698c71ac1ca99671",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-002.html": [
+   "446f2154de81c5e33462e325739edb1f2c0854b5",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html": [
+   "246a5bad51ed6155177a7f1fb11705c4ca7dd944",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-auto-003.html": [
+   "c5da41152863551a6977aeed6b9cb937a77da0a1",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html": [
+   "39c6abdcf8eba74a04c1255388ca551cf8988ed5",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html": [
+   "e565b56fe98d61022f5cfc184706325ad98a9101",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html": [
+   "535915a7a7bed54142f731a21eb20a97379650a1",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html": [
+   "bc1141822a66c4560a6cc75f69f890f95d9d233c",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html": [
+   "eb6394fe28464f74106c99830d67af1efa58aba4",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html": [
+   "78502f4bd645e47658358d760f67dae2b5a02a1e",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html": [
+   "d5e7c9ff9bb9c4f155955065161e14f1fcbc954e",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html": [
+   "7187222c4ce55dfd827ea81fd3ac0e841b652b7c",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html": [
+   "c23984f5f1a4d07c2121088987718781d00fc85c",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html": [
+   "0ec60fdaa3353e0a799838ce61eccd3f3ae6b264",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html": [
+   "9b9e25d3c8da8693f82bfa7d49e87a320bb3f141",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html": [
+   "e4882539b82b691256e6d1af5cdb700411810502",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html": [
+   "6894b4643ad616d4acf3a631c991718c76cdae27",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html": [
+   "0e749f7038c83382aa43ae152e6537714b893c73",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html": [
+   "5cce190275940e70c3e3451a47ed9432025dab46",
+   "support"
+  ],
+  "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html": [
+   "973683aac4208fc6c379ec5541a56b7029c965f3",
+   "reftest"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html": [
+   "e9a073ca2aacd9dd9fce6a1b0d33493498b33bac",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html": [
+   "1b6cba20f88d78f8e29d385676a261d6d78c8e67",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html": [
+   "b34c73b230f50d00371811ec063180bfc249fad7",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-height-computed.html": [
+   "6f95274c637a54bd88b1bf5e732b8a6aaa291e32",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html": [
+   "1f801124a2b5f2fe3cf96c76b9b64fe33d9f50da",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-height-valid.html": [
+   "e461476211879b903e451e662ad393162a94afdd",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html": [
+   "c53a77e5631068101f4d58a9a67d6db8b9c8c2a3",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html": [
+   "6ad224d11d3831ba227fc41ab90bf0c3b748be46",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html": [
+   "ad5aef95dca952785a8263a7b6447ef4e4b83e03",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-size-computed.html": [
+   "29be33d4a3d9a33ec30cfe150f9c9f80d5fd796d",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html": [
+   "b4cb2dbffd2004762d028f092e82e5f9297655ec",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html": [
+   "e70c3179223eaf220edd3993069848b8e0294dea",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-size-valid.html": [
+   "7ab13c7d7986151f22e01711f34a9184effca082",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-width-computed.html": [
+   "08602e5347f3de0827446875b15a29c8b6789b27",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html": [
+   "b89f6567ae27595ac752ece8bfe66784d16146de",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/parsing/intrinsic-width-valid.html": [
+   "e2d23eabe5da207ce82519e9f57adcbd4cf5d70c",
+   "testharness"
+  ],
+  "css/css-intrinsic-size/resources/dice.png": [
+   "c82d01517cd056fe1b63266b00fb9a96ce6251a2",
+   "support"
+  ],
   "css/css-layout-api/META.yml": [
    "c85c2d4ccc0b02f3e22ca444952fb7583d96e7c7",
    "support"
@@ -386757,6 +388158,10 @@
    "df54e8fb0df8146f896c2abd136d63d930d92d1c",
    "testharness"
   ],
+  "css/css-lists/list-inside-contain.html": [
+   "dc06eab97ea648bb598cdbfae5ac43d61847e8ae",
+   "testharness"
+  ],
   "css/css-lists/list-item-definition-ref.html": [
    "2d49bc4cb972803c45f701667d68d13028c4abc2",
    "support"
@@ -390534,7 +391939,7 @@
    "reftest"
   ],
   "css/css-overflow/dynamic-visible-to-clip-001.html": [
-   "08114d73b8bf6364d2ad647236fe5388f9eef1b2",
+   "b97701bfb299b5b9fc06b774f489b2e2285b2c13",
    "reftest"
   ],
   "css/css-overflow/float-with-relpos-and-transform.html": [
@@ -400961,18 +402366,42 @@
    "d125a0b5c85c15c94f4765c11c5b6ef276cca7e2",
    "reftest"
   ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html": [
+   "ac90149ff30d1d8252171460ab1f3b8800c2d58a",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html": [
+   "a5e10a84ebd3dad65e5cecfbf55eea0e70cdc108",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html": [
+   "ddb95629999d3599d972de5cf19afaa9378d6d06",
+   "reftest"
+  ],
   "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html": [
    "8655b1f087df4534f59ea7c6348fe3272f84ccbf",
    "reftest"
   ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html": [
+   "5a93c873445e91d59a857220056ba18234926850",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html": [
+   "38dc19631d3794e011f046acb225471aec2363dd",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html": [
+   "511294901d914cf8f836ea8b50662544fb72dbf4",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html": [
+   "e498e1eff16a40ce96279173b42c3827b566ba5c",
+   "reftest"
+  ],
   "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html": [
    "c4a0e10fa42d6389f1bb02a945137a4f40fa03db",
    "reftest"
   ],
-  "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002-expected.txt": [
-   "db1a5fe8be54f9d11b92c5a0fd40cd590752c57b",
-   "support"
-  ],
   "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002.html": [
    "b149ca4d7c25c25999e4fed9373df926c1f30cb6",
    "testharness"
@@ -401046,7 +402475,7 @@
    "reftest"
   ],
   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html": [
-   "608d4853a2425d9b4157bbe331fd78763985cecd",
+   "6975e816b469a898d3f3617f49ad91badfdc0859",
    "reftest"
   ],
   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-002.html": [
@@ -401058,7 +402487,23 @@
    "reftest"
   ],
   "css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html": [
-   "7ee2b344f7fdee15b05e590ff93a23c04cf63ffc",
+   "16161ece69dc85e0caffe370889e46a3071ebe08",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html": [
+   "c8c2a1a43353f9f572ce0a586a2d9c81f51515d1",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html": [
+   "dbbd39301bd741cb77f49deebc6de0ea324e8ddb",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html": [
+   "7296b8d3769a6ea83726d41efdd0725c230e9d17",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html": [
+   "5c2b3958bd79a235d2c0236804de8df195c87776",
    "reftest"
   ],
   "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html": [
@@ -401098,7 +402543,7 @@
    "support"
   ],
   "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html": [
-   "99d964777c663fb8ca37be00c162ddfbb82951c9",
+   "ef5c2e88cefbb99163b8144098d38eb5fb0d06bf",
    "support"
   ],
   "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-002-ref.html": [
@@ -401110,7 +402555,7 @@
    "support"
   ],
   "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html": [
-   "c37f3f107841a33afd891a7f39433146ab4704cc",
+   "93e22ba71ed08199fb01858e8db9950c41d4b35b",
    "support"
   ],
   "css/css-text/overflow-wrap/reference/overflow-wrap-normal-keep-all-001-ref.html": [
@@ -401189,10 +402634,6 @@
    "caaae9a5a0150a35563662a8c917046fb08e79fb",
    "testharness"
   ],
-  "css/css-text/parsing/overflow-wrap-computed-expected.txt": [
-   "6866ac85893203f11267894682e1eef594072202",
-   "support"
-  ],
   "css/css-text/parsing/overflow-wrap-computed.html": [
    "5cc8b831a8f66c154638aecf0f2b249d1391566e",
    "testharness"
@@ -401201,10 +402642,6 @@
    "1a467d5f1882fe1d5ede656bd91008499b49367a",
    "testharness"
   ],
-  "css/css-text/parsing/overflow-wrap-valid-expected.txt": [
-   "13b5febca96187dbb6310f3b55ff58bfcb833c81",
-   "support"
-  ],
   "css/css-text/parsing/overflow-wrap-valid.html": [
    "8ab907c570288a397249fb7b14cc795049283227",
    "testharness"
@@ -401361,10 +402798,6 @@
    "217b2488f53128b8475ce4a3f4ca2aa84570b743",
    "testharness"
   ],
-  "css/css-text/parsing/word-wrap-computed-expected.txt": [
-   "6f296dd1c7f8e39482b99c89358ce56962cc9f6e",
-   "support"
-  ],
   "css/css-text/parsing/word-wrap-computed.html": [
    "0f3639e2e1cbdaee8f349f208f63659d13eefef7",
    "testharness"
@@ -401373,10 +402806,6 @@
    "40890775ca563101f4ebcb4d46ecd439bececb61",
    "testharness"
   ],
-  "css/css-text/parsing/word-wrap-valid-expected.txt": [
-   "364576f2ccab5a97dc80e4f647f1455a0ba3a488",
-   "support"
-  ],
   "css/css-text/parsing/word-wrap-valid.html": [
    "ce5731551aec95f08df44f15ea6491045d14b235",
    "testharness"
@@ -403370,7 +404799,7 @@
    "reftest"
   ],
   "css/css-text/white-space/break-spaces-before-first-char-011.html": [
-   "bc6b2965cb0fdc554082ae0cd2453c602fd805de",
+   "cf1babeb5e93f601a416994cce060d46a3894f07",
    "reftest"
   ],
   "css/css-text/white-space/break-spaces-before-first-char-012.html": [
@@ -403381,6 +404810,26 @@
    "828058f53dd811d4dbea0b7e0d56ab5a940725c6",
    "reftest"
   ],
+  "css/css-text/white-space/break-spaces-before-first-char-014.html": [
+   "6eb32b57f3f3298d9b66056c7c6842c88851b152",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-before-first-char-015.html": [
+   "785c2f2a4e9ac98bbb53124eb5a0a45e5bf1648e",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-before-first-char-016.html": [
+   "bec4520b113b26a10f1ff29b3f515487f8d565e0",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-before-first-char-017.html": [
+   "9cb8fdbebcbec4687a1f523b1ffcd4a137338bff",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-before-first-char-018.html": [
+   "828058f53dd811d4dbea0b7e0d56ab5a940725c6",
+   "reftest"
+  ],
   "css/css-text/white-space/break-spaces-tab-001.html": [
    "4b01a60395a6c1133c7af8af957dd70859db4823",
    "reftest"
@@ -403405,6 +404854,46 @@
    "34df3bfc1bd2f20abbe29b79124a95ce28a4cfaf",
    "reftest"
   ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html": [
+   "6912bafee9ebd55cfeddd878f9145048b235566b",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html": [
+   "caef57ec60f8fa7c1874825272290d8236af10dd",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html": [
+   "9f91d085d8ad295b7308fe65822ad4114273fbf7",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html": [
+   "911cff021ad2df5ada257d3aa0d2a53aa131caac",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html": [
+   "d5c836539d2636e3b4e916d2b66eca135a659321",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html": [
+   "0e4b6a80f14eb9c6ed73d7d97d040ba0163dbe93",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html": [
+   "bf51e4bc2fb4b3d17635df65716a3fe2e504bda2",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html": [
+   "9826449ecc639cd0c6f388159e0a118ff1f2e0ca",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html": [
+   "3b6e76433091aae25af57b389b207d75d51dae73",
+   "reftest"
+  ],
+  "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html": [
+   "d479c5e56757fd32fcfff2066e326a8bfc24860a",
+   "reftest"
+  ],
   "css/css-text/white-space/control-chars-000.html": [
    "b038fe9a90d3b8b9cb3bde7fd46396c7121688c9",
    "reftest"
@@ -403717,6 +405206,14 @@
    "e2faf3671c2061c30028be4c9608ba1495b79072",
    "reftest"
   ],
+  "css/css-text/white-space/pre-wrap-009.html": [
+   "0912a2d3a150cea47ace39cb815af14ca811bb60",
+   "reftest"
+  ],
+  "css/css-text/white-space/pre-wrap-010.html": [
+   "71d169c65c011fe28e1b2fcdb3c3bd9dd35dad32",
+   "reftest"
+  ],
   "css/css-text/white-space/pre-wrap-011.html": [
    "9945e3ae2dda846c8691a3676d3a83aacd08bb0c",
    "reftest"
@@ -404709,6 +406206,14 @@
    "930ae436fe4f1c91b60e9a84c0925e679b6ddfc0",
    "reftest"
   ],
+  "css/css-text/word-break/word-break-break-all-inline-009.html": [
+   "e1914f5f4db6d5bfbc5c928562eb1ab790a934b8",
+   "reftest"
+  ],
+  "css/css-text/word-break/word-break-break-all-inline-010.html": [
+   "875a36233c555e9b99822773d39f960b579d16f6",
+   "reftest"
+  ],
   "css/css-text/word-break/word-break-break-word-crash-001.html": [
    "894a6f3aa0ce257a92926158b75a29986a98e079",
    "testharness"
@@ -404754,7 +406259,7 @@
    "reftest"
   ],
   "css/css-text/word-break/word-break-min-content-001.html": [
-   "20b610180b359bfdf7da5720d2e962af2ba6343f",
+   "a310e304529dd83f1d356cab6b6664e7f07be97d",
    "reftest"
   ],
   "css/css-text/word-break/word-break-min-content-002.html": [
@@ -404766,7 +406271,7 @@
    "reftest"
   ],
   "css/css-text/word-break/word-break-min-content-004.html": [
-   "efa61b9cd8af65bdb354ef7b07e7008f8a3b6511",
+   "89b30027c2e9b127ee65e5466ae0d7872f0fa451",
    "reftest"
   ],
   "css/css-text/word-break/word-break-min-content-005.html": [
@@ -432690,7 +434195,7 @@
    "support"
   ],
   "custom-elements/CustomElementRegistry.html": [
-   "368044df3c9373b4ea966bd1b7e9080581b91293",
+   "c288e8232703afbe00d355ef5b40bdc8d1fa0ac2",
    "testharness"
   ],
   "custom-elements/Document-createElement-svg.svg": [
@@ -434550,7 +436055,7 @@
    "testharness"
   ],
   "dom/nodes/aria-element-reflection.tentative.html": [
-   "848828810f160d5ac01f11bf41b27230b9738800",
+   "7c8e690a28bbcaa1391878300f143aa1e584fe5e",
    "testharness"
   ],
   "dom/nodes/attributes.html": [
@@ -446318,7 +447823,7 @@
    "support"
   ],
   "html/cross-origin-opener-policy/coep.https.html": [
-   "1c04ed30dd7b3e7cdf7df43e29eca3b433000703",
+   "64994cdfb76f18cb11c42cc8258209fcfd1091e3",
    "testharness"
   ],
   "html/cross-origin-opener-policy/coep.https.html.headers": [
@@ -446350,7 +447855,7 @@
    "support"
   ],
   "html/cross-origin-opener-policy/no-https.html": [
-   "da9efdce777c43e5b3f37bda628884c1a3579fde",
+   "014ba1f333b5e254609819bd99618ebcc6b7391b",
    "testharness"
   ],
   "html/cross-origin-opener-policy/no-https.html.headers": [
@@ -447669,7 +449174,7 @@
    "aba2b3016a5d56e29cdf5526b7b7259e402c188d",
    "testharness"
   ],
-  "html/dom/usvstring-reflection.html": [
+  "html/dom/usvstring-reflection.https.html": [
    "b9cafd1fb352cf619141420cbb68aca1483ca8e4",
    "testharness"
   ],
@@ -451382,7 +452887,7 @@
    "support"
   ],
   "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js": [
-   "96276d747047fc72d02a22055edf2986ab2163b9",
+   "a755865911d7bd5eea2c7eeca85705602234e571",
    "testharness"
   ],
   "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt": [
@@ -451530,7 +453035,7 @@
    "support"
   ],
   "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js": [
-   "9befc9006e706853d9fab259e631a39f3193c095",
+   "ffc3708acb7ae00339efbde8c9d912b1f58e7e50",
    "support"
   ],
   "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers": [
@@ -463581,6 +465086,10 @@
    "006827f186eb4e47d387a3b0c9fae404e41e1d37",
    "testharness"
   ],
+  "html/webappapis/the-windoworworkerglobalscope-mixin/README.md": [
+   "10ae3e5f03601a67e247f771cf73fdfddfdda12f",
+   "support"
+  ],
   "html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html": [
    "22b28b3e35ef5f05d18b4013798d6513c59c1700",
    "testharness"
@@ -464514,7 +466023,7 @@
    "support"
   ],
   "infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini": [
-   "0bcdd374f2521b6534208ab750a1c0d36e7dd7ca",
+   "40a58e4153ec8c39c3ce6ce64e8bcaae391f3b68",
    "support"
   ],
   "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-following-subtest.html.ini": [
@@ -464526,7 +466035,7 @@
    "support"
   ],
   "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [
-   "39773dfe714a6b5754bfe73c64294bcb38f2afa3",
+   "da4fe27e58959f7e3d6ba5ebbc7edd58a93dcf5c",
    "support"
   ],
   "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [
@@ -464570,19 +466079,19 @@
    "support"
   ],
   "infrastructure/metadata/infrastructure/server/context.any.js.ini": [
-   "c3431d687b60aa1a07d9a4307ccfd4a2253ee162",
+   "ca095a18785a6d31070c02492a868c3b8d6e6606",
    "support"
   ],
   "infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini": [
-   "8db9536e38cc880865c374f3743d7df9f727a530",
+   "23387657b41e99385f8fb9cbc0e46a7dd2626164",
    "support"
   ],
   "infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini": [
-   "5f5ed991cf1b04da84e89d7eae2e0d80b9fd2841",
+   "5b24c9429dc6e75a1288379290f04b18ab050f2c",
    "support"
   ],
   "infrastructure/metadata/infrastructure/server/title.any.js.ini": [
-   "e2a7b5578c3b0dec13206ec60da2a5c018c23eb1",
+   "8cbb5f76493c2c8e21f6c45223d4b551f5335b68",
    "support"
   ],
   "infrastructure/metadata/infrastructure/server/wpt-server-http.sub.html.ini": [
@@ -465454,7 +466963,7 @@
    "support"
   ],
   "interfaces/web-animations.idl": [
-   "6fd172ce425d570d097fcb573115091c83cc5484",
+   "0d5d40ba74f40ed68c19a8218710204b2767ae12",
    "support"
   ],
   "interfaces/web-bluetooth.idl": [
@@ -465466,7 +466975,7 @@
    "support"
   ],
   "interfaces/web-share.idl": [
-   "f433f2314becd82e7446cc00c96108d1f0efe681",
+   "a29107f05987369128593b9fb2bd3bb13017eae0",
    "support"
   ],
   "interfaces/webaudio.idl": [
@@ -465502,7 +467011,7 @@
    "support"
   ],
   "interfaces/webrtc-stats.idl": [
-   "2b823047ff1e37a13e9d2e71711360944019fcb5",
+   "3e58254baa45dbd9f94307326bf3f6fedce53b60",
    "support"
   ],
   "interfaces/webrtc.idl": [
@@ -468794,7 +470303,7 @@
    "manual"
   ],
   "mediacapture-streams/MediaStream-MediaElement-srcObject.https.html": [
-   "79100ab59fb65cc1eaccf7db0207c6f158f3e0e8",
+   "790f73ae7bd21bb118a104fc3c3e37d7895f5fe6",
    "testharness"
   ],
   "mediacapture-streams/MediaStream-add-audio-track.https.html": [
@@ -494506,7 +496015,7 @@
    "support"
   ],
   "resources/chromium/nfc-mock.js": [
-   "8924a26adb4fe28704d3ec017e8634e6527cb778",
+   "ce22a9c2cfe9c0ae460d6e1eff4aaa99fe6b24e3",
    "support"
   ],
   "resources/chromium/sensor.mojom.js": [
@@ -494566,7 +496075,7 @@
    "support"
   ],
   "resources/chromium/webxr-test.js": [
-   "ffb7f87ab0f2b772b696f37480b48447ac27c5ae",
+   "653dcac79f8f22e7143568fcf33543d210eb0127",
    "support"
   ],
   "resources/chromium/webxr-test.js.headers": [
@@ -494610,7 +496119,7 @@
    "support"
   ],
   "resources/testharness.js": [
-   "bed2856685478f1ac43bd1c655cdc57d3a1081ba",
+   "7fb1c0c8a52c1be6f2a54d9912e714f74922ee89",
    "support"
   ],
   "resources/testharness.js.headers": [
@@ -494761,8 +496270,8 @@
    "e1b50f670105f3a05dacd3518d62770685121c67",
    "support"
   ],
-  "screen_enumeration/requestDisplays.tentative.https.any.js": [
-   "e2a5bc427deb96275a1441141d53e2ffc7f8cd99",
+  "screen_enumeration/getScreens.tentative.https.any.js": [
+   "0b8c226ddbd7035d29760b8afa84d8429a3d3482",
    "testharness"
   ],
   "scroll-animations/META.yml": [
@@ -494813,16 +496322,20 @@
    "0320210f8394c7439353a6e1efd0eba339b27e20",
    "testharness"
   ],
+  "scroll-to-text-fragment/scroll-to-text-fragment-api.html": [
+   "8b1dea6f331bf41b4759cadf6859f016848566fa",
+   "testharness"
+  ],
   "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html": [
    "3bfd45382e55657b8f42d16f3a47c0188cd5c73f",
    "testharness"
   ],
   "scroll-to-text-fragment/scroll-to-text-fragment-target.html": [
-   "cf8e29589701bc8fc91d201bd43b12e5d1302073",
+   "1ef9dbba519697c61529fba0e81dc64979257e70",
    "support"
   ],
   "scroll-to-text-fragment/scroll-to-text-fragment.html": [
-   "eda63fa5b6477655a5a3ad44047f0dd6466f0b37",
+   "b3a35f489aca424b24c57b40796a179c5ee5b4c7",
    "testharness"
   ],
   "secure-contexts/META.yml": [
@@ -499910,7 +501423,7 @@
    "testharness"
   ],
   "speech-api/SpeechSynthesis-speak-events.html": [
-   "babfe3c388e92aee8c4e6ea62cd3c038eb5bcb2d",
+   "c559da1f92965d00c7532bfdad6e0cccad80c83a",
    "testharness"
   ],
   "speech-api/SpeechSynthesis-speak-ownership-expected.txt": [
@@ -500197,26 +501710,10 @@
    "48bb81fca5cd7b7fb689c0ce7ed22e9894461e63",
    "support"
   ],
-  "streams/piping/abort.any-expected.txt": [
-   "d85fa6d704d972c59296336120755ac134aef6a3",
-   "support"
-  ],
   "streams/piping/abort.any.js": [
    "65c458aa2941ff64677ec976e05de5be264dda60",
    "testharness"
   ],
-  "streams/piping/abort.any.serviceworker-expected.txt": [
-   "d85fa6d704d972c59296336120755ac134aef6a3",
-   "support"
-  ],
-  "streams/piping/abort.any.sharedworker-expected.txt": [
-   "d85fa6d704d972c59296336120755ac134aef6a3",
-   "support"
-  ],
-  "streams/piping/abort.any.worker-expected.txt": [
-   "d85fa6d704d972c59296336120755ac134aef6a3",
-   "support"
-  ],
   "streams/piping/close-propagation-backward.any.js": [
    "99141e3120ffe2cb81120451434f08bc0d16318d",
    "testharness"
@@ -500245,30 +501742,18 @@
    "541cfad6243c12114dc683c68ce558e7c4d9a042",
    "testharness"
   ],
-  "streams/piping/pipe-through.any-expected.txt": [
-   "372db5d0ee3948fd7350b216ae901bd21f0c9ef0",
-   "support"
-  ],
   "streams/piping/pipe-through.any.js": [
    "868899c72665802f8083d367955a021321c2a3be",
    "testharness"
   ],
-  "streams/piping/pipe-through.any.serviceworker-expected.txt": [
-   "372db5d0ee3948fd7350b216ae901bd21f0c9ef0",
-   "support"
-  ],
-  "streams/piping/pipe-through.any.sharedworker-expected.txt": [
-   "372db5d0ee3948fd7350b216ae901bd21f0c9ef0",
-   "support"
-  ],
-  "streams/piping/pipe-through.any.worker-expected.txt": [
-   "372db5d0ee3948fd7350b216ae901bd21f0c9ef0",
-   "support"
-  ],
   "streams/piping/then-interception.any.js": [
    "3c85f6edb25b955645ccc5fedae3f0facdb36a2b",
    "testharness"
   ],
+  "streams/piping/throwing-options.any.js": [
+   "6fab32cc6dcf4c2f4fb5a7a22999788f22459f4e",
+   "testharness"
+  ],
   "streams/piping/transform-streams.any.js": [
    "368ed79da4786e0206d421d33076fe9fe61a14ba",
    "testharness"
@@ -501261,6 +502746,10 @@
    "56f67dc5ed1ceeeea347b703f5048b289f95131b",
    "testharness"
   ],
+  "svg/animations/short-simple-duration-and-fractional-repeatcount.html": [
+   "025dd5092d3bb77707423b316f10bef8f2fb927d",
+   "testharness"
+  ],
   "svg/animations/single-values-animation.html": [
    "40aa3461866cf4c32316d86216dcfe4298be7718",
    "testharness"
@@ -501565,6 +503054,10 @@
    "17b78a2787d0becf64b90136fcf0f6f966404baa",
    "testharness"
   ],
+  "svg/animations/switching-animated-target-to-unknown-element.html": [
+   "fef86a723eebede0641f0fd46f7a2672b184457e",
+   "testharness"
+  ],
   "svg/animations/syncbase-remove-add-while-running.html": [
    "61b9604a7b6751a156c48431b89fa2f3cd1af551",
    "testharness"
@@ -503638,7 +505131,7 @@
    "support"
   ],
   "tools/OWNERS": [
-   "e1a1c69d26f27b9b8d36c08dc36eb06eb2b2f9cf",
+   "1cfc2ba5907a71ed1007031053a855bde4ebeea3",
    "support"
   ],
   "tools/__init__.py": [
@@ -508150,7 +509643,7 @@
    "support"
   ],
   "tools/wptrunner/requirements.txt": [
-   "d8a6c898d24f40c2bcffae42c32e63a9e5b10005",
+   "60775f8259eb317203825ea8fd5c26c901db5fad",
    "support"
   ],
   "tools/wptrunner/requirements_android_webview.txt": [
@@ -513749,6 +515242,10 @@
    "a33d6d4f24676356b59b6b431968d8486df50615",
    "testharness"
   ],
+  "web-animations/idlharness.window.js": [
+   "c32016280e659fe8268c87b58e4956a1eb81b399",
+   "testharness"
+  ],
   "web-animations/interfaces/Animatable/animate-expected.txt": [
    "a69448468b1eb5de8f6fbb6df1fad60c14d27aab",
    "support"
@@ -513809,10 +515306,6 @@
    "793616d3006a7360f2e2e17639acd3529042083a",
    "support"
   ],
-  "web-animations/interfaces/Animation/idlharness.window.js": [
-   "14b8395a2171db536ac5bbde964972a99defc41d",
-   "testharness"
-  ],
   "web-animations/interfaces/Animation/oncancel.html": [
    "d5391196092c9671c2c22c1c035bc173bbef7b4f",
    "testharness"
@@ -513865,10 +515358,6 @@
    "1c40a3fb211c1bd3e33e6c6c6325b1d25e3b981d",
    "testharness"
   ],
-  "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js": [
-   "5124e5095724521c721b8781dcfc92ff573f48e8",
-   "testharness"
-  ],
   "web-animations/interfaces/Document/getAnimations-expected.txt": [
    "859827578a16c73324301d8d506f23ded98c4c64",
    "support"
@@ -513889,10 +515378,6 @@
    "ca0997ac8f9012b7d019760be97e09fa0f837179",
    "testharness"
   ],
-  "web-animations/interfaces/DocumentTimeline/idlharness.window.js": [
-   "395d133f482a38a33ea5be061450f0f322be9fc9",
-   "testharness"
-  ],
   "web-animations/interfaces/DocumentTimeline/style-change-events.html": [
    "c1607e6fb92943c580802025e4a4cc617a747144",
    "testharness"
@@ -513921,10 +515406,6 @@
    "461f7f2cf65778622d41016e16fddd79285bae8e",
    "support"
   ],
-  "web-animations/interfaces/KeyframeEffect/idlharness.window.js": [
-   "22548861ae335c80858808cbe19f996f24a7edc9",
-   "testharness"
-  ],
   "web-animations/interfaces/KeyframeEffect/iterationComposite-expected.txt": [
    "5319aefca8ebc4b276a13c936b91f71f2a3a9322",
    "support"
@@ -514469,10 +515950,6 @@
    "3bf3bc23b20764ba54d5ff125699df91fffe741a",
    "support"
   ],
-  "webaudio/refresh_idl.rb": [
-   "a07847535ad7cae63b06c3d30333819cfef08b77",
-   "support"
-  ],
   "webaudio/resources/4ch-440.wav": [
    "85dc1ea9044e28eeeac6176bae61285c25ebf711",
    "support"
@@ -516462,7 +517939,7 @@
    "support"
   ],
   "webgpu/cts.html": [
-   "b60faec9623bb0adf7c1b9ad0e5d488ce14b5882",
+   "b66553df983d543453ed1f35cf20add65801481f",
    "testharness"
   ],
   "webgpu/framework/allowed_characters.js": [
@@ -516474,7 +517951,7 @@
    "support"
   ],
   "webgpu/framework/fixture.js": [
-   "2c1ea8314689e610528ba81254ee00e99242f4d5",
+   "127931223cb8b071606af2f08d97681c1a32f295",
    "support"
   ],
   "webgpu/framework/gpu/implementation.js": [
@@ -516498,7 +517975,7 @@
    "support"
   ],
   "webgpu/framework/logger.js": [
-   "e854292473640a21d6bb660a2a0999e740a90c8e",
+   "ee86919612d8725136f12879a58520004575138c",
    "support"
   ],
   "webgpu/framework/params/combine.js": [
@@ -516542,7 +518019,7 @@
    "support"
   ],
   "webgpu/framework/test_group.js": [
-   "69d8cc0401714f4f6ffe2ddfe0f8763b833914e5",
+   "68527a5b2cf55426ae779739fba788cfde94b244",
    "support"
   ],
   "webgpu/framework/tree.js": [
@@ -516562,7 +518039,7 @@
    "support"
   ],
   "webgpu/framework/util/stack.js": [
-   "ae99ac904a132d947f304ca0f03f50b25fd197ae",
+   "bd51d54509483954bb84ea9757b873ca42233cab",
    "support"
   ],
   "webgpu/framework/util/timeout.js": [
@@ -516570,7 +518047,7 @@
    "support"
   ],
   "webgpu/framework/version.js": [
-   "55a72f5efb03ad9043ea2600a311cfff249a21ce",
+   "154f0629b0dd367d3ef89ae4f200ce851b845f66",
    "support"
   ],
   "webgpu/runtime/helper/options.js": [
@@ -516586,7 +518063,7 @@
    "testharness"
   ],
   "webgpu/runtime/wpt.js": [
-   "c87f9167bbeba1edca847a76a6cb59401f0c7409",
+   "e078f6717471ad2364cf31587c55b4f24f2a3a00",
    "support"
   ],
   "webgpu/suites/cts/buffers/create_mapped.spec.js": [
@@ -516610,7 +518087,7 @@
    "support"
   ],
   "webgpu/suites/cts/canvas/context_creation.spec.js": [
-   "ba0d47228536da7192111f8bd7a6947de7c6181a",
+   "a693b002769ae9a1e951bc1888ca49ba393df7d0",
    "support"
   ],
   "webgpu/suites/cts/command_buffer/basic.spec.js": [
@@ -516618,7 +518095,7 @@
    "support"
   ],
   "webgpu/suites/cts/command_buffer/compute/basic.spec.js": [
-   "8fcc7ef9309b5a8760247f0c86ea374c0d3f3e14",
+   "8a5fc168a4d8fbed69ba5ee2009fc7049fdcf3a3",
    "support"
   ],
   "webgpu/suites/cts/command_buffer/copies.spec.js": [
@@ -516630,11 +518107,11 @@
    "support"
   ],
   "webgpu/suites/cts/command_buffer/render/rendering.spec.js": [
-   "46829a8d07cc51a04ad1ec323fdaf6f5b14e6cdc",
+   "43c4566799531fca8869500823c12feacd7d1522",
    "support"
   ],
   "webgpu/suites/cts/command_buffer/render/storeop.spec.js": [
-   "0b38debc13425c87def0548f88085aa362a7a7cb",
+   "0326cf65ad69a1558a69b83df94622041d7eb1db",
    "support"
   ],
   "webgpu/suites/cts/examples.spec.js": [
@@ -516650,7 +518127,7 @@
    "support"
   ],
   "webgpu/suites/cts/gpu_test.js": [
-   "96f109d3043edf8f77d7cbfce88e13b348e44f58",
+   "272b1b831e8f42626f285b7e4bbdff3c0b6b6306",
    "support"
   ],
   "webgpu/suites/cts/index.js": [
@@ -516670,7 +518147,7 @@
    "support"
   ],
   "webgpu/suites/cts/validation/createRenderPipeline.spec.js": [
-   "cc838fc6515a5b9a7cc55bacc0361556a3bdd93c",
+   "b66dabf285a2c007e01356ed9c42a9cfe7eddc43",
    "support"
   ],
   "webgpu/suites/cts/validation/createTexture.spec.js": [
@@ -516694,7 +518171,7 @@
    "support"
   ],
   "webgpu/suites/cts/validation/render_pass.spec.js": [
-   "52da36fa7ac9cb196aaf578707acf09a7f62724d",
+   "3e08dcc17368ecb7a74d386c64e2166fb6baff66",
    "support"
   ],
   "webgpu/suites/cts/validation/render_pass_descriptor.spec.js": [
@@ -516718,7 +518195,7 @@
    "support"
   ],
   "webgpu/suites/cts/validation/setVertexBuffer.spec.js": [
-   "1df40173abe0eab97fe384b12df94f0e4ec03c3b",
+   "0f47e7324eb06aeb8d52c6e744932884ba2064ee",
    "support"
   ],
   "webgpu/suites/cts/validation/setViewport.spec.js": [
@@ -516730,7 +518207,7 @@
    "support"
   ],
   "webgpu/suites/cts/validation/vertex_input.spec.js": [
-   "951c9ead3cfc53569bbcfa322252edef3b672609",
+   "c5978025c9a777fd6e275fe7d2520092d3f39c8c",
    "support"
   ],
   "webmessaging/Channel_postMessage_Blob.htm": [
@@ -525442,7 +526919,7 @@
    "support"
   ],
   "wpt.py": [
-   "0736186c5d813f04a83fdd117974a9e1513dbff1",
+   "c65e1ed2c6cde4d3abd9e9a771f02542398fec49",
    "support"
   ],
   "x-frame-options/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt
new file mode 100644
index 0000000..42e1de3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html
index 08114d7..b97701b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html
@@ -1,4 +1,5 @@
 <!doctype html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>Overflow areas are updated when dynamically changed to overflow: clip</title>
 <link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip">
@@ -30,7 +31,10 @@
 onload = function() {
   let target = document.getElementById("target");
   window.unused = target.getBoundingClientRect(); // Update layout
-  target.style.overflow = "-moz-hidden-unscrollable";
-  target.style.overflow = "clip";
+  requestAnimationFrame(() => requestAnimationFrame(() => {
+    target.style.overflow = "-moz-hidden-unscrollable";
+    target.style.overflow = "clip";
+    document.documentElement.removeAttribute("class");
+  }));
 }
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html
index f15adc9b..6975e81 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html
@@ -6,6 +6,7 @@
 <meta name="flags" content="">
 <link rel="match" href="reference/overflow-wrap-min-content-size-001-ref.html">
 <meta name="assert" content="Soft wrap opportunities introduced by overflow-wrap:anywhere **are** considered when calculating min-content intrinsic sizes.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
 <style>
 table {
   font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html
index 1fe8f94..16161ec 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html
@@ -6,6 +6,7 @@
 <meta name="flags" content="ahem">
 <link rel="match" href="reference/overflow-wrap-min-content-size-004-ref.html">
 <meta name="assert" content="Soft wrap opportunities introduced by overflow-wrap:break-word **are not** considered when calculating min-content intrinsic sizes.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
 <style>
 table {
   font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html
index 1c87ab9a..ef5c2e8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html
@@ -2,6 +2,7 @@
 <meta charset="utf-8">
 <title>CSS Text Test reference</title>
 <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
 <style>
 div {
   font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html
index 6639eda..93e22ba 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html
@@ -2,6 +2,7 @@
 <meta charset="utf-8">
 <title>CSS Text Test reference</title>
 <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
 <style>
 div {
   font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html
index ba7009e7..a310e30 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html
@@ -7,6 +7,7 @@
 <meta name="flags" content="">
 <link rel="match" href="../overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html">
 <meta name="assert" content="word-break: break-word should behave as overflow-wrap: anywhere, so breaking opportunities **are** considered when calculating min-content intrinsic sizes.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
 <style>
 div { font: 20px/1 Ahem; }
 table {
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt
deleted file mode 100644
index 2f827d6..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-This is a testharness.js-based test.
-PASS CustomElementRegistry interface must have define as a method
-PASS customElements.define must throw when the element interface is not a constructor
-PASS customElements.define must not throw the constructor is HTMLElement
-PASS customElements.define must throw with an invalid name
-PASS customElements.define must throw when there is already a custom element of the same name
-PASS customElements.define must throw a NotSupportedError when there is already a custom element with the same class
-PASS customElements.define must throw a NotSupportedError when element definition is running flag is set
-PASS customElements.define must check IsConstructor on the constructor before checking the element definition is running flag
-PASS customElements.define must validate the custom element name before checking the element definition is running flag
-PASS customElements.define unset the element definition is running flag before upgrading custom elements
-FAIL customElements.define must not throw when defining another custom element in a different global object during Get(constructor, "prototype") Failed to execute 'define' on 'CustomElementRegistry': the name "another-custom-element" has already been used with this registry
-PASS Custom Elements: CustomElementRegistry interface
-FAIL customElements.define must get "prototype" property of the constructor assert_array_equals: lengths differ, expected 1 got 3
-PASS customElements.define must rethrow an exception thrown while getting "prototype" property of the constructor
-PASS customElements.define must throw when "prototype" property of the constructor is not an object
-PASS customElements.define must get callbacks of the constructor prototype
-PASS customElements.define must rethrow an exception thrown while getting callbacks on the constructor prototype
-PASS customElements.define must rethrow an exception thrown while converting a callback value to Function callback type
-PASS customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present
-PASS customElements.define must rethrow an exception thrown while getting observedAttributes on the constructor prototype
-PASS customElements.define must rethrow an exception thrown while converting the value of observedAttributes to sequence<DOMString>
-PASS customElements.define must rethrow an exception thrown while iterating over observedAttributes to sequence<DOMString>
-PASS customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on observedAttributes
-PASS customElements.define must not throw even if "observedAttributes" fails to convert if "attributeChangedCallback" is not defined
-PASS customElements.define must rethrow an exception thrown while getting disabledFeatures on the constructor prototype
-PASS customElements.define must rethrow an exception thrown while converting the value of disabledFeatures to sequence<DOMString>
-PASS customElements.define must rethrow an exception thrown while iterating over disabledFeatures to sequence<DOMString>
-PASS customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on disabledFeatures
-PASS customElements.define must rethrow an exception thrown while getting formAssociated on the constructor prototype
-PASS customElements.define must get four additional callbacks on the prototype if formAssociated is converted to true
-PASS customElements.define must rethrow an exception thrown while getting additional formAssociated callbacks on the constructor prototype
-PASS customElements.define must define an instantiatable custom element
-PASS customElements.define must upgrade elements in the shadow-including tree order
-PASS CustomElementRegistry interface must have get as a method
-PASS customElements.get must return undefined when the registry does not contain an entry with the given name
-PASS customElements.get must return undefined when the registry does not contain an entry with the given name even if the name was not a valid custom element name
-PASS customElements.get return the constructor of the entry with the given name when there is a matching entry.
-PASS customElements.whenDefined must return a promise for a valid custom element name
-PASS customElements.whenDefined must return the same promise each time invoked for a valid custom element name which has not been defined
-PASS customElements.whenDefined must return an unresolved promise when the registry does not contain the entry with the given name
-PASS customElements.whenDefined must return a rejected promise when the given name is not a valid custom element name
-PASS customElements.whenDefined must return a resolved promise when the registry contains the entry with the given name
-PASS customElements.whenDefined must return a new resolved promise each time invoked when the registry contains the entry with the given name
-PASS A promise returned by customElements.whenDefined must be resolved by "define"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html
index 368044df..c288e82 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html
@@ -185,12 +185,15 @@
             var proxy = new Proxy(class extends HTMLElement { }, {
                 get: function (target, name) {
                     calls.push(name);
-                    iframe.contentWindow.customElements.define('another-custom-element', InnerCustomElement);
+                    if (name === "prototype") {
+                        iframe.contentWindow.customElements.define('another-custom-element', InnerCustomElement);
+                    }
                     return target[name];
                 }
             })
             customElements.define('element-with-inner-element-define', proxy);
-            assert_array_equals(calls, ['prototype'], 'customElements.define must get "prototype"');
+            assert_array_equals(calls, ['prototype', 'disabledFeatures', 'formAssociated'],
+                                'customElements.define must get "prototype", "disabledFeatures", and "formAssociated" on the constructor');
             assert_true(iframe.contentDocument.createElement('another-custom-element') instanceof InnerCustomElement);
         });
         document.body.removeChild(iframe);
@@ -226,8 +229,8 @@
         }
     });
     customElements.define('proxy-element', proxy);
-    assert_array_equals(calls, ['prototype']);
-}, 'customElements.define must get "prototype" property of the constructor');
+    assert_array_equals(calls, ['prototype', 'disabledFeatures', 'formAssociated']);
+}, 'customElements.define must get "prototype", "disabledFeatures", and "formAssociated" property of the constructor');
 
 test(function () {
     var proxy = new Proxy(class extends HTMLElement { }, {
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt
index f6bcb6a..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL redirect-https-downgrade Uncaught SyntaxError: Unexpected token 'return'
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt
index 2be08465..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-document on HTML element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt
index 6a1b58d..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-document on SVG element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt
index f735916..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-object on HTML element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt
index e5649930..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-object on SVG element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt
index f57f1a03b..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-symbol on HTML element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt
index 98a13d5..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL graphics-symbol on SVG element Uncaught ReferenceError: ATTAcomm is not defined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt
index 9d1840b5..1bafd5c6 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt
@@ -7,5 +7,6 @@
 FAIL Same-site popup with coop unsafe-inherit without coep assert_equals: expected "" but got "same-site-popup-with-coop-unsafe-inherit-without-coep"
 FAIL Same-origin popup without coep assert_equals: expected "" but got "popup-without-coep"
 FAIL Same-site popup without coep assert_equals: expected "" but got "same-site-popup-without-coep"
+FAIL Bonus: window.crossOriginIsolated assert_true: expected true got undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html
index 1c04ed30..64994cdf 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html
@@ -40,4 +40,8 @@
     coop_coep_test(t, SAME_SITE, variant.coop, variant.coep, `same-site-${variant.title.replace(/ /g,"-")}`, false);
   }, `Same-site ${variant.title}`);
 });
+
+test(() => {
+  assert_true(window.crossOriginIsolated);
+}, "Bonus: window.crossOriginIsolated");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt
new file mode 100644
index 0000000..9cd8ef4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+PASS Cross-Origin-Opener-Policy only works over secure contexts
+FAIL Bonus: window.crossOriginIsolated assert_false: expected false got undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html
index da9efdc..014ba1f 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html
@@ -15,4 +15,8 @@
     t.done();
   }, 500);
 }, "Cross-Origin-Opener-Policy only works over secure contexts");
+
+test(() => {
+  assert_false(window.crossOriginIsolated);
+}, "Bonus: window.crossOriginIsolated");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.html b/third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.html
rename to third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt
index 7b70ea2..d6e67e0 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
 FAIL postMessaging to a dedicated sub-worker allows them to see each others' modifications Worker is not defined
+FAIL Bonus: self.crossOriginIsolated assert_true: expected true got undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt
new file mode 100644
index 0000000..0c7bb4b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+PASS postMessaging to a dedicated sub-worker allows them to see each others' modifications
+FAIL Bonus: self.crossOriginIsolated assert_true: expected true got undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt
index 03e29e36..3d3e7c3 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt
@@ -2,5 +2,6 @@
 FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw
 FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw
 FAIL SharedArrayBuffer over postMessage() without COOP+COEP assert_throws: function "() => self.postMessage(sab)" did not throw
+FAIL Bonus: self.crossOriginIsolated assert_false: expected false got undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js
index 96276d7..a755865 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js
@@ -16,3 +16,7 @@
     assert_throws("DataCloneError", () => self.postMessage(sab));
   }, "SharedArrayBuffer over postMessage() without COOP+COEP");
 }
+
+test(() => {
+  assert_false(self.crossOriginIsolated);
+}, "Bonus: self.crossOriginIsolated");
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt
index 6600416..35419f6 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw
 FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw
+FAIL Bonus: self.crossOriginIsolated assert_false: expected false got undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js
index 9befc90..ffc3708 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js
@@ -7,4 +7,8 @@
   return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker");
 }, "postMessaging to a dedicated sub-worker allows them to see each others' modifications");
 
+test(() => {
+  assert_true(self.crossOriginIsolated);
+}, "Bonus: self.crossOriginIsolated");
+
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
index 49cfaff..c960d0d 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
@@ -7,7 +7,7 @@
 PASS JS-engine-created TypeError (cross-site iframe)
 PASS web API-created TypeError (worker)
 PASS web API-created TypeError (cross-site iframe)
-FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1914:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
-FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1914:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
+FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
+FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md b/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md
new file mode 100644
index 0000000..10ae3e5f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md
@@ -0,0 +1 @@
+`self.crossOriginIsolated` is tested in `html/cross-origin-opener-policy/coep.https.html`, `html/cross-origin-opener-policy/no-https.html`, `html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js`, and `html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js`.
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt
index 1765dd9..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Uncaught exception Uncaught Error: error outside any setup or test
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt
index 3a828c8..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Unhandled rejection Unhandled rejection: error outside any setup or test
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini
index 0bcdd374..40a58e41 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini
@@ -1,4 +1,2 @@
 [uncaught-exception.html]
-  [Uncaught exception]
-    expected: FAIL
-
+  expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini
index 39773df..da4fe27 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini
@@ -1,4 +1,2 @@
 [unhandled-rejection.html]
-  [Unhandled rejection]
-    expected: FAIL
-
+  expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini
index c3431d6..ca095a18 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini
@@ -1,7 +1,6 @@
 [context.any.sharedworker.html]
-  [context]
-    expected:
-      if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
+  expected:
+    if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
 
 [context.any.serviceworker.html]
   [context]
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini
index 8db9536..2338765 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini
@@ -1,6 +1,5 @@
 [order-of-metas.any.sharedworker.html]
-  [foo]
-    expected:
-      if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
+  expected:
+    if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
 
 
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini
index 5f5ed991..5b24c942 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini
@@ -1,7 +1,6 @@
 [secure-context.https.any.sharedworker.html]
-  [secure-context]
-    expected:
-      if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
+  expected:
+    if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
 
 [secure-context.https.any.serviceworker.html]
   [secure-context]
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini
index e2a7b55..8cbb5f7 100644
--- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini
@@ -1,6 +1,5 @@
 [title.any.sharedworker.html]
-  [foobar]
-    expected:
-      if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
+  expected:
+    if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
 
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl
index 6fd172c..0d5d40ba 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl
@@ -92,11 +92,12 @@
 
 [Exposed=Window]
 interface KeyframeEffect : AnimationEffect {
-    constructor((Element or CSSPseudoElement)? target,
+    constructor(Element? target,
                 object? keyframes,
                 optional (unrestricted double or KeyframeEffectOptions) options = {});
     constructor(KeyframeEffect source);
-    attribute (Element or CSSPseudoElement)? target;
+    attribute Element? target;
+    attribute CSSOMString? pseudoElement;
     attribute CompositeOperation             composite;
     sequence<object> getKeyframes();
     void             setKeyframes(object? keyframes);
@@ -122,7 +123,8 @@
 };
 
 dictionary KeyframeEffectOptions : EffectTiming {
-    CompositeOperation          composite = "replace";
+    CompositeOperation composite = "replace";
+    CSSOMString?       pseudoElement = null;
 };
 
 enum CompositeOperation { "replace", "add", "accumulate" };
@@ -153,8 +155,6 @@
 
 Element includes Animatable;
 
-CSSPseudoElement includes Animatable;
-
 [Exposed=Window]
 interface AnimationPlaybackEvent : Event {
     constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {});
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl
index f433f23..a29107f 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into reffy-reports
 // (https://github.com/tidoust/reffy-reports)
-// Source: Web Share API - Level 1 (https://w3c.github.io/web-share/)
+// Source: Web Share API (https://w3c.github.io/web-share/)
 
 partial interface Navigator {
   [SecureContext] Promise<void> share(optional ShareData data = {});
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
index 2b82304..3e58254b 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
@@ -78,6 +78,8 @@
  double framesPerSecond;
  unsigned long long qpSum;
  double totalDecodeTime;
+ double totalInterFrameDelay;
+ double totalSquaredInterFrameDelay;
  boolean voiceActivityFlag;
  DOMHighResTimeStamp lastPacketReceivedTimestamp;
  double averageRtcpInterval;
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html
index 79100ab5..790f73a 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html
@@ -12,6 +12,7 @@
 the success callback in getUserMedia can be properly assigned to a video element
 via the <code>srcObject</code> attribute.</p>
 
+<audio id="aud"></audio>
 <video id="vid"></video>
 
 <div id='log'></div>
@@ -21,6 +22,11 @@
 'use strict';
 const vid = document.getElementById("vid");
 
+function queueTask(f) {
+  window.onmessage = f;
+  window.postMessage("hi");
+}
+
 promise_test(async t => {
   const stream = await navigator.mediaDevices.getUserMedia({video: true});
   t.add_cleanup(() => {
@@ -307,6 +313,112 @@
   // otherwise the media element sets currentTime to 0 without ending.
   await new Promise(r => vid.onended = r);
 }, "Tests that the loop attribute has no effect on a media element with an assigned MediaStream");
+
+promise_test(async t => {
+  const stream = await navigator.mediaDevices.getUserMedia({video: true});
+  t.add_cleanup(() => { vid.srcObject = null; });
+  vid.srcObject = stream;
+
+  await vid.play();
+
+  for (const track of stream.getTracks()) {
+    track.stop();
+  }
+
+  assert_false(stream.active, "MediaStream becomes inactive with only ended tracks");
+  assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)");
+
+  await Promise.resolve();
+  assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)");
+
+  let ended = false;
+  vid.onended = () => ended = true;
+  await new Promise(r => queueTask(r));
+
+  assert_true(vid.ended, "HTMLMediaElement becomes ended asynchronously when its MediaStream provider becomes inactive");
+  assert_true(ended, "HTMLMediaElement fires the ended event asynchronously when its MediaStream provider becomes inactive");
+}, "Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through tracks ending");
+
+promise_test(async t => {
+  const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+  t.add_cleanup(() => {
+    aud.srcObject = null;
+    stream.getTracks().forEach(track => track.stop());
+  });
+  aud.srcObject = stream;
+
+  await aud.play();
+
+  for (const track of stream.getAudioTracks()) {
+    track.stop();
+  }
+
+  assert_true(stream.active, "MediaStream is still active with a live video track");
+  assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)");
+
+  await Promise.resolve();
+  assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)");
+
+  let ended = false;
+  aud.onended = () => ended = true;
+  await new Promise(r => queueTask(r));
+
+  assert_true(aud.ended, "HTMLAudioElement becomes ended asynchronously when its MediaStream provider becomes inaudible");
+  assert_true(ended, "HTMLAudioElement fires the ended event asynchronously when its MediaStream provider becomes inaudible");
+}, "Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through audio tracks ending");
+
+promise_test(async t => {
+  const stream = await navigator.mediaDevices.getUserMedia({video: true});
+  t.add_cleanup(() => { vid.srcObject = null; });
+  vid.srcObject = stream;
+
+  await vid.play();
+
+  for (const track of stream.getTracks()) {
+    stream.removeTrack(track);
+  }
+
+  assert_false(stream.active, "MediaStream becomes inactive with no tracks");
+  assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)");
+
+  await Promise.resolve();
+  assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)");
+
+  let ended = false;
+  vid.onended = () => ended = true;
+  await new Promise(r => queueTask(r));
+
+  assert_true(vid.ended, "HTMLMediaElement becomes ended asynchronously when its MediaStream provider becomes inactive");
+  assert_true(ended, "HTMLMediaElement fires the ended event asynchronously when its MediaStream provider becomes inactive");
+}, "Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through track removal");
+
+promise_test(async t => {
+  const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+  t.add_cleanup(() => {
+    aud.srcObject = null;
+    stream.getTracks().forEach(track => track.stop());
+  });
+  aud.srcObject = stream;
+
+  await aud.play();
+
+  for (const track of stream.getAudioTracks()) {
+    stream.removeTrack(track);
+  }
+
+  assert_true(stream.active, "MediaStream is still active with a live video track");
+  assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)");
+
+  await Promise.resolve();
+  assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)");
+
+  let ended = false;
+  aud.onended = () => ended = true;
+  await new Promise(r => queueTask(r));
+
+  assert_true(aud.ended, "HTMLAudioElement becomes ended asynchronously when its MediaStream provider becomes inaudible");
+  assert_true(ended, "HTMLAudioElement fires the ended event asynchronously when its MediaStream provider becomes inaudible");
+}, "Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through track removal");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt
index f30628b..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for PaymentRequestEvent.changePaymentMethod() Unhandled rejection: Not allowed to install this payment handler
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt
index de7d406..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for PaymentRequestEvent.changeShippingAddress() Unhandled rejection: Not allowed to install this payment handler
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt
index 4b23059b..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for PaymentRequestEvent.changeShippingOption() Unhandled rejection: Not allowed to install this payment handler
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt
index a00a329..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for PaymentRequestEvent Unhandled rejection: Not allowed to install this payment handler
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt
index 149709f31..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for Delegation of shipping and contact collection to PH Unhandled rejection: Not allowed to install this payment handler
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt
index f04ac0a..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Test for PaymentRequest.show(optional promise) method Uncaught TypeError: Cannot set property 'click' of undefined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt
index 0f09114..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Tests for PaymentRequest.canMakePayment() method Uncaught TypeError: Cannot set property 'click' of undefined
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js
index bed28566..7fb1c0c 100644
--- a/third_party/blink/web_tests/external/wpt/resources/testharness.js
+++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -792,7 +792,10 @@
 
     function done() {
         if (tests.tests.length === 0) {
-            tests.set_file_is_test();
+            tests.status.status = tests.status.ERROR;
+            tests.status.message = "done() was called without first defining any tests";
+            tests.complete();
+            return;
         }
         if (tests.file_is_test) {
             // file is test files never have asynchronous cleanup logic,
@@ -3379,9 +3382,6 @@
      */
     function assert(expected_true, function_name, description, error, substitutions)
     {
-        if (tests.tests.length === 0) {
-            tests.set_file_is_test();
-        }
         if (expected_true !== true) {
             var msg = make_message(function_name, description,
                                    error, substitutions);
@@ -3672,10 +3672,6 @@
 
     if (global_scope.addEventListener) {
         var error_handler = function(message, stack) {
-            if (tests.tests.length === 0 && !tests.allow_uncaught_exception) {
-                tests.set_file_is_test();
-            }
-
             if (tests.file_is_test) {
                 var test = tests.tests[0];
                 if (test.phase >= test.phases.HAS_RESULT) {
@@ -3710,15 +3706,17 @@
         }, false);
 
         addEventListener("unhandledrejection", function(e) {
-            var reason;
-            if (e.reason) {
-                reason  = e.reason.message ? e.reason.message : e.reason;
+            var message;
+            if (e.reason && e.reason.message) {
+                message = "Unhandled rejection: " + e.reason.message;
             } else {
-                reason = e;
+                message = "Unhandled rejection";
             }
-            var message = "Unhandled rejection: " + reason;
-            // There's no stack for unhandled rejections.
-            error_handler(message);
+            var stack;
+            if (e.reason && e.reason.stack) {
+                stack = e.reason.stack;
+            }
+            error_handler(message, stack);
         }, false);
     }
 
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html
index babfe3c..c559da1 100644
--- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html
+++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html
@@ -5,14 +5,18 @@
 <script src="/resources/testdriver-vendor.js"></script>
 <body>
 <script>
-async_test(t => {
-  test_driver.bless('speechSynthesis.speak', t.step_func(() => {
-    const utter = new SpeechSynthesisUtterance('test');
-    utter.onerror = t.unreached_func('error event');
-    speechSynthesis.speak(utter);
-    utter.onstart = t.step_func(() => {
-      utter.onend = t.step_func_done();
-    });
-  }));
+async function runStartEndTest(t, utterance) {
+  const eventWatcher = new EventWatcher(t, utterance, ['start', 'end', 'error']);
+  await test_driver.bless('speechSynthesis.speak',
+      () => speechSynthesis.speak(utterance));
+  await eventWatcher.wait_for(['start', 'end']);
+}
+promise_test(async (t) => {
+  const utterance = new SpeechSynthesisUtterance();
+  await runStartEndTest(t, utterance);
+}, 'speechSynthesis.speak() fires start and end events with empty utterance');
+promise_test(async (t) => {
+  const utterance = new SpeechSynthesisUtterance('test');
+  await runStartEndTest(t, utterance);
 }, 'speechSynthesis.speak() fires start and end events');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt
index 8ec519e1..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL construct-byob-request Uncaught RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
index 6e0da30..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL construct-byob-request Unhandled rejection: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/streams/readable-byte-streams/does/not/exist') with script ('https://web-platform.test:8444/streams/readable-byte-streams/construct-byob-request.any.worker.js'): ServiceWorker script evaluation failed
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt
index 8ec519e1..42e1de3 100644
--- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL construct-byob-request Uncaught RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
index d8a6c898..60775f82 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
@@ -5,4 +5,4 @@
 pillow==6.2.1
 urllib3[secure]==1.25.6
 requests==2.22.0
-six==1.12.0
+six==1.13.0
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt
new file mode 100644
index 0000000..38f05e8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt
@@ -0,0 +1,147 @@
+This is a testharness.js-based test.
+Found 143 tests; 131 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS idl_test validation
+PASS Partial interface Document: original interface defined
+PASS Partial interface Document: member names are unique
+PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined
+PASS Partial interface mixin DocumentOrShadowRoot: member names are unique
+PASS Partial interface Document[2]: member names are unique
+PASS Partial interface Document[3]: member names are unique
+PASS Element includes Animatable: member names are unique
+PASS Element includes ParentNode: member names are unique
+PASS Element includes NonDocumentTypeChildNode: member names are unique
+PASS Element includes ChildNode: member names are unique
+PASS Element includes Slotable: member names are unique
+PASS Document includes NonElementParentNode: member names are unique
+PASS Document includes DocumentOrShadowRoot: member names are unique
+PASS Document includes ParentNode: member names are unique
+PASS Document includes XPathEvaluatorBase: member names are unique
+PASS Document includes GlobalEventHandlers: member names are unique
+PASS Document includes DocumentAndElementEventHandlers: member names are unique
+PASS DocumentFragment includes NonElementParentNode: member names are unique
+PASS DocumentFragment includes ParentNode: member names are unique
+PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique
+PASS AnimationTimeline interface: existence and properties of interface object
+PASS AnimationTimeline interface object length
+PASS AnimationTimeline interface object name
+PASS AnimationTimeline interface: existence and properties of interface prototype object
+PASS AnimationTimeline interface: existence and properties of interface prototype object's "constructor" property
+PASS AnimationTimeline interface: existence and properties of interface prototype object's @@unscopables property
+PASS AnimationTimeline interface: attribute currentTime
+PASS DocumentTimeline interface: existence and properties of interface object
+PASS DocumentTimeline interface object length
+PASS DocumentTimeline interface object name
+PASS DocumentTimeline interface: existence and properties of interface prototype object
+PASS DocumentTimeline interface: existence and properties of interface prototype object's "constructor" property
+PASS DocumentTimeline interface: existence and properties of interface prototype object's @@unscopables property
+PASS DocumentTimeline must be primary interface of document.timeline
+PASS Stringification of document.timeline
+PASS AnimationTimeline interface: document.timeline must inherit property "currentTime" with the proper type
+PASS Animation interface: existence and properties of interface object
+PASS Animation interface object length
+PASS Animation interface object name
+PASS Animation interface: existence and properties of interface prototype object
+PASS Animation interface: existence and properties of interface prototype object's "constructor" property
+PASS Animation interface: existence and properties of interface prototype object's @@unscopables property
+PASS Animation interface: attribute id
+PASS Animation interface: attribute effect
+PASS Animation interface: attribute timeline
+PASS Animation interface: attribute startTime
+PASS Animation interface: attribute currentTime
+PASS Animation interface: attribute playbackRate
+PASS Animation interface: attribute playState
+FAIL Animation interface: attribute replaceState assert_true: The prototype object must have a property "replaceState" expected true got false
+PASS Animation interface: attribute pending
+PASS Animation interface: attribute ready
+PASS Animation interface: attribute finished
+PASS Animation interface: attribute onfinish
+PASS Animation interface: attribute oncancel
+FAIL Animation interface: attribute onremove assert_true: The prototype object must have a property "onremove" expected true got false
+PASS Animation interface: operation cancel()
+PASS Animation interface: operation finish()
+PASS Animation interface: operation play()
+PASS Animation interface: operation pause()
+PASS Animation interface: operation updatePlaybackRate(double)
+PASS Animation interface: operation reverse()
+FAIL Animation interface: operation persist() assert_own_property: interface prototype object missing non-static operation expected property "persist" missing
+FAIL Animation interface: operation commitStyles() assert_own_property: interface prototype object missing non-static operation expected property "commitStyles" missing
+PASS Animation must be primary interface of new Animation()
+PASS Stringification of new Animation()
+PASS Animation interface: new Animation() must inherit property "id" with the proper type
+PASS Animation interface: new Animation() must inherit property "effect" with the proper type
+PASS Animation interface: new Animation() must inherit property "timeline" with the proper type
+PASS Animation interface: new Animation() must inherit property "startTime" with the proper type
+PASS Animation interface: new Animation() must inherit property "currentTime" with the proper type
+PASS Animation interface: new Animation() must inherit property "playbackRate" with the proper type
+PASS Animation interface: new Animation() must inherit property "playState" with the proper type
+FAIL Animation interface: new Animation() must inherit property "replaceState" with the proper type assert_inherits: property "replaceState" not found in prototype chain
+PASS Animation interface: new Animation() must inherit property "pending" with the proper type
+PASS Animation interface: new Animation() must inherit property "ready" with the proper type
+PASS Animation interface: new Animation() must inherit property "finished" with the proper type
+PASS Animation interface: new Animation() must inherit property "onfinish" with the proper type
+PASS Animation interface: new Animation() must inherit property "oncancel" with the proper type
+FAIL Animation interface: new Animation() must inherit property "onremove" with the proper type assert_inherits: property "onremove" not found in prototype chain
+PASS Animation interface: new Animation() must inherit property "cancel()" with the proper type
+PASS Animation interface: new Animation() must inherit property "finish()" with the proper type
+PASS Animation interface: new Animation() must inherit property "play()" with the proper type
+PASS Animation interface: new Animation() must inherit property "pause()" with the proper type
+PASS Animation interface: new Animation() must inherit property "updatePlaybackRate(double)" with the proper type
+PASS Animation interface: calling updatePlaybackRate(double) on new Animation() with too few arguments must throw TypeError
+PASS Animation interface: new Animation() must inherit property "reverse()" with the proper type
+FAIL Animation interface: new Animation() must inherit property "persist()" with the proper type assert_inherits: property "persist" not found in prototype chain
+FAIL Animation interface: new Animation() must inherit property "commitStyles()" with the proper type assert_inherits: property "commitStyles" not found in prototype chain
+PASS AnimationEffect interface: existence and properties of interface object
+PASS AnimationEffect interface object length
+PASS AnimationEffect interface object name
+PASS AnimationEffect interface: existence and properties of interface prototype object
+PASS AnimationEffect interface: existence and properties of interface prototype object's "constructor" property
+PASS AnimationEffect interface: existence and properties of interface prototype object's @@unscopables property
+PASS AnimationEffect interface: operation getTiming()
+PASS AnimationEffect interface: operation getComputedTiming()
+PASS AnimationEffect interface: operation updateTiming(OptionalEffectTiming)
+PASS KeyframeEffect interface: existence and properties of interface object
+PASS KeyframeEffect interface object length
+PASS KeyframeEffect interface object name
+PASS KeyframeEffect interface: existence and properties of interface prototype object
+PASS KeyframeEffect interface: existence and properties of interface prototype object's "constructor" property
+PASS KeyframeEffect interface: existence and properties of interface prototype object's @@unscopables property
+PASS KeyframeEffect interface: attribute target
+FAIL KeyframeEffect interface: attribute pseudoElement assert_true: The prototype object must have a property "pseudoElement" expected true got false
+PASS KeyframeEffect interface: attribute composite
+PASS KeyframeEffect interface: operation getKeyframes()
+PASS KeyframeEffect interface: operation setKeyframes(object)
+PASS KeyframeEffect must be primary interface of new KeyframeEffect(null, null)
+PASS Stringification of new KeyframeEffect(null, null)
+PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "target" with the proper type
+FAIL KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "pseudoElement" with the proper type assert_inherits: property "pseudoElement" not found in prototype chain
+PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "composite" with the proper type
+PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "getKeyframes()" with the proper type
+PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "setKeyframes(object)" with the proper type
+PASS KeyframeEffect interface: calling setKeyframes(object) on new KeyframeEffect(null, null) with too few arguments must throw TypeError
+PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "getTiming()" with the proper type
+PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "getComputedTiming()" with the proper type
+PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "updateTiming(OptionalEffectTiming)" with the proper type
+PASS AnimationEffect interface: calling updateTiming(OptionalEffectTiming) on new KeyframeEffect(null, null) with too few arguments must throw TypeError
+PASS AnimationPlaybackEvent interface: existence and properties of interface object
+PASS AnimationPlaybackEvent interface object length
+PASS AnimationPlaybackEvent interface object name
+PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object
+PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS AnimationPlaybackEvent interface: attribute currentTime
+PASS AnimationPlaybackEvent interface: attribute timelineTime
+PASS AnimationPlaybackEvent must be primary interface of new AnimationPlaybackEvent("cancel")
+PASS Stringification of new AnimationPlaybackEvent("cancel")
+PASS AnimationPlaybackEvent interface: new AnimationPlaybackEvent("cancel") must inherit property "currentTime" with the proper type
+PASS AnimationPlaybackEvent interface: new AnimationPlaybackEvent("cancel") must inherit property "timelineTime" with the proper type
+PASS Document interface: attribute timeline
+PASS Document interface: operation getAnimations()
+PASS Document interface: document must inherit property "timeline" with the proper type
+PASS Document interface: document must inherit property "getAnimations()" with the proper type
+FAIL ShadowRoot interface: operation getAnimations() assert_own_property: interface prototype object missing non-static operation expected property "getAnimations" missing
+FAIL ShadowRoot interface: shadowRoot must inherit property "getAnimations()" with the proper type assert_inherits: property "getAnimations" not found in prototype chain
+PASS Element interface: operation animate(object, [object Object],[object Object])
+PASS Element interface: operation getAnimations(GetAnimationsOptions)
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js
new file mode 100644
index 0000000..c320162
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js
@@ -0,0 +1,20 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+'use strict';
+
+idl_test(
+  ['web-animations'],
+  ['dom', 'html'],
+  idl_array => {
+    idl_array.add_objects({
+      Animation: ['new Animation()'],
+      AnimationPlaybackEvent: ['new AnimationPlaybackEvent("cancel")'],
+      Document: ['document'],
+      DocumentTimeline: ['document.timeline'],
+      KeyframeEffect: ['new KeyframeEffect(null, null)'],
+      ShadowRoot: ['shadowRoot'],
+    });
+    self.shadowRoot = document.createElement("div").attachShadow({mode: "open"});
+  }
+);
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js
deleted file mode 100644
index 14b8395..0000000
--- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// META: script=/resources/WebIDLParser.js
-// META: script=/resources/idlharness.js
-
-// https://w3c.github.io/web-animations/#animation
-
-'use strict';
-
-promise_test(async () => {
-  const srcs = ['web-animations', 'dom', 'html'];
-  const [idl, dom, html] = await Promise.all(
-      srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text())));
-
-  const idlArray = new IdlArray();
-  idlArray.add_idls(idl, {only: ['Animation', 'AnimationPlayState']});
-  idlArray.add_dependency_idls(idl);
-  idlArray.add_dependency_idls(dom);
-  idlArray.add_dependency_idls(html);
-  idlArray.add_untested_idls('interface CSSPseudoElement {};');
-  idlArray.add_objects( { Animation: ['new Animation()'] } );
-  idlArray.test();
-}, 'Animation interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js
deleted file mode 100644
index 5124e50..0000000
--- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// META: script=/resources/WebIDLParser.js
-// META: script=/resources/idlharness.js
-
-// https://w3c.github.io/web-animations/#animationplaybackevent
-
-'use strict';
-
-promise_test(async () => {
-  const srcs = ['web-animations', 'dom'];
-  const [idl, dom] = await Promise.all(
-      srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text())));
-
-  const idlArray = new IdlArray();
-  idlArray.add_idls(idl, {
-    only: [
-      'AnimationPlaybackEventInit',
-      'AnimationPlaybackEvent',
-    ]
-  });
-  idlArray.add_dependency_idls(dom);
-  idlArray.add_objects({
-    AnimationPlaybackEvent: ['new AnimationPlaybackEvent("cancel")'],
-  });
-
-  idlArray.test();
-}, 'AnimationPlaybackEvent interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js
deleted file mode 100644
index 395d133..0000000
--- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// META: script=/resources/WebIDLParser.js
-// META: script=/resources/idlharness.js
-
-// https://w3c.github.io/web-animations/#documenttimeline
-
-'use strict';
-
-promise_test(async () => {
-  const text = await fetch('/interfaces/web-animations.idl').then(r => r.text());
-  const idlArray = new IdlArray();
-  idlArray.add_idls(text, {
-    only: [
-      'AnimationTimeline',
-      'DocumentTimelineOptions',
-      'DocumentTimeline',
-    ]
-  });
-  idlArray.add_objects({ DocumentTimeline: ['document.timeline'] });
-
-  idlArray.test();
-  done();
-}, 'DocumentTimeline interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js
deleted file mode 100644
index 22548861..0000000
--- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// META: script=/resources/WebIDLParser.js
-// META: script=/resources/idlharness.js
-
-// https://w3c.github.io/web-animations/#keyframeeffect
-
-'use strict';
-
-promise_test(async () => {
-  const srcs = ['web-animations', 'html'];
-  const [idl, html] = await Promise.all(
-      srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text())));
-
-  const idlArray = new IdlArray();
-  idlArray.add_idls(idl, {
-    only: [
-      'IterationCompositeOperation',
-      'CompositeOperation',
-      'KeyframeEffectOptions',
-      'KeyframeEffect',
-    ]
-  });
-  idlArray.add_untested_idls('interface CSSPseudoElement {};');
-  idlArray.add_dependency_idls(idl);
-  idlArray.add_dependency_idls(html);
-  idlArray.add_objects({
-    KeyframeEffect: ['new KeyframeEffect(null, null)'],
-  });
-
-  idlArray.test();
-  done();
-}, 'KeyframeEffect interface.');
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb b/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb
deleted file mode 100755
index a0784753..0000000
--- a/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env ruby
-require 'nokogiri'
-
-def base_dir
-  File.dirname(__FILE__)
-end
-
-def output_directory
-  File.join(base_dir, 'idl')
-end
-
-def specification
-  file = File.open(File.join(base_dir, 'specification.html'))
-  doc = Nokogiri::XML(file)
-  file.close
-  doc
-end
-
-def write_node_inner_text_to_file(filename, node)
-  File.open(filename, 'w') { |file| file.write(node.inner_text.strip) }
-  puts "Wrote: #{filename}"
-end
-
-def load_idl(id)
-  file = File.join(output_directory, id)
-  return false if !File.exist?(file)
-  File.read(file)
-end
-
-# Parse the specification writing each block of idl to its own file
-specification.css(".idl-code").each do |idl_block|
-  id = idl_block["id"]
-  write_node_inner_text_to_file(File.join(output_directory, id), idl_block) if id
-end
-
-# Update the idl in the pre blocks for each idl test
-idl_test_files = [
-  File.join(base_dir, 'the-audio-api', 'the-gainnode-interface', 'idl-test.html'),
-  File.join(base_dir, 'the-audio-api', 'the-audiodestinationnode-interface', 'idl-test.html'),
-  File.join(base_dir, 'the-audio-api', 'the-delaynode-interface', 'idl-test.html'),
-  File.join(base_dir, 'the-audio-api', 'the-audiobuffer-interface', 'idl-test.html'),
-]
-
-idl_test_files.each do |fn|
-  file = File.open(fn)
-  doc = Nokogiri::HTML(file)
-  file.close
-
-  doc.css('pre').each do |node|
-    node_id = node["id"]
-    if idl = load_idl(node_id)
-      node.content = idl
-    end
-  end
-
-  File.open(fn, 'w') { |file| file.write(doc.to_html)}
-end
diff --git a/third_party/blink/web_tests/external/wpt/wpt.py b/third_party/blink/web_tests/external/wpt/wpt.py
index 0736186c..c65e1ed2c 100644
--- a/third_party/blink/web_tests/external/wpt/wpt.py
+++ b/third_party/blink/web_tests/external/wpt/wpt.py
@@ -1 +1,3 @@
-execfile("wpt")
\ No newline at end of file
+# This file exists to allow `python wpt <command>` to work on Windows:
+# https://github.com/web-platform-tests/wpt/pull/6907
+execfile("wpt")
diff --git a/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html b/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html
new file mode 100644
index 0000000..7cead172
--- /dev/null
+++ b/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+.gillsanstest {
+font-family: Gill Sans;
+font-size: 60px;
+}
+</style>
+<p>y needs to be kerned under the T on Gill Sans on Mac for weights under 700. <a href="https://crbug.com/1004945">https://crbug.com/1004945</a></p>
+<div class="gillsanstest" style="font-weight: 300;">TyTo</div>
+<div class="gillsanstest" style="font-weight: 500;">TyTo</div>
+<div class="gillsanstest" style="font-weight: 600;">TyTo</div>
+<div class="gillsanstest" style="font-weight: 700;">TyTo</div>
+<div class="gillsanstest" style="font-weight: 800;">TyTo</div>
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png
index 3869a74..86fd887 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png
deleted file mode 100644
index 2733d4ea..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png
deleted file mode 100644
index f7e90a75..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png
new file mode 100644
index 0000000..c4bf06bb
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png
deleted file mode 100644
index f6e0d7c7..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png
deleted file mode 100644
index d464d81..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png
new file mode 100644
index 0000000..2dc6636
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png b/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png
index 02c8c9e..2733d4ea 100644
--- a/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png
+++ b/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png b/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png
index 458ad41..f7e90a75 100644
--- a/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png
+++ b/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png b/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png
new file mode 100644
index 0000000..1992dabf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png b/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png
index 63c2816..f6e0d7c7 100644
--- a/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md b/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md
deleted file mode 100644
index ac81ca3..0000000
--- a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# virtual/cross-origin-embedder-policy
-
-https://crbug.com/887967
-
-Cross-Origin-Embedder-Policy (COEP)
diff --git a/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md b/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md
new file mode 100644
index 0000000..d051641
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md
@@ -0,0 +1,7 @@
+# virtual/cross-origin-isolation
+
+https://crbug.com/922191
+https://crbug.com/887967
+
+Cross-Origin-Opener-Policy (COOP)
+Cross-Origin-Embedder-Policy (COEP)
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/README.md b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/README.md
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/README.md
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/README.md
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt
rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt
diff --git a/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt b/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt
new file mode 100644
index 0000000..42e1de3
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests
+Harness: the test ran to completion.
+
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 83a2b8e..d7dd216a 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-10-1-72-gb75031a26
-Revision: b75031a26eed8838222ddb3a81bc1672a0e463a8
+Version: VER-2-10-1-73-g3aaae716b
+Revision: 3aaae716b25bd2d3232e279bc05af65cff446dd9
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
 License File: src/docs/FTL.TXT
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn
index 8403845..26553bc 100644
--- a/third_party/harfbuzz-ng/BUILD.gn
+++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -223,7 +223,6 @@
       "src/src/hb-unicode.cc",
       "src/src/hb-unicode.hh",
       "src/src/hb-utf.hh",
-      "src/src/hb-warning.cc",
       "src/src/hb.hh",
     ]
 
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index b636820..6f1fb6a 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,9 +1,9 @@
 Name: harfbuzz-ng
 Short Name: harfbuzz-ng
 URL: http://harfbuzz.org
-Version: 2.6.2-45
-Date: 20191016
-Revision: e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b
+Version: 2.6.4-5
+Date: 20191104
+Revision: 7cde68f10cdf2c3ff77c1d9077475c0fc034c75c
 Security Critical: yes
 License: MIT
 License File: src/COPYING
diff --git a/third_party/zlib/google/compression_utils.cc b/third_party/zlib/google/compression_utils.cc
index d1218d7..9f63a840 100644
--- a/third_party/zlib/google/compression_utils.cc
+++ b/third_party/zlib/google/compression_utils.cc
@@ -42,7 +42,7 @@
   const uLongf input_size = static_cast<uLongf>(input.size());
 
   uLongf compressed_data_size =
-      zlib_internal::GZipExpectedCompressedSize(input_size);
+      zlib_internal::GzipExpectedCompressedSize(input_size);
 
   Bytef* compressed_data;
   if (!base::UncheckedMalloc(compressed_data_size,
@@ -109,7 +109,7 @@
 }
 
 uint32_t GetUncompressedSize(base::StringPiece compressed_data) {
-  return zlib_internal::GetUncompressedSize(
+  return zlib_internal::GetGzipUncompressedSize(
       bit_cast<Bytef*>(compressed_data.data()), compressed_data.length());
 }
 
diff --git a/third_party/zlib/google/compression_utils_portable.cc b/third_party/zlib/google/compression_utils_portable.cc
index f4f36b6..21338b5 100644
--- a/third_party/zlib/google/compression_utils_portable.cc
+++ b/third_party/zlib/google/compression_utils_portable.cc
@@ -28,13 +28,13 @@
 // The expected compressed size is based on the input size factored by
 // internal Zlib constants (e.g. window size, etc) plus the wrapper
 // header size.
-uLongf GZipExpectedCompressedSize(uLongf input_size) {
+uLongf GzipExpectedCompressedSize(uLongf input_size) {
   return kGzipZlibHeaderDifferenceBytes + compressBound(input_size);
 }
 
 // The expected decompressed size is stored in the last
-// 4 bytes of |input| in LE.
-uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length) {
+// 4 bytes of |input| in LE. See https://tools.ietf.org/html/rfc1952#page-5
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length) {
   uint32_t size;
   if (length < sizeof(size))
     return 0;
@@ -47,15 +47,39 @@
 #endif
 }
 
-// This code is taken almost verbatim from third_party/zlib/compress.c. The only
-// difference is deflateInit2() is called which sets the window bits to be > 16.
-// That causes a gzip header to be emitted rather than a zlib header.
+// The number of window bits determines the type of wrapper to use - see
+// https://cs.chromium.org/chromium/src/third_party/zlib/zlib.h?l=566
+inline int ZlibStreamWrapperType(WrapperType type) {
+  if (type == ZLIB)  // zlib DEFLATE stream wrapper
+    return MAX_WBITS;
+  if (type == GZIP)  // gzip DEFLATE stream wrapper
+    return MAX_WBITS + kWindowBitsToGetGzipHeader;
+  if (type == ZRAW)  // no wrapper, use raw DEFLATE
+    return -MAX_WBITS;
+  return 0;
+}
+
 int GzipCompressHelper(Bytef* dest,
                        uLongf* dest_length,
                        const Bytef* source,
                        uLong source_length,
                        void* (*malloc_fn)(size_t),
                        void (*free_fn)(void*)) {
+  return CompressHelper(GZIP, dest, dest_length, source, source_length,
+                        malloc_fn, free_fn);
+}
+
+// This code is taken almost verbatim from third_party/zlib/compress.c. The only
+// difference is deflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+int CompressHelper(WrapperType wrapper_type,
+                   Bytef* dest,
+                   uLongf* dest_length,
+                   const Bytef* source,
+                   uLong source_length,
+                   void* (*malloc_fn)(size_t),
+                   void (*free_fn)(void*)) {
   z_stream stream;
 
   // FIXME(cavalcantii): z_const is not defined as 'const'.
@@ -94,17 +118,21 @@
     stream.opaque = static_cast<voidpf>(0);
   }
 
-  gz_header gzip_header;
-  memset(&gzip_header, 0, sizeof(gzip_header));
   int err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
-                         MAX_WBITS + kWindowBitsToGetGzipHeader,
-                         kZlibMemoryLevel, Z_DEFAULT_STRATEGY);
+                         ZlibStreamWrapperType(wrapper_type), kZlibMemoryLevel,
+                         Z_DEFAULT_STRATEGY);
   if (err != Z_OK)
     return err;
 
-  err = deflateSetHeader(&stream, &gzip_header);
-  if (err != Z_OK)
-    return err;
+  // This has to exist outside of the if statement to prevent it going off the
+  // stack before deflate(), which will use this object.
+  gz_header gzip_header;
+  if (wrapper_type == GZIP) {
+    memset(&gzip_header, 0, sizeof(gzip_header));
+    err = deflateSetHeader(&stream, &gzip_header);
+    if (err != Z_OK)
+      return err;
+  }
 
   err = deflate(&stream, Z_FINISH);
   if (err != Z_STREAM_END) {
@@ -117,13 +145,22 @@
   return err;
 }
 
-// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
-// difference is inflateInit2() is called which sets the window bits to be > 16.
-// That causes a gzip header to be parsed rather than a zlib header.
 int GzipUncompressHelper(Bytef* dest,
                          uLongf* dest_length,
                          const Bytef* source,
                          uLong source_length) {
+  return UncompressHelper(GZIP, dest, dest_length, source, source_length);
+}
+
+// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
+// difference is inflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+int UncompressHelper(WrapperType wrapper_type,
+                     Bytef* dest,
+                     uLongf* dest_length,
+                     const Bytef* source,
+                     uLong source_length) {
   z_stream stream;
 
   // FIXME(cavalcantii): z_const is not defined as 'const'.
@@ -140,7 +177,7 @@
   stream.zalloc = static_cast<alloc_func>(0);
   stream.zfree = static_cast<free_func>(0);
 
-  int err = inflateInit2(&stream, MAX_WBITS + kWindowBitsToGetGzipHeader);
+  int err = inflateInit2(&stream, ZlibStreamWrapperType(wrapper_type));
   if (err != Z_OK)
     return err;
 
diff --git a/third_party/zlib/google/compression_utils_portable.h b/third_party/zlib/google/compression_utils_portable.h
index 5f8b46ed..7c3753b 100644
--- a/third_party/zlib/google/compression_utils_portable.h
+++ b/third_party/zlib/google/compression_utils_portable.h
@@ -17,9 +17,15 @@
 
 namespace zlib_internal {
 
-uLongf GZipExpectedCompressedSize(uLongf input_size);
+enum WrapperType {
+  ZLIB,
+  GZIP,
+  ZRAW,
+};
 
-uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length);
+uLongf GzipExpectedCompressedSize(uLongf input_size);
+
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length);
 
 int GzipCompressHelper(Bytef* dest,
                        uLongf* dest_length,
@@ -28,11 +34,25 @@
                        void* (*malloc_fn)(size_t),
                        void (*free_fn)(void*));
 
+int CompressHelper(WrapperType wrapper_type,
+                   Bytef* dest,
+                   uLongf* dest_length,
+                   const Bytef* source,
+                   uLong source_length,
+                   void* (*malloc_fn)(size_t),
+                   void (*free_fn)(void*));
+
 int GzipUncompressHelper(Bytef* dest,
                          uLongf* dest_length,
                          const Bytef* source,
                          uLong source_length);
 
+int UncompressHelper(WrapperType wrapper_type,
+                     Bytef* dest,
+                     uLongf* dest_length,
+                     const Bytef* source,
+                     uLong source_length);
+
 }  // namespace zlib_internal
 
 #endif  // THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_
diff --git a/tools/binary_size/libsupersize/caspian/BUILD.gn b/tools/binary_size/libsupersize/caspian/BUILD.gn
index 116a14dc..e31449f8 100644
--- a/tools/binary_size/libsupersize/caspian/BUILD.gn
+++ b/tools/binary_size/libsupersize/caspian/BUILD.gn
@@ -39,6 +39,7 @@
     ":caspian-lib",
     "//testing/gtest",
     "//testing/gtest:gtest_main",
+    "//third_party/re2:re2",
   ]
 }
 
diff --git a/tools/binary_size/libsupersize/caspian/function_signature.cc b/tools/binary_size/libsupersize/caspian/function_signature.cc
index a211185..721588b 100644
--- a/tools/binary_size/libsupersize/caspian/function_signature.cc
+++ b/tools/binary_size/libsupersize/caspian/function_signature.cc
@@ -1,13 +1,15 @@
 // Copyright 2019 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
+// found in the LICENSE file.
 
 // Much of this logic is duplicated at
 // tools/binary_size/libsupersize/function_signature.py.
 
 #include <stddef.h>
 
+#include <algorithm>
 #include <deque>
+#include <iostream>
 #include <string>
 #include <string_view>
 #include <tuple>
@@ -15,6 +17,20 @@
 
 #include "tools/binary_size/libsupersize/caspian/function_signature.h"
 
+namespace {
+bool EndsWith(std::string_view str,
+              std::string_view suffix,
+              size_t pos = std::string_view::npos) {
+  pos = std::min(pos, str.size());
+  size_t span = suffix.size();
+  return pos >= span && str.substr(pos - span, span) == suffix;
+}
+
+std::string_view Slice(std::string_view sv, size_t lo, size_t hi) {
+  return sv.substr(lo, hi - lo);
+}
+}  // namespace
+
 namespace caspian {
 std::vector<std::string_view> SplitBy(std::string_view str, char delim) {
   std::vector<std::string_view> ret;
@@ -32,6 +48,8 @@
 std::tuple<std::string_view, std::string_view, std::string_view> ParseJava(
     std::string_view full_name,
     std::deque<std::string>* owned_strings) {
+  // |owned_strings| is used as an allocator, the relative order of its
+  // elements can be arbitrary.
   std::string maybe_member_type;
   size_t hash_idx = full_name.find('#');
   std::string_view full_class_name;
@@ -42,7 +60,7 @@
     // Format: Class#symbol: type
     full_class_name = full_name.substr(0, hash_idx);
     size_t colon_idx = full_name.find(':');
-    member = full_name.substr(hash_idx + 1, colon_idx - hash_idx - 1);
+    member = Slice(full_name, hash_idx + 1, colon_idx);
     if (colon_idx != std::string_view::npos) {
       member_type = full_name.substr(colon_idx);
     }
@@ -81,4 +99,232 @@
 
   return std::make_tuple(full_name, template_name, name);
 }
+
+size_t FindLastCharOutsideOfBrackets(std::string_view name,
+                                     char target_char,
+                                     size_t prev_idx) {
+  int paren_balance_count = 0;
+  int angle_balance_count = 0;
+  std::string_view prefix = name.substr(0, prev_idx);
+  while (true) {
+    size_t idx = prefix.rfind(target_char);
+    if (idx == std::string_view::npos) {
+      return std::string_view::npos;
+    }
+    for (char c : prefix.substr(idx)) {
+      switch (c) {
+        case '<':
+          angle_balance_count++;
+          break;
+        case '>':
+          angle_balance_count--;
+          break;
+        case '(':
+          paren_balance_count++;
+          break;
+        case ')':
+          paren_balance_count--;
+          break;
+      }
+    }
+    if (angle_balance_count == 0 && paren_balance_count == 0) {
+      return idx;
+    }
+    prefix = prefix.substr(0, idx);
+  }
+}
+
+size_t FindReturnValueSpace(std::string_view name, size_t paren_idx) {
+  size_t space_idx = paren_idx;
+  // Special case: const cast operators (see tests).
+  if (EndsWith(name, " const", paren_idx)) {
+    space_idx = paren_idx - 6;
+  }
+  while (true) {
+    space_idx = FindLastCharOutsideOfBrackets(name, ' ', space_idx);
+    // Special cases: "operator new", "operator< <templ>", "operator<< <tmpl>".
+    // No space is added for operator>><tmpl>.
+    // Currently does not handle operator->, operator->*
+    if (std::string_view::npos == space_idx) {
+      break;
+    }
+    if (EndsWith(name, "operator", space_idx)) {
+      space_idx -= 8;
+    } else if (EndsWith(name, "operator<", space_idx)) {
+      space_idx -= 9;
+    } else if (EndsWith(name, "operator<<", space_idx)) {
+      space_idx -= 10;
+    } else {
+      break;
+    }
+  }
+  return space_idx;
+}
+
+std::string StripTemplateArgs(std::string name) {
+  size_t last_right_idx = std::string::npos;
+  while (true) {
+    last_right_idx = name.substr(0, last_right_idx).rfind('>');
+    if (last_right_idx == std::string_view::npos) {
+      return name;
+    }
+    size_t left_idx =
+        FindLastCharOutsideOfBrackets(name, '<', last_right_idx + 1);
+    if (left_idx != std::string_view::npos) {
+      // Leave in empty <>s to denote that it's a template.
+      name = std::string(name.substr(0, left_idx + 1)) +
+             std::string(name.substr(last_right_idx));
+      last_right_idx = left_idx;
+    }
+  }
+}
+
+std::string NormalizeTopLevelGccLambda(std::string_view name,
+                                       size_t left_paren_idx) {
+  // cc::{lambda(PaintOp*)#63}::_FUN(cc:PaintOp*)
+  // -> cc::$lambda#63(cc:PaintOp*)
+
+  size_t left_brace_idx = name.find('{');
+  if (left_brace_idx == std::string_view::npos) {
+    exit(1);
+  }
+  size_t hash_idx = name.find('#', left_brace_idx + 1);
+  if (hash_idx == std::string_view::npos) {
+    exit(1);
+  }
+  size_t right_brace_idx = name.find('}', hash_idx + 1);
+  if (right_brace_idx == std::string_view::npos) {
+    exit(1);
+  }
+  std::string_view number = Slice(name, hash_idx + 1, right_brace_idx);
+
+  std::string ret;
+  ret += name.substr(0, left_brace_idx);
+  ret += "$lambda#";
+  ret += number;
+  ret += name.substr(left_paren_idx);
+  return ret;
+}
+
+std::string NormalizeTopLevelClangLambda(std::string_view name,
+                                         size_t left_paren_idx) {
+  // cc::$_21::__invoke(int) -> cc::$lambda#21(int)
+  size_t dollar_idx = name.find('$');
+  if (dollar_idx == std::string_view::npos) {
+    exit(1);
+  }
+  size_t colon_idx = name.find(':', dollar_idx + 1);
+  if (colon_idx == std::string_view::npos) {
+    exit(1);
+  }
+  std::string_view number = Slice(name, dollar_idx + 2, colon_idx);
+
+  std::string ret;
+  ret += name.substr(0, dollar_idx);
+  ret += "$lambda#";
+  ret += number;
+  ret += name.substr(left_paren_idx);
+  return ret;
+}
+
+size_t FindParameterListParen(std::string_view name) {
+  size_t start_idx = 0;
+  int angle_balance_count = 0;
+  int paren_balance_count = 0;
+  while (true) {
+    size_t idx = name.find('(', start_idx);
+    if (idx == std::string_view::npos) {
+      return std::string_view::npos;
+    }
+    for (char c : Slice(name, start_idx, idx)) {
+      switch (c) {
+        case '<':
+          angle_balance_count++;
+          break;
+        case '>':
+          angle_balance_count--;
+          break;
+        case '(':
+          paren_balance_count++;
+          break;
+        case ')':
+          paren_balance_count--;
+          break;
+      }
+    }
+    size_t operator_offset = Slice(name, start_idx, idx).find("operator<");
+    if (operator_offset != std::string_view::npos) {
+      if (name[start_idx + operator_offset + 9] == '<') {
+        // Handle operator<<, <<=
+        angle_balance_count -= 2;
+      } else {
+        // Handle operator<=
+        angle_balance_count -= 1;
+      }
+    } else {
+      operator_offset = Slice(name, start_idx, idx).find("operator>");
+      if (operator_offset != std::string_view::npos) {
+        if (name[start_idx + operator_offset + 9] == '>') {
+          // Handle operator>>,>>=
+          angle_balance_count += 2;
+        } else {
+          // Handle operator>=
+          angle_balance_count += 1;
+        }
+      }
+    }
+
+    // Adjust paren
+    if (angle_balance_count == 0 && paren_balance_count == 0) {
+      // Special case: skip "(anonymous namespace)".
+      if (name.substr(idx, 21) == "(anonymous namespace)") {
+        start_idx = idx + 21;
+        continue;
+      }
+      // Special case: skip "decltype (...)"
+      // Special case: skip "{lambda(PaintOp*)#63}"
+      if (idx && name[idx - 1] != ' ' && !EndsWith(name, "{lambda", idx)) {
+        return idx;
+      }
+    }
+
+    start_idx = idx + 1;
+    paren_balance_count++;
+  }
+}
+
+std::tuple<std::string, std::string, std::string> ParseCpp(
+    const std::string& input_name) {
+  std::string name = input_name;
+  size_t left_paren_idx = FindParameterListParen(input_name);
+  std::string full_name = input_name;
+  if (left_paren_idx != std::string::npos && left_paren_idx > 0) {
+    size_t right_paren_idx = name.rfind(')');
+    if (right_paren_idx <= left_paren_idx) {
+      std::cerr << "ParseCpp() received bad symbol: " << name << std::endl;
+      exit(1);
+    }
+    size_t space_idx = FindReturnValueSpace(name, left_paren_idx);
+    std::string name_no_params =
+        std::string(Slice(name, space_idx + 1, left_paren_idx));
+    // Special case for top-level lambdas.
+    if (EndsWith(name_no_params, "}::_FUN")) {
+      // Don't use |name_no_params| in here since prior _idx will be off if
+      // there was a return value.
+      name = NormalizeTopLevelGccLambda(name, left_paren_idx);
+      return ParseCpp(name);
+    } else if (EndsWith(name_no_params, "::__invoke") &&
+               name_no_params.find('$') != std::string::npos) {
+      name = NormalizeTopLevelClangLambda(name, left_paren_idx);
+      return ParseCpp(name);
+    }
+
+    full_name = name.substr(space_idx + 1);
+    name = name_no_params + name.substr(right_paren_idx + 1);
+  }
+
+  std::string template_name = name;
+  name = StripTemplateArgs(name);
+  return std::make_tuple(full_name, template_name, name);
+}
 }  // namespace caspian
diff --git a/tools/binary_size/libsupersize/caspian/function_signature.h b/tools/binary_size/libsupersize/caspian/function_signature.h
index ed40599..d8961cc 100644
--- a/tools/binary_size/libsupersize/caspian/function_signature.h
+++ b/tools/binary_size/libsupersize/caspian/function_signature.h
@@ -23,6 +23,37 @@
 std::tuple<std::string_view, std::string_view, std::string_view> ParseJava(
     std::string_view full_name,
     std::deque<std::string>* owned_strings);
+
+// Strips return type and breaks function signature into parts.
+// See unit tests for example signatures.
+// Returns:
+//  A tuple of:
+//   * name without return type (symbol.full_name),
+//   * full_name without params (symbol.template_name),
+//   * full_name without params and template args (symbol.name)
+std::tuple<std::string, std::string, std::string> ParseCpp(
+    const std::string& name);
+
+// Returns the last index of |target_char| that is not within ()s nor <>s.
+size_t FindLastCharOutsideOfBrackets(std::string_view name,
+                                     char target_char,
+                                     size_t prev_idx = std::string::npos);
+
+// Finds index of the "(" that denotes the start of a parameter list.
+size_t FindParameterListParen(std::string_view name);
+
+// Returns the index of the space that comes after the return type.
+size_t FindReturnValueSpace(std::string_view name, size_t paren_idx);
+
+// Different compilers produce different lambda symbols. These utility
+// functions standardize the two, so we can compare between compilers.
+std::string NormalizeTopLevelGccLambda(std::string_view name,
+                                       size_t left_paren_idx);
+std::string NormalizeTopLevelClangLambda(std::string_view name,
+                                         size_t left_paren_idx);
+
+// Strips the contents of <>, leaving empty <>s to denote that it's a template.
+std::string StripTemplateArgs(std::string name);
 }  // namespace caspian
 
 #endif  // TOOLS_BINARY_SIZE_LIBSUPERSIZE_CASPIAN_FUNCTION_SIGNATURE_H_
diff --git a/tools/binary_size/libsupersize/caspian/function_signature_test.cc b/tools/binary_size/libsupersize/caspian/function_signature_test.cc
index 6dfb5edc..3bcdc5d 100644
--- a/tools/binary_size/libsupersize/caspian/function_signature_test.cc
+++ b/tools/binary_size/libsupersize/caspian/function_signature_test.cc
@@ -9,6 +9,7 @@
 #include <tuple>
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/re2/src/re2/re2.h"
 
 namespace {
 std::tuple<std::string, std::string, std::string> PrettyDebug(
@@ -36,6 +37,59 @@
   EXPECT_EQ(expected_output, caspian::SplitBy(input, '/'));
 }
 
+TEST(AnalyzeTest, FindLastCharOutsideOfBrackets) {
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("(a)a", 'a'), 3u);
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("abc(a)a", 'a'), 6u);
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("(b)aaa", 'b'),
+            std::string::npos);
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("", 'b'), std::string::npos);
+
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("a(a)a", 'a', 4u), 0u);
+  EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("a<<>", '<', 4u), 2u);
+}
+
+TEST(AnalyzeTest, FindParameterListParen) {
+  EXPECT_EQ(caspian::FindParameterListParen("a()"), 1u);
+  EXPECT_EQ(
+      caspian::FindParameterListParen(
+          "bool foo::Bar<unsigned int, int>::Do<unsigned int>(unsigned int)"),
+      50u);
+  EXPECT_EQ(caspian::FindParameterListParen(
+                "std::basic_ostream<char, std::char_traits<char> >& "
+                "std::operator<< <std::char_traits<char> "
+                ">(std::basic_ostream<char, std::char_traits<char> >&, char)"),
+            92u);
+}
+
+TEST(AnalyzeTest, FindReturnValueSpace) {
+  EXPECT_EQ(caspian::FindReturnValueSpace("bool a()", 6u), 4u);
+  EXPECT_EQ(caspian::FindReturnValueSpace("operator delete(void*)", 15),
+            std::string::npos);
+  EXPECT_EQ(
+      caspian::FindReturnValueSpace(
+          "bool foo::Bar<unsigned int, int>::Do<unsigned int>(unsigned int)",
+          50u),
+      4u);
+  EXPECT_EQ(caspian::FindReturnValueSpace(
+                "std::basic_ostream<char, std::char_traits<char> >& "
+                "std::operator<< <std::char_traits<char> "
+                ">(std::basic_ostream<char, std::char_traits<char> >&, char)",
+                92u),
+            50u);
+}
+
+TEST(AnalyzeTest, NormalizeTopLevelGccLambda) {
+  EXPECT_EQ(caspian::NormalizeTopLevelGccLambda(
+                "cc::{lambda(PaintOp*)#63}::_FUN()", 31u),
+            "cc::$lambda#63()");
+}
+
+TEST(AnalyzeTest, NormalizeTopLevelClangLambda) {
+  // cc::$_21::__invoke() -> cc::$lambda#21()
+  EXPECT_EQ(caspian::NormalizeTopLevelClangLambda("cc::$_21::__invoke()", 18u),
+            "cc::$lambda#21()");
+}
+
 TEST(AnalyzeTest, ParseJavaFunctionSignature) {
   ::std::deque<std::string> owned_strings;
   // Java method with no args
@@ -71,4 +125,118 @@
   do_test("org.ClassName some.Type mField", "org.ClassName#mField: some.Type",
           "org.ClassName#mField", "ClassName#mField");
 }
+
+TEST(AnalyzeTest, ParseFunctionSignature) {
+  auto check = [](std::string ret_part, std::string name_part,
+                  std::string params_part, std::string after_part = "",
+                  std::string name_without_templates = "") {
+    if (name_without_templates.empty()) {
+      name_without_templates = name_part;
+      // Heuristic to drop templates: std::vector<int> -> std::vector<>
+      RE2::GlobalReplace(&name_without_templates, "<.*?>", "<>");
+      name_without_templates += after_part;
+    }
+    std::string signature = name_part + params_part + after_part;
+    auto result = caspian::ParseCpp(signature);
+    EXPECT_EQ(name_without_templates, std::get<2>(result));
+    EXPECT_EQ(name_part + after_part, std::get<1>(result));
+    EXPECT_EQ(name_part + params_part + after_part, std::get<0>(result));
+
+    if (!ret_part.empty()) {
+      // Parse should be unchanged when we prepend |ret_part|
+      signature = ret_part + name_part + params_part + after_part;
+      result = caspian::ParseCpp(signature);
+      EXPECT_EQ(name_without_templates, std::get<2>(result));
+      EXPECT_EQ(name_part + after_part, std::get<1>(result));
+      EXPECT_EQ(name_part + params_part + after_part, std::get<0>(result));
+    }
+  };
+
+  check("bool ", "foo::Bar<unsigned int, int>::Do<unsigned int>",
+        "(unsigned int)");
+  check("base::internal::CheckedNumeric<int>& ",
+        "base::internal::CheckedNumeric<int>::operator+=<int>", "(int)");
+  check("base::internal::CheckedNumeric<int>& ",
+        "b::i::CheckedNumeric<int>::MathOp<b::i::CheckedAddOp, int>", "(int)");
+  check("", "(anonymous namespace)::GetBridge", "(long long)");
+  check("", "operator delete", "(void*)");
+  check("",
+        "b::i::DstRangeRelationToSrcRangeImpl<long long, long long, "
+        "std::__ndk1::numeric_limits, (b::i::Integer)1>::Check",
+        "(long long)");
+  check("", "cc::LayerIterator::operator cc::LayerIteratorPosition const", "()",
+        " const");
+  check("decltype ({parm#1}((SkRecords::NoOp)())) ",
+        "SkRecord::Record::visit<SkRecords::Draw&>", "(SkRecords::Draw&)",
+        " const");
+  check("", "base::internal::BindStateBase::BindStateBase",
+        "(void (*)(), void (*)(base::internal::BindStateBase const*))");
+  check("int ", "std::__ndk1::__c11_atomic_load<int>",
+        "(std::__ndk1::<int> volatile*, std::__ndk1::memory_order)");
+  check("std::basic_ostream<char, std::char_traits<char> >& ",
+        "std::operator<< <std::char_traits<char> >",
+        "(std::basic_ostream<char, std::char_traits<char> >&, char)", "",
+        "std::operator<< <>");
+  check("",
+        "std::basic_istream<char, std::char_traits<char> >"
+        "::operator>>",
+        "(unsigned int&)", "", "std::basic_istream<>::operator>>");
+  check("", "std::operator><std::allocator<char> >", "()", "",
+        "std::operator><>");
+  check("", "std::operator>><std::allocator<char> >",
+        "(std::basic_istream<char, std::char_traits<char> >&)", "",
+        "std::operator>><>");
+  check("", "std::basic_istream<char>::operator>", "(unsigned int&)", "",
+        "std::basic_istream<>::operator>");
+  check("v8::internal::SlotCallbackResult ",
+        "v8::internal::UpdateTypedSlotHelper::UpdateCodeTarget"
+        "<v8::PointerUpdateJobTraits<(v8::Direction)1>::Foo(v8::Heap*, "
+        "v8::MemoryChunk*)::{lambda(v8::SlotType, unsigned char*)#2}::"
+        "operator()(v8::SlotType, unsigned char*, unsigned char*) "
+        "const::{lambda(v8::Object**)#1}>",
+        "(v8::RelocInfo, v8::Foo<(v8::PointerDirection)1>::Bar(v8::Heap*)::"
+        "{lambda(v8::SlotType)#2}::operator()(v8::SlotType) const::"
+        "{lambda(v8::Object**)#1})",
+        "", "v8::internal::UpdateTypedSlotHelper::UpdateCodeTarget<>");
+  check("", "WTF::StringAppend<WTF::String, WTF::String>::operator WTF::String",
+        "()", " const");
+  // Make sure []s are not removed from the name part.
+  check("", "Foo", "()", " [virtual thunk]");
+  // Template function that accepts an anonymous lambda.
+  check("",
+        "blink::FrameView::ForAllNonThrottledFrameViews<blink::FrameView::Pre"
+        "Paint()::{lambda(FrameView&)#2}>",
+        "(blink::FrameView::PrePaint()::{lambda(FrameView&)#2} const&)", "");
+
+  // Test with multiple template args.
+  check("int ", "Foo<int()>::bar<a<b> >", "()", "", "Foo<>::bar<>");
+
+  // See function_signature_test.py for full comment
+  std::string sig =
+      "(anonymous namespace)::Foo::Baz() const::GLSLFP::onData(Foo, Bar)";
+  auto ret = caspian::ParseCpp(sig);
+  EXPECT_EQ("(anonymous namespace)::Foo::Baz", std::get<2>(ret));
+  EXPECT_EQ("(anonymous namespace)::Foo::Baz", std::get<1>(ret));
+  EXPECT_EQ(sig, std::get<0>(ret));
+
+  // Top-level lambda.
+  // Note: Inline lambdas do not seem to be broken into their own symbols.
+  sig = "cc::{lambda(cc::PaintOp*)#63}::_FUN(cc::PaintOp*)";
+  ret = caspian::ParseCpp(sig);
+  EXPECT_EQ("cc::$lambda#63", std::get<2>(ret));
+  EXPECT_EQ("cc::$lambda#63", std::get<1>(ret));
+  EXPECT_EQ("cc::$lambda#63(cc::PaintOp*)", std::get<0>(ret));
+
+  sig = "cc::$_63::__invoke(cc::PaintOp*)";
+  ret = caspian::ParseCpp(sig);
+  EXPECT_EQ("cc::$lambda#63", std::get<2>(ret));
+  EXPECT_EQ("cc::$lambda#63", std::get<1>(ret));
+  EXPECT_EQ("cc::$lambda#63(cc::PaintOp*)", std::get<0>(ret));
+
+  // Data members
+  check("", "blink::CSSValueKeywordsHash::findValueImpl", "(char const*)",
+        "::value_word_list");
+  check("", "foo::Bar<Z<Y> >::foo<bar>", "(abc)", "::var<baz>",
+        "foo::Bar<>::foo<>::var<>");
+}
 }  // namespace
diff --git a/tools/binary_size/libsupersize/function_signature.py b/tools/binary_size/libsupersize/function_signature.py
index 7c1741f..0cfe01e 100644
--- a/tools/binary_size/libsupersize/function_signature.py
+++ b/tools/binary_size/libsupersize/function_signature.py
@@ -14,43 +14,42 @@
   # is necessary (rather than reusing _FindLastCharOutsideOfBrackets), is
   # to capture the outer-most function in the case where classes are nested.
   start_idx = 0
+  template_balance_count = 0
+  paren_balance_count = 0
   while True:
-    template_balance_count = 0
-    paren_balance_count = 0
-    while True:
-      idx = name.find('(', start_idx)
-      if idx == -1:
-        return -1
-      template_balance_count += (
-          name.count('<', start_idx, idx) - name.count('>', start_idx, idx))
-      # Special: operators with angle brackets.
-      operator_idx = name.find('operator<', start_idx, idx)
-      if operator_idx != -1:
-        if name[operator_idx + 9] == '<':
-          template_balance_count -= 2
-        else:
-          template_balance_count -= 1
+    idx = name.find('(', start_idx)
+    if idx == -1:
+      return -1
+    template_balance_count += (
+        name.count('<', start_idx, idx) - name.count('>', start_idx, idx))
+    # Special: operators with angle brackets.
+    operator_idx = name.find('operator<', start_idx, idx)
+    if operator_idx != -1:
+      if name[operator_idx + 9] == '<':
+        template_balance_count -= 2
       else:
-        operator_idx = name.find('operator>', start_idx, idx)
-        if operator_idx != -1:
-          if name[operator_idx + 9] == '>':
-            template_balance_count += 2
-          else:
-            template_balance_count += 1
+        template_balance_count -= 1
+    else:
+      operator_idx = name.find('operator>', start_idx, idx)
+      if operator_idx != -1:
+        if name[operator_idx + 9] == '>':
+          template_balance_count += 2
+        else:
+          template_balance_count += 1
 
-      paren_balance_count += (
-          name.count('(', start_idx, idx) - name.count(')', start_idx, idx))
-      if template_balance_count == 0 and paren_balance_count == 0:
-        # Special case: skip "(anonymous namespace)".
-        if -1 != name.find('(anonymous namespace)', idx, idx + 21):
-          start_idx = idx + 21
-          continue
-        # Special case: skip "decltype (...)"
-        # Special case: skip "{lambda(PaintOp*)#63}"
-        if name[idx - 1] != ' ' and name[idx - 7:idx] != '{lambda':
-          return idx
-      start_idx = idx + 1
-      paren_balance_count += 1
+    paren_balance_count += (
+        name.count('(', start_idx, idx) - name.count(')', start_idx, idx))
+    if template_balance_count == 0 and paren_balance_count == 0:
+      # Special case: skip "(anonymous namespace)".
+      if -1 != name.find('(anonymous namespace)', idx, idx + 21):
+        start_idx = idx + 21
+        continue
+      # Special case: skip "decltype (...)"
+      # Special case: skip "{lambda(PaintOp*)#63}"
+      if name[idx - 1] != ' ' and name[idx - 7:idx] != '{lambda':
+        return idx
+    start_idx = idx + 1
+    paren_balance_count += 1
 
 
 def _FindLastCharOutsideOfBrackets(name, target_char, prev_idx=None):
@@ -82,12 +81,18 @@
     space_idx = _FindLastCharOutsideOfBrackets(name, ' ', space_idx)
     # Special cases: "operator new", "operator< <templ>", "operator<< <tmpl>".
     # No space is added for operator>><tmpl>.
-    if -1 == space_idx or (
-        -1 == name.find('operator', space_idx - 8, space_idx) and
-        -1 == name.find('operator<', space_idx - 9, space_idx) and
-        -1 == name.find('operator<<', space_idx - 10, space_idx)):
+    if -1 == space_idx:
       break
-    space_idx -= 8
+
+    if -1 != name.find('operator', space_idx - 8, space_idx):
+      space_idx -= 8
+    elif -1 != name.find('operator<', space_idx - 9, space_idx):
+      space_idx -= 9
+    elif -1 != name.find('operator<<', space_idx - 10, space_idx):
+      space_idx -= 10
+    else:
+      break
+
   return space_idx
 
 
@@ -186,9 +191,9 @@
     assert right_paren_idx > left_paren_idx
     space_idx = _FindReturnValueSpace(name, left_paren_idx)
     name_no_params = name[space_idx + 1:left_paren_idx]
-    # Special case for top-level lamdas.
+    # Special case for top-level lambdas.
     if name_no_params.endswith('}::_FUN'):
-      # Don't use name_no_params in here since prior _idx will be off if
+      # Don't use |name_no_params| in here since prior _idx will be off if
       # there was a return value.
       name = _NormalizeTopLevelGccLambda(name, left_paren_idx)
       return Parse(name)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index bcb50d6..200ba4bca 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -35678,6 +35678,7 @@
   <int value="-1961648833" label="show_summary"/>
   <int value="-1961497025" label="tint-gl-composited-content"/>
   <int value="-1961062505" label="VrBrowsingInCustomTab:disabled"/>
+  <int value="-1960766118" label="CrossOriginIsolation:disabled"/>
   <int value="-1960567385" label="KeepPrefetchedContentSuggestions:enabled"/>
   <int value="-1959563554" label="ChromeOSAccountManager:enabled"/>
   <int value="-1958315092" label="EnableGamepadButtonAxisEvents:disabled"/>
@@ -35724,6 +35725,7 @@
       label="AlwaysShowServerCardsInSyncTransport:disabled"/>
   <int value="-1916060206" label="enable-display-zoom-setting"/>
   <int value="-1915854488" label="enable-offline-pages"/>
+  <int value="-1914798479" label="CryptAuthV1DeviceSyncDeprecate:disabled"/>
   <int value="-1913801713"
       label="UploadCrashReportsUsingJobScheduler:disabled"/>
   <int value="-1912999136" label="enable-automatic-password-saving:enabled"/>
@@ -36033,7 +36035,6 @@
   <int value="-1514611301" label="enable-data-reduction-proxy-bypass-warnings"/>
   <int value="-1512656386" label="disable-new-audio-rendering-mixing-strategy"/>
   <int value="-1510839574" label="disable-sync-synced-notifications"/>
-  <int value="-1509001043" label="CrossOriginEmbedderPolicy:enabled"/>
   <int value="-1508852757" label="CreditCardAutofillTouchBar:disabled"/>
   <int value="-1506880454"
       label="SupervisedUserCommittedInterstitials:disabled"/>
@@ -36485,6 +36486,7 @@
   <int value="-992785453" label="ExplicitLanguageAsk:disabled"/>
   <int value="-991253797"
       label="OmniboxSpeculativeServiceWorkerStartOnQueryInput:disabled"/>
+  <int value="-990374250" label="CrossOriginIsolation:enabled"/>
   <int value="-990187062" label="SendTabToSelfShowSendingUI:enabled"/>
   <int value="-989671895" label="OfflineIndicatorAlwaysHttpProbe:enabled"/>
   <int value="-987470173" label="ClickToCallOpenDialerDirectly:disabled"/>
@@ -36756,7 +36758,6 @@
   <int value="-662064703" label="MediaSessionService:enabled"/>
   <int value="-661978438" label="enable-data-reduction-proxy-lo-fi"/>
   <int value="-660160292" label="enable-apps-show-on-first-paint"/>
-  <int value="-656345197" label="CrossOriginEmbedderPolicy:disabled"/>
   <int value="-654196854" label="PasswordsKeyboardAccessory:enabled"/>
   <int value="-653616608" label="MacSyscallSandbox:disabled"/>
   <int value="-650504533" label="enable-speculative-launch-service-worker"/>
@@ -37105,6 +37106,7 @@
   <int value="-174564579"
       label="ServiceWorkerImportedScriptUpdateCheck:enabled"/>
   <int value="-174319545" label="BulkPrinters:enabled"/>
+  <int value="-174161156" label="CryptAuthV1DeviceSyncDeprecate:enabled"/>
   <int value="-173268856" label="GesturePropertiesDBusService"/>
   <int value="-171232290" label="ListAllDisplayModes:disabled"/>
   <int value="-171173736" label="VrBrowsingExperimentalFeatures:disabled"/>
diff --git a/tools/perf/core/results_processor/command_line.py b/tools/perf/core/results_processor/command_line.py
index 94b99b5..5ea5e73 100644
--- a/tools/perf/core/results_processor/command_line.py
+++ b/tools/perf/core/results_processor/command_line.py
@@ -18,6 +18,7 @@
 
 from core.results_processor import formatters
 from core.results_processor import util
+from core.results_processor import trace_processor
 
 
 def ArgumentParser(standalone=False):
@@ -69,6 +70,11 @@
           'How to interpret the testPath attribute.',
           'Available options: %(choices)s. Default: %(default)s.'))
   group.add_argument(
+      '--trace-processor-path', default=trace_processor.DEFAULT_TP_PATH,
+      help=Sentences(
+          'Path to trace processor shell.',
+          'Default: %(default)s.'))
+  group.add_argument(
       '--upload-results', action='store_true',
       help='Upload generated artifacts to cloud storage.')
   group.add_argument(
diff --git a/tools/perf/core/results_processor/compute_metrics.py b/tools/perf/core/results_processor/compute_metrics.py
index 193d964..c745f86 100644
--- a/tools/perf/core/results_processor/compute_metrics.py
+++ b/tools/perf/core/results_processor/compute_metrics.py
@@ -15,9 +15,7 @@
 HTML_TRACE_NAME = 'trace.html'
 
 
-def _RunMetric(test_result):
-  metrics = [tag['value'] for tag in test_result['tags']
-             if tag['key'] == 'tbmv2']
+def _RunMetric(test_result, metrics):
   html_trace = test_result['outputArtifacts'][HTML_TRACE_NAME]
   html_local_path = html_trace['filePath']
   html_remote_url = html_trace.get('remoteUrl')
@@ -59,8 +57,16 @@
   if test_result['status'] == 'SKIP':
     return
 
-  if (HTML_TRACE_NAME not in artifacts or
-      not any(tag['key'] == 'tbmv2' for tag in test_result.get('tags', []))):
+  metrics = [tag['value'] for tag in test_result.get('tags', [])
+             if tag['key'] == 'tbmv2']
+  if not metrics:
+    logging.info('%s: No metrics specified.', test_result['testPath'])
+    return
+
+  if HTML_TRACE_NAME not in artifacts:
+    util.SetUnexpectedFailure(test_result)
+    logging.error('%s: No traces to compute metrics on.',
+                  test_result['testPath'])
     return
 
   trace_size_in_mib = (os.path.getsize(artifacts[HTML_TRACE_NAME]['filePath'])
@@ -73,4 +79,4 @@
                   test_result['testPath'], trace_size_in_mib)
     return
 
-  test_result['_histograms'].ImportDicts(_RunMetric(test_result))
+  test_result['_histograms'].ImportDicts(_RunMetric(test_result, metrics))
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py
index d5a75c3..853e55d 100644
--- a/tools/perf/core/results_processor/processor.py
+++ b/tools/perf/core/results_processor/processor.py
@@ -21,6 +21,7 @@
 from core.results_processor import command_line
 from core.results_processor import compute_metrics
 from core.results_processor import formatters
+from core.results_processor import trace_processor
 from core.results_processor import util
 
 from tracing.trace_data import trace_data
@@ -34,6 +35,7 @@
 TEST_RESULTS = '_test_results.jsonl'
 DIAGNOSTICS_NAME = 'diagnostics.json'
 MEASUREMENTS_NAME = 'measurements.json'
+CONVERTED_JSON_TRACE_NAME = 'converted_from_pb.json'
 
 FORMATS_WITH_METRICS = ['csv', 'histograms', 'html']
 
@@ -63,6 +65,7 @@
   results_label = options.results_label
   max_num_values = options.max_values_per_test_case
   test_path_format = options.test_path_format
+  trace_processor_path = options.trace_processor_path
   test_suite_start = (test_results[0]['startTime']
       if test_results and 'startTime' in test_results[0]
       else datetime.datetime.utcnow().isoformat() + 'Z')
@@ -74,7 +77,7 @@
       lambda result: ProcessTestResult(
           result, upload_bucket, results_label, run_identifier,
           test_suite_start, should_compute_metrics, max_num_values,
-          test_path_format),
+          test_path_format, trace_processor_path),
       test_results,
       on_failure=util.SetUnexpectedFailure,
   )
@@ -96,8 +99,9 @@
 
 def ProcessTestResult(test_result, upload_bucket, results_label,
                       run_identifier, test_suite_start, should_compute_metrics,
-                      max_num_values, test_path_format):
-  AggregateTraces(test_result)
+                      max_num_values, test_path_format, trace_processor_path):
+  ConvertProtoTraces(test_result, trace_processor_path)
+  AggregateJsonTraces(test_result)
   if upload_bucket is not None:
     UploadArtifacts(test_result, upload_bucket, run_identifier)
 
@@ -152,27 +156,68 @@
   return test_results
 
 
-def AggregateTraces(test_result):
-  """Replace individual traces with an aggregate one for each test result.
+def _IsProtoTrace(trace_name):
+  return (trace_name.startswith('trace/') and
+          (trace_name.endswith('.pb') or trace_name.endswith('.pb.gz')))
 
-  For a test run with traces, generates an aggregate HTML trace. Removes
+
+def _IsJsonTrace(trace_name):
+  return (trace_name.startswith('trace/') and
+          (trace_name.endswith('.json') or trace_name.endswith('.json.gz')))
+
+
+def _BuildOutputPath(input_files, output_name):
+  """Build a path to a file in the same folder as input_files."""
+  return os.path.join(
+      os.path.dirname(os.path.commonprefix(input_files)),
+      output_name
+  )
+
+
+def ConvertProtoTraces(test_result, trace_processor_path):
+  """Convert proto traces to json.
+
+  For a test result with proto traces, converts them to json using
+  trace_processor and stores the json trace as a separate artifact.
+  """
+  artifacts = test_result.get('outputArtifacts', {})
+  proto_trace_files = [
+      artifact['filePath'] for name, artifact in artifacts.iteritems()
+      if _IsProtoTrace(name)]
+
+  if proto_trace_files:
+    logging.info('%s: Converting proto traces %s.',
+                 test_result['testPath'], proto_trace_files)
+    json_path = _BuildOutputPath(proto_trace_files, CONVERTED_JSON_TRACE_NAME)
+    trace_processor.ConvertProtoTracesToJson(
+        trace_processor_path, proto_trace_files, json_path)
+    artifacts['trace/' + CONVERTED_JSON_TRACE_NAME] = {
+        'filePath': json_path,
+        'contentType': 'application/json',
+    }
+
+
+def AggregateJsonTraces(test_result):
+  """Replace individual json traces with an aggregate HTML trace.
+
+  For a test result with json traces, generates an aggregate HTML trace. Removes
   all entries for individual traces and adds one entry for aggregate one.
   """
   artifacts = test_result.get('outputArtifacts', {})
-  traces = [name for name in artifacts if name.startswith('trace/')]
+  json_traces = [name for name in artifacts if _IsJsonTrace(name)]
   # TODO(crbug.com/981349): Stop checking for HTML_TRACE_NAME after
   # Telemetry does not aggregate traces anymore.
-  if traces and compute_metrics.HTML_TRACE_NAME not in artifacts:
-    trace_files = [artifacts[name]['filePath'] for name in traces]
-    html_path = os.path.join(
-        os.path.dirname(os.path.commonprefix(trace_files)),
-        compute_metrics.HTML_TRACE_NAME)
+  if json_traces and compute_metrics.HTML_TRACE_NAME not in artifacts:
+    trace_files = [artifacts[name]['filePath'] for name in json_traces]
+    html_path = _BuildOutputPath(trace_files, compute_metrics.HTML_TRACE_NAME)
+    logging.info('%s: Aggregating json traces %s.',
+                 test_result['testPath'], trace_files)
     trace_data.SerializeAsHtml(trace_files, html_path)
     artifacts[compute_metrics.HTML_TRACE_NAME] = {
       'filePath': html_path,
       'contentType': 'text/html',
     }
-  for name in traces:
+  for name in json_traces:
     del artifacts[name]
 
 
diff --git a/tools/perf/core/results_processor/processor_test.py b/tools/perf/core/results_processor/processor_test.py
index 7c0d37e..d3962a85 100644
--- a/tools/perf/core/results_processor/processor_test.py
+++ b/tools/perf/core/results_processor/processor_test.py
@@ -123,7 +123,7 @@
             'benchmark/story',
             output_artifacts={
                 'logs': testing.Artifact('/logs.txt', 'gs://logs.txt'),
-                'trace/telemetry': testing.Artifact('/telemetry.json'),
+                'trace/telemetry.json': testing.Artifact('/telemetry.json'),
                 'trace.html':
                     testing.Artifact('/trace.html', 'gs://trace.html'),
             }
@@ -314,7 +314,7 @@
     self.SerializeIntermediateResults(
         testing.TestResult(
             'benchmark/story',
-            output_artifacts={'trace/json': testing.Artifact(json_trace)},
+            output_artifacts={'trace/trace.json': testing.Artifact(json_trace)},
             tags=['tbmv2:sampleMetric'],
         ),
     )
diff --git a/tools/perf/core/results_processor/processor_unittest.py b/tools/perf/core/results_processor/processor_unittest.py
index 2659fce9..2dc5517 100644
--- a/tools/perf/core/results_processor/processor_unittest.py
+++ b/tools/perf/core/results_processor/processor_unittest.py
@@ -90,7 +90,7 @@
           test_suite_start='2019-10-01T12:00:00.123456Z')
     self.assertEqual(run_identifier, 'src_abc_123_20191001T120000_54321')
 
-  def testAggregateTraces(self):
+  def testAggregateJsonTraces(self):
     test_result = testing.TestResult(
         'benchmark/story2',
         output_artifacts={
@@ -103,7 +103,7 @@
 
     serialize_method = 'tracing.trace_data.trace_data.SerializeAsHtml'
     with mock.patch(serialize_method) as mock_serialize:
-      processor.AggregateTraces(test_result)
+      processor.AggregateJsonTraces(test_result)
 
     self.assertEqual(mock_serialize.call_count, 1)
     trace_files, file_path = mock_serialize.call_args[0][:2]
diff --git a/tools/perf/core/results_processor/trace_processor.py b/tools/perf/core/results_processor/trace_processor.py
new file mode 100644
index 0000000..08ee0d3
--- /dev/null
+++ b/tools/perf/core/results_processor/trace_processor.py
@@ -0,0 +1,51 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import gzip
+import logging
+import os
+import shutil
+import subprocess
+
+from core import path_util
+from py_utils import tempfile_ext
+
+
+DEFAULT_TP_PATH = os.path.join(
+    path_util.GetChromiumSrcDir(), 'out', 'Debug', 'trace_processor_shell')
+EXPORT_JSON_QUERY_TEMPLATE = 'select export_json(%s)\n'
+
+
+def _SqlString(s):
+  """Produce a valid SQL string constant."""
+  return "'%s'" % s.replace("'", "''")
+
+
+def ConvertProtoTracesToJson(trace_processor_path, proto_files, json_path):
+  if not os.path.isfile(trace_processor_path):
+    raise RuntimeError("Can't find trace processor executable at %s" %
+                       trace_processor_path)
+
+  with tempfile_ext.NamedTemporaryFile() as concatenated_trace:
+    for trace_file in proto_files:
+      if trace_file.endswith('.pb.gz'):
+        with gzip.open(trace_file, 'rb') as f:
+          shutil.copyfileobj(f, concatenated_trace)
+      else:
+        with open(trace_file, 'rb') as f:
+          shutil.copyfileobj(f, concatenated_trace)
+    concatenated_trace.close()
+
+    with tempfile_ext.NamedTemporaryFile() as query_file:
+      query_file.write(EXPORT_JSON_QUERY_TEMPLATE % _SqlString(json_path))
+      query_file.close()
+      subprocess.check_call([
+          trace_processor_path,
+          concatenated_trace.name,
+          '-q', query_file.name,
+      ])
+
+  logging.info('Converted json trace written to %s', json_path)
+
+  return json_path
diff --git a/tools/perf/core/results_processor/trace_processor_unittest.py b/tools/perf/core/results_processor/trace_processor_unittest.py
new file mode 100644
index 0000000..642cf00b
--- /dev/null
+++ b/tools/perf/core/results_processor/trace_processor_unittest.py
@@ -0,0 +1,34 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import gzip
+import os
+import shutil
+import tempfile
+import unittest
+
+from core.results_processor import trace_processor
+
+import mock
+
+
+class TraceProcessorTestCase(unittest.TestCase):
+  def setUp(self):
+    self.temp_dir = tempfile.mkdtemp()
+
+  def tearDown(self):
+    shutil.rmtree(self.temp_dir)
+
+  def testConvertProtoTracesToJson(self):
+    trace_plain = os.path.join(self.temp_dir, 'trace1.pb')
+    with open(trace_plain, 'w') as f:
+      f.write('a')
+    trace_gzipped = os.path.join(self.temp_dir, 'trace2.pb.gz')
+    with gzip.open(trace_gzipped, 'w') as f:
+      f.write('b')
+
+    with mock.patch('os.path.isfile', return_value=True):
+      with mock.patch('subprocess.check_call'):
+        trace_processor.ConvertProtoTracesToJson(
+            '/path/to/tp', [trace_plain, trace_gzipped], '/path/to/json')
diff --git a/tools/perf/examples/pinpoint_cli/bisect_job.json b/tools/perf/examples/pinpoint_cli/bisect_job.json
index ada8220..5c2be88 100644
--- a/tools/perf/examples/pinpoint_cli/bisect_job.json
+++ b/tools/perf/examples/pinpoint_cli/bisect_job.json
@@ -1,16 +1,14 @@
 {
   "name": "Example bisect job",
-  "bug_id": "944965",
+  "bug_id": "1022349",
   "target": "performance_webview_test_suite",
   "configuration": "android-go_webview-perf",
-  "benchmark": "system_health.memory_mobile",
   "comparison_mode": "performance",
-  "story": "browse.media.facebook.photos",
+  "benchmark": "system_health.memory_mobile",
+  "story": "browse:media:facebook_photos",
   "chart": "memory:webview:all_processes:reported_by_os:system_memory:private_dirty_size",
-  "tir_label": "browse_media",
-  "trace": "browse:media:facebook_photos",
   "statistic": "avg",
   "repository": "chromium",
-  "start_git_hash": "dd0f551fcd96d46c6ec2b2a7c543cb2083f1831d",
-  "end_git_hash": "e6808e8d7e973f43b0796505a09ee03caf6ec976"
+  "start_git_hash": "9bb441de89f7d031992ec67585ac0732ef622222",
+  "end_git_hash": "f402331ff436d3ac12cacbd1c959641eb3524923"
 }
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc
index 102ad3a..dfbd111 100644
--- a/ui/accessibility/ax_role_properties.cc
+++ b/ui/accessibility/ax_role_properties.cc
@@ -205,13 +205,16 @@
     case ax::mojom::Role::kImage:
     case ax::mojom::Role::kImageMap:
     case ax::mojom::Role::kSvgRoot:
-    case ax::mojom::Role::kVideo:
       return true;
     default:
       return false;
   }
 }
 
+bool IsImageOrVideo(const ax::mojom::Role role) {
+  return IsImage(role) || role == ax::mojom::Role::kVideo;
+}
+
 bool IsInvokable(const AXNodeData& data) {
   // A control is "invokable" if it initiates an action when activated but
   // does not maintain any state. A control that maintains state when activated
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h
index 8e4f741..e79f1d7 100644
--- a/ui/accessibility/ax_role_properties.h
+++ b/ui/accessibility/ax_role_properties.h
@@ -53,6 +53,9 @@
 // Returns true if the given AXNodeData has ignored state or ignored role.
 AX_EXPORT bool IsIgnored(const AXNodeData& data);
 
+// Returns true if the provided role is for any kind of image or video.
+AX_EXPORT bool IsImageOrVideo(const ax::mojom::Role role);
+
 // Returns true if the provided role belongs to an image, graphic, canvas, etc.
 AX_EXPORT bool IsImage(const ax::mojom::Role role);
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 91a9610..241412e 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2078,7 +2078,7 @@
   // for each object.
   interface_mask |= 1 << ATK_ACTION_INTERFACE;
 
-  if (!ui::IsImage(GetData().role)) {
+  if (!ui::IsImageOrVideo(GetData().role)) {
     interface_mask |= 1 << ATK_TEXT_INTERFACE;
     if (!IsPlainTextField())
       interface_mask |= 1 << ATK_HYPERTEXT_INTERFACE;
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 4c833ca..b6c41265 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4312,7 +4312,7 @@
     if (!IsCellOrTableHeader(accessible->GetData().role))
       return E_NOINTERFACE;
   } else if (riid == IID_IAccessibleText || riid == IID_IAccessibleHypertext) {
-    if (ui::IsImage(accessible->GetData().role)) {
+    if (ui::IsImageOrVideo(accessible->GetData().role)) {
       return E_NOINTERFACE;
     }
   }