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 6845545..eafaa7c 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 b8cd99f..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..673420f 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 32918ef..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 f3ac4d6..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..2a816a8 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 c0d3759..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..dc880a5 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..f1b973b 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..b4cdd05 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 eea641d..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..6d212f0 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 7e976ef..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 0a234ba..d95a22e 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 efb7a63..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 ef467b0..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..b47348f 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 ec760b5..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..094cb97 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 98e8d2c..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 50e441a..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..ac99e36 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 b19b1c7..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..7273eaf 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..2e4f95e 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 0045e74..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..d3eed6e 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..0e86369 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..4490e72
--- /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..e51ccd8 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..217c44f 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..d605f9b 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 538751d..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..d125f54 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..e6a9249 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 1428af5..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..b1fd6e5 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..5376da2 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..38727a6 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..f464412 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 345b8ed..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 59e8548..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 495e93b..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..f0eec1b 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..0d503b4 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 5d01d00..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 f33a7d3..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..e22dd39 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..1e3df55 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..29ecdde 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..57a7fb6 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 577ad91..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 4feb056..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 4dd39a7..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 56e5cf6..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 2c4d92b..2ae3cb5 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 cc18387..aa6f3a9 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 b666b15..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 9d993ad..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 1bd75c2..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..6f57f7b 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 5238069..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 1513427..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 c65fff1..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 3a71b3c..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 8269719..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.