diff --git a/DEPS b/DEPS
index 78f8850c..5102f66 100644
--- a/DEPS
+++ b/DEPS
@@ -199,7 +199,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': 'ce4c3060f6fbfd5ed410de314f7e83a66fd792d9',
+  'v8_revision': '1e0d126cf79ed826bbf944072b5e9bbb0c572bbd',
   # 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.
@@ -207,7 +207,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': '38ddebf9a771aef3a906667595354c7a564edf31',
+  'angle_revision': 'e4e2a847dab3512f10f28f212d8f6911336ed069',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -246,7 +246,7 @@
   # 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': '8b3601324fde1ba49338dd6279057cd366c25919',
+  'freetype_revision': 'f9f6adb625c48ef15b5d61a3ac1709a068ea95a3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
@@ -266,7 +266,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': 'e794555edb6fe7cd872ea43c25c415e941669b58',
+  'devtools_frontend_revision': '011b0075cd53a71e094bf9dcfc85e553c5ff9c73',
   # 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.
@@ -875,7 +875,7 @@
 
   # Build tools for Chrome OS.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '93bb4f5a94f3e1d8be7b774b1e6d0b683d097bf8',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f123f22cb971fbd2cdbffcd67ff2b3a9c019f743',
       'condition': 'checkout_chromeos',
   },
 
@@ -1248,7 +1248,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '23c5b63d1c68730cf0a6bb2a904dbd67f288508c',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9a43f48ed4cd22ec0f6e1436cd88b829a3b99550',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1537,7 +1537,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@171aaf4db08f1c4a372cc3d81e445f22467074bc',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@08a9885983f136f2ae6aa4bcfd3da0634bcf489c',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6532a0d..9f61883 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -301,7 +301,7 @@
   '^chrome/browser/chromeos/',
   '^chrome/browser/component_updater/',
   '^chrome/browser/custom_handlers/protocol_handler_registry.cc',
-  '^chrome/browser/device_identity/chromeos/device_oauth2_token_store_chromeos.cc',
+  '^chrome/browser/device_identity/chromeos/device_oauth2_token_store_chromeos.cc', # pylint: disable=line-too-long
   '^chrome/browser/devtools/',
   '^chrome/browser/download/',
   '^chrome/browser/extensions/',
@@ -313,12 +313,12 @@
   '^chrome/browser/media/',
   '^chrome/browser/metrics/',
   '^chrome/browser/nacl_host/test/gdb_debug_stub_browsertest.cc',
-  '^chrome/browser/nearby_sharing/client/nearby_share_api_call_flow_impl_unittest.cc',
+  '^chrome/browser/nearby_sharing/client/nearby_share_api_call_flow_impl_unittest.cc', # pylint: disable=line-too-long
   '^chrome/browser/net/',
   '^chrome/browser/notifications/',
   '^chrome/browser/ntp_tiles/ntp_tiles_browsertest.cc',
   '^chrome/browser/offline_pages/',
-  '^chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc',
+  '^chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc', # pylint: disable=line-too-long
   '^chrome/browser/password_manager/',
   '^chrome/browser/payments/payment_manifest_parser_browsertest.cc',
   '^chrome/browser/pdf/pdf_extension_test.cc',
@@ -1492,6 +1492,8 @@
   name_pattern = r'ForTest(s|ing)?'
   # Describes an occurrence of "ForTest*" inside a // comment.
   comment_re = input_api.re.compile(r'//.*%s' % name_pattern)
+  # Describes @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+  annotation_re = input_api.re.compile(r'@VisibleForTesting\(otherwise')
   # Catch calls.
   inclusion_re = input_api.re.compile(r'(%s)\s*\(' % name_pattern)
   # Ignore definitions. (Comments are ignored separately.)
@@ -1516,6 +1518,7 @@
         continue
       if (inclusion_re.search(line) and
           not comment_re.search(line) and
+          not annotation_re.search(line) and
           not exclusion_re.search(line)):
         problems.append(
           '%s:%d\n    %s' % (local_path, line_number, line.strip()))
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py
index f3e928c..0a9e5a5 100644
--- a/PRESUBMIT_test_mocks.py
+++ b/PRESUBMIT_test_mocks.py
@@ -61,8 +61,6 @@
   """
 
   DEFAULT_FILES_TO_SKIP = ()
-  # TODO(https://crbug.com/1098562): Remove once no longer used)
-  DEFAULT_BLACK_LIST = ()
 
   def __init__(self):
     self.canned_checks = MockCannedChecks()
@@ -95,11 +93,7 @@
     return self.AffectedFiles(file_filter=file_filter)
 
   def FilterSourceFile(self, file,
-                       files_to_check=(), files_to_skip=(),
-                       # TODO(https://crbug.com/1098562): Remove once no longer used
-                       white_list=(), black_list=()):
-    files_to_check = files_to_check or white_list
-    files_to_skip = files_to_skip or black_list
+                       files_to_check=(), files_to_skip=()):
     local_path = file.LocalPath()
     found_in_files_to_check = not files_to_check
     if files_to_check:
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index f6e9de2..2973809 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -59,6 +59,7 @@
   standalone_system_webview_apk_tmpl("system_webview_base_bundle_module") {
     target_type = "android_app_bundle_module"
     is_base_module = true
+    bundle_target = ":system_webview_bundle"
 
     if (_verify_android_configuration) {
       expected_android_manifest =
@@ -101,6 +102,7 @@
       target_type = "android_app_bundle_module"
       include_64_bit_webview = false
       is_base_module = true
+      bundle_target = ":system_webview_32_bundle"
     }
 
     system_webview_bundle("system_webview_32_bundle") {
@@ -145,6 +147,7 @@
   trichrome_webview_tmpl("trichrome_webview_base_bundle_module") {
     target_type = "android_app_bundle_module"
     is_base_module = true
+    bundle_target = ":trichrome_webview_bundle"
 
     if (_verify_android_configuration) {
       expected_android_manifest =
@@ -225,6 +228,7 @@
     trichrome_webview_64_32_tmpl("trichrome_webview_64_32_base_bundle_module") {
       target_type = "android_app_bundle_module"
       is_base_module = true
+      bundle_target = ":trichrome_webview_64_32_bundle"
     }
 
     system_webview_bundle("trichrome_webview_64_32_bundle") {
@@ -238,6 +242,7 @@
     trichrome_webview_32_64_tmpl("trichrome_webview_32_64_base_bundle_module") {
       target_type = "android_app_bundle_module"
       is_base_module = true
+      bundle_target = ":trichrome_webview_32_64_bundle"
     }
 
     system_webview_bundle("trichrome_webview_32_64_bundle") {
@@ -275,6 +280,7 @@
     trichrome_webview_32_tmpl("trichrome_webview_32_base_bundle_module") {
       target_type = "android_app_bundle_module"
       is_base_module = true
+      bundle_target = ":trichrome_webview_32_bundle"
     }
 
     system_webview_bundle("trichrome_webview_32_bundle") {
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn
index 88b3944..fbb00eb 100644
--- a/android_webview/nonembedded/BUILD.gn
+++ b/android_webview/nonembedded/BUILD.gn
@@ -140,6 +140,7 @@
     "java/res_devui/layout/crashes_list_item_body.xml",
     "java/res_devui/layout/crashes_list_item_header.xml",
     "java/res_devui/layout/flag_states.xml",
+    "java/res_devui/layout/flag_ui_warning.xml",
     "java/res_devui/layout/fragment_crashes_list.xml",
     "java/res_devui/layout/fragment_flags.xml",
     "java/res_devui/layout/fragment_home.xml",
diff --git a/android_webview/nonembedded/java/res_devui/layout/flag_ui_warning.xml b/android_webview/nonembedded/java/res_devui/layout/flag_ui_warning.xml
new file mode 100644
index 0000000..9367e64e
--- /dev/null
+++ b/android_webview/nonembedded/java/res_devui/layout/flag_ui_warning.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/flag_ui_warning"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
+
+    <!--suppress HardcodedText -->
+    <TextView
+        android:id="@+id/flags_warning"
+        android:text="WARNING: EXPERIMENTAL FEATURES AHEAD!"
+        android:textColor="@color/error_red"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+    <TextView
+        android:id="@+id/flags_description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+</LinearLayout>
diff --git a/android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml b/android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml
index 69d6c8a..f8cee00 100644
--- a/android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml
+++ b/android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml
@@ -11,26 +11,8 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:padding="10dp">
-
-    <!--suppress HardcodedText -->
-    <TextView
-        android:id="@+id/flags_warning"
-        android:text="WARNING: EXPERIMENTAL FEATURES AHEAD!"
-        android:textColor="@color/error_red"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="5dp"
-        android:paddingTop="5dp"
-        android:textAppearance="?android:attr/textAppearanceLarge"/>
-
-    <TextView
-        android:id="@+id/flags_description"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="5dp"
-        android:paddingTop="5dp"
-        android:textAppearance="?android:attr/textAppearanceMedium"/>
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp">
 
     <!--suppress HardcodedText -->
     <Button
@@ -38,7 +20,8 @@
         android:id="@+id/reset_flags_button"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="5dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
         android:textAppearance="?android:attr/textAppearanceMedium"/>
 
     <!-- horizontal divider -->
diff --git a/android_webview/nonembedded/java/res_devui/layout/toggleable_flag.xml b/android_webview/nonembedded/java/res_devui/layout/toggleable_flag.xml
index deedc1c..640cd65 100644
--- a/android_webview/nonembedded/java/res_devui/layout/toggleable_flag.xml
+++ b/android_webview/nonembedded/java/res_devui/layout/toggleable_flag.xml
@@ -10,7 +10,6 @@
     android:id="@+id/toggleable_flag"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginTop="15dp"
     android:orientation="vertical">
 
     <!-- A compound drawable will be populated at runtime, but it's OK to configure drawablePadding now. -->
@@ -22,8 +21,8 @@
         android:textStyle="bold"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:drawablePadding="4dp"
-        android:paddingBottom="2dp"
-        android:paddingTop="2dp" />
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp"/>
 
     <TextView
         android:id="@+id/flag_description"
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
index 6112247..cb7b40f 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
@@ -24,6 +24,9 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+
 import org.chromium.android_webview.common.DeveloperModeUtils;
 import org.chromium.android_webview.common.Flag;
 import org.chromium.android_webview.common.ProductionSupportedFlagList;
@@ -73,10 +76,6 @@
         activity.setTitle("WebView Flags");
 
         ListView flagsListView = view.findViewById(R.id.flags_list);
-        TextView flagsDescriptionView = view.findViewById(R.id.flags_description);
-        flagsDescriptionView.setText("By enabling these features, you could "
-                + "lose app data or compromise your security or privacy. Enabled features apply to "
-                + "WebViews across all apps on the device.");
 
         // Restore flag overrides from the service process to repopulate the UI, if developer mode
         // is enabled.
@@ -84,7 +83,13 @@
             mOverriddenFlags = DeveloperModeUtils.getFlagOverrides(mContext.getPackageName());
         }
 
-        mListAdapter = new FlagsListAdapter(sortFlagList(ProductionSupportedFlagList.sFlagList));
+        Flag[] sortedFlags = sortFlagList(ProductionSupportedFlagList.sFlagList);
+        Flag[] flagsAndWarningText = new Flag[ProductionSupportedFlagList.sFlagList.length + 1];
+        flagsAndWarningText[0] = null; // the first entry is the warning text
+        for (int i = 0; i < ProductionSupportedFlagList.sFlagList.length; i++) {
+            flagsAndWarningText[i + 1] = sortedFlags[i];
+        }
+        mListAdapter = new FlagsListAdapter(flagsAndWarningText);
         flagsListView.setAdapter(mListAdapter);
 
         Button resetFlagsButton = view.findViewById(R.id.reset_flags_button);
@@ -163,16 +168,22 @@
         public void onNothingSelected(AdapterView<?> parent) {}
     }
 
+    @IntDef({LayoutType.WARNING_MESSAGE, LayoutType.TOGGLEABLE_FLAG})
+    private @interface LayoutType {
+        int WARNING_MESSAGE = 0;
+        int TOGGLEABLE_FLAG = 1;
+        int COUNT = 2;
+    }
+
     /**
      * Adapter to create rows of toggleable Flags.
      */
     private class FlagsListAdapter extends ArrayAdapter<Flag> {
-        public FlagsListAdapter(Flag[] sortedFlags) {
-            super(mContext, R.layout.toggleable_flag, sortedFlags);
+        public FlagsListAdapter(Flag[] flagsAndWarningText) {
+            super(mContext, 0, flagsAndWarningText);
         }
 
-        @Override
-        public View getView(int position, View view, ViewGroup parent) {
+        private View getToggleableFlag(@NonNull Flag flag, View view, ViewGroup parent) {
             // If the the old view is already created then reuse it, else create a new one by layout
             // inflation.
             if (view == null) {
@@ -183,7 +194,6 @@
             TextView flagDescription = view.findViewById(R.id.flag_description);
             Spinner flagToggle = view.findViewById(R.id.flag_toggle);
 
-            Flag flag = getItem(position);
             String label = flag.getName();
             if (flag.getEnabledStateValue() != null) {
                 label += "=" + flag.getEnabledStateValue();
@@ -203,6 +213,43 @@
 
             return view;
         }
+
+        private View getWarningMessage(View view, ViewGroup parent) {
+            // If the the old view is already created then reuse it, else create a new one by layout
+            // inflation.
+            if (view == null) {
+                view = getLayoutInflater().inflate(R.layout.flag_ui_warning, null);
+            }
+
+            TextView flagsDescriptionView = view.findViewById(R.id.flags_description);
+            flagsDescriptionView.setText("By enabling these features, you could "
+                    + "lose app data or compromise your security or privacy. Enabled features "
+                    + "apply to WebViews across all apps on the device.");
+
+            return view;
+        }
+
+        @Override
+        @LayoutType
+        public int getItemViewType(int position) {
+            if (getItem(position) == null) return LayoutType.WARNING_MESSAGE;
+            return LayoutType.TOGGLEABLE_FLAG;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return LayoutType.COUNT;
+        }
+
+        @Override
+        public View getView(int position, View view, ViewGroup parent) {
+            Flag flag = getItem(position);
+            if (getItemViewType(position) == LayoutType.WARNING_MESSAGE) {
+                return getWarningMessage(view, parent);
+            } else {
+                return getToggleableFlag(flag, view, parent);
+            }
+        }
     }
 
     /**
diff --git a/ash/login/parent_access_controller.cc b/ash/login/parent_access_controller.cc
index 407b6ea..e18df07 100644
--- a/ash/login/parent_access_controller.cc
+++ b/ash/login/parent_access_controller.cc
@@ -23,6 +23,7 @@
 base::string16 GetTitle(ParentAccessRequestReason reason) {
   int title_id;
   switch (reason) {
+    case ParentAccessRequestReason::kOnlineLogin:
     case ParentAccessRequestReason::kUnlockTimeLimits:
       title_id = IDS_ASH_LOGIN_PARENT_ACCESS_TITLE;
       break;
@@ -39,6 +40,7 @@
 base::string16 GetDescription(ParentAccessRequestReason reason) {
   int description_id;
   switch (reason) {
+    case ParentAccessRequestReason::kOnlineLogin:
     case ParentAccessRequestReason::kUnlockTimeLimits:
       description_id = IDS_ASH_LOGIN_PARENT_ACCESS_DESCRIPTION;
       break;
@@ -71,8 +73,16 @@
                             action);
 }
 
-void RecordParentAccessUsage(ParentAccessRequestReason reason) {
+void RecordParentAccessUsage(const AccountId& child_account_id,
+                             ParentAccessRequestReason reason) {
   switch (reason) {
+    case ParentAccessRequestReason::kOnlineLogin:
+      UMA_HISTOGRAM_ENUMERATION(
+          ParentAccessController::kUMAParentAccessCodeUsage,
+          child_account_id.empty()
+              ? ParentAccessController::UMAUsage::kAddUserLoginScreen
+              : ParentAccessController::UMAUsage::kReauhLoginScreen);
+      return;
     case ParentAccessRequestReason::kUnlockTimeLimits: {
       UMA_HISTOGRAM_ENUMERATION(
           ParentAccessController::kUMAParentAccessCodeUsage,
@@ -160,7 +170,7 @@
   request.description = GetDescription(reason);
   request.accessible_title = GetAccessibleTitle();
   PinRequestWidget::Show(std::move(request), this);
-  RecordParentAccessUsage(reason);
+  RecordParentAccessUsage(account_id_, reason);
   return true;
 }
 
diff --git a/ash/login/parent_access_controller.h b/ash/login/parent_access_controller.h
index 12b6dde..51d39a5 100644
--- a/ash/login/parent_access_controller.h
+++ b/ash/login/parent_access_controller.h
@@ -35,7 +35,9 @@
     kTimeChangeLoginScreen = 1,
     kTimeChangeInSession = 2,
     kTimezoneChange = 3,
-    kMaxValue = kTimezoneChange,
+    kAddUserLoginScreen = 4,
+    kReauhLoginScreen = 5,
+    kMaxValue = kReauhLoginScreen,
   };
 
   // Histogram to log actions that originated in parent access dialog.
diff --git a/ash/login/parent_access_controller_unittest.cc b/ash/login/parent_access_controller_unittest.cc
index 7d7dd3e..b7568d2 100644
--- a/ash/login/parent_access_controller_unittest.cc
+++ b/ash/login/parent_access_controller_unittest.cc
@@ -57,9 +57,14 @@
 
   void StartParentAccess(ParentAccessRequestReason reason =
                              ParentAccessRequestReason::kUnlockTimeLimits) {
+    StartParentAccess(account_id_, reason);
+  }
+
+  void StartParentAccess(const AccountId& account_id,
+                         ParentAccessRequestReason reason) {
     validation_time_ = base::Time::Now();
     controller_->ShowWidget(
-        account_id_,
+        account_id,
         base::BindOnce(&ParentAccessControllerTest::OnFinished,
                        base::Unretained(this)),
         reason, false, validation_time_);
@@ -182,9 +187,29 @@
   ExpectUMAActionReported(ParentAccessController::UMAAction::kCanceledByUser, 5,
                           5);
 
+  GetSessionControllerClient()->SetSessionState(
+      session_manager::SessionState::LOGIN_PRIMARY);
+  StartParentAccess(ParentAccessRequestReason::kOnlineLogin);
+  histogram_tester_.ExpectBucketCount(
+      ParentAccessController::kUMAParentAccessCodeUsage,
+      ParentAccessController::UMAUsage::kReauhLoginScreen, 1);
+  SimulateButtonPress(PinRequestView::TestApi(view_).back_button());
+  ExpectUMAActionReported(ParentAccessController::UMAAction::kCanceledByUser, 6,
+                          6);
+
+  GetSessionControllerClient()->SetSessionState(
+      session_manager::SessionState::LOGIN_PRIMARY);
+  StartParentAccess(EmptyAccountId(), ParentAccessRequestReason::kOnlineLogin);
+  histogram_tester_.ExpectBucketCount(
+      ParentAccessController::kUMAParentAccessCodeUsage,
+      ParentAccessController::UMAUsage::kAddUserLoginScreen, 1);
+  SimulateButtonPress(PinRequestView::TestApi(view_).back_button());
+  ExpectUMAActionReported(ParentAccessController::UMAAction::kCanceledByUser, 7,
+                          7);
+
   histogram_tester_.ExpectTotalCount(
-      ParentAccessController::kUMAParentAccessCodeUsage, 5);
-  EXPECT_EQ(5, back_action_);
+      ParentAccessController::kUMAParentAccessCodeUsage, 7);
+  EXPECT_EQ(7, back_action_);
 }
 
 // Tests successful parent access validation flow.
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index 9f1d001..5b456c9 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -55,6 +55,7 @@
 #include "chromeos/components/proximity_auth/public/mojom/auth_type.mojom.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
+#include "components/user_manager/known_user.h"
 #include "components/user_manager/user_type.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -932,6 +933,8 @@
   }
 
   state->show_pin = enabled;
+  state->autosubmit_pin_length =
+      user_manager::known_user::GetUserPinLength(user);
 
   LoginBigUserView* big_user =
       TryToFindBigUser(user, true /*require_auth_active*/);
@@ -1773,7 +1776,7 @@
       UserState* state = FindStateForUser(
           view->auth_user()->current_user().basic_user_info.account_id);
       uint32_t to_update_auth;
-      bool show_pinpad = false;
+      LoginAuthUserView::AuthMethodsMetadata auth_metadata;
       if (state->force_online_sign_in) {
         to_update_auth = LoginAuthUserView::AUTH_ONLINE_SIGN_IN;
       } else if (state->disable_auth) {
@@ -1788,10 +1791,10 @@
         // visible, but the keyboard is in a different root window or the view
         // has not been added to the widget. In these cases, the keyboard does
         // not interfere with PIN entry.
-        const bool is_keyboard_visible_for_view =
+        auth_metadata.virtual_keyboard_visible =
             GetKeyboardControllerForView() ? keyboard_shown_ : false;
-        show_pinpad = !is_keyboard_visible_for_view &&
-                      (state->show_pin || state->show_pin_pad_for_password);
+        auth_metadata.show_pinpad_for_pw = state->show_pin_pad_for_password;
+        auth_metadata.autosubmit_pin_length = state->autosubmit_pin_length;
         if (state->show_pin)
           to_update_auth |= LoginAuthUserView::AUTH_PIN;
         if (state->enable_tap_auth)
@@ -1799,7 +1802,7 @@
         if (state->fingerprint_state != FingerprintState::UNAVAILABLE)
           to_update_auth |= LoginAuthUserView::AUTH_FINGERPRINT;
       }
-      view->auth_user()->SetAuthMethods(to_update_auth, show_pinpad);
+      view->auth_user()->SetAuthMethods(to_update_auth, auth_metadata);
     } else if (view->public_account()) {
       view->public_account()->SetAuthEnabled(true /*enabled*/, animate);
     }
@@ -1809,8 +1812,7 @@
     if (!view)
       return;
     if (view->auth_user()) {
-      view->auth_user()->SetAuthMethods(LoginAuthUserView::AUTH_NONE,
-                                        false /*show_pinpad*/);
+      view->auth_user()->SetAuthMethods(LoginAuthUserView::AUTH_NONE);
     } else if (view->public_account()) {
       view->public_account()->SetAuthEnabled(false /*enabled*/, animate);
     }
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h
index 37d68ed..750e493c 100644
--- a/ash/login/ui/lock_contents_view.h
+++ b/ash/login/ui/lock_contents_view.h
@@ -248,6 +248,7 @@
     bool force_online_sign_in = false;
     bool disable_auth = false;
     bool show_pin_pad_for_password = false;
+    size_t autosubmit_pin_length = 0;
     base::Optional<EasyUnlockIconOptions> easy_unlock_state;
     FingerprintState fingerprint_state;
 
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc
index 875560a..c358846 100644
--- a/ash/login/ui/login_auth_user_view.cc
+++ b/ash/login/ui/login_auth_user_view.cc
@@ -745,8 +745,8 @@
     non_pin_y_start_in_screen = view->GetBoundsInScreen().y();
     pin_start_in_screen = view->pin_view_->GetBoundsInScreen().origin();
 
-    had_pinpad = view->show_pinpad_;
-    had_password = view->HasAuthMethod(LoginAuthUserView::AUTH_PASSWORD);
+    had_pinpad = view->ShouldShowPinPad();
+    had_password = view->ShouldShowPasswordField();
     had_fingerprint = view->HasAuthMethod(LoginAuthUserView::AUTH_FINGERPRINT);
   }
 
@@ -978,21 +978,23 @@
   add_padding(kDistanceFromPinKeyboardToBigUserViewBottomDp);
 
   // Update authentication UI.
-  SetAuthMethods(auth_methods_, false /*show_pinpad*/);
+  SetAuthMethods(auth_methods_);
   user_view_->UpdateForUser(user, false /*animate*/);
 }
 
 LoginAuthUserView::~LoginAuthUserView() = default;
 
 void LoginAuthUserView::SetAuthMethods(uint32_t auth_methods,
-                                       bool show_pinpad) {
-  show_pinpad_ = show_pinpad;
+                                       AuthMethodsMetadata auth_metadata) {
   bool had_password = HasAuthMethod(AUTH_PASSWORD);
 
+  // Apply changes and determine the new state of input fields.
   auth_methods_ = static_cast<AuthMethods>(auth_methods);
-  bool has_password = HasAuthMethod(AUTH_PASSWORD);
-  bool has_pin = HasAuthMethod(AUTH_PIN);
-  bool has_tap = HasAuthMethod(AUTH_TAP);
+  auth_metadata_ = auth_metadata;
+  UpdateInputFieldMode();
+
+  bool has_password = ShouldShowPasswordField();
+  bool has_pinpad = ShouldShowPinPad();
   bool force_online_sign_in = HasAuthMethod(AUTH_ONLINE_SIGN_IN);
   bool has_fingerprint = HasAuthMethod(AUTH_FINGERPRINT);
   bool has_challenge_response = HasAuthMethod(AUTH_CHALLENGE_RESPONSE);
@@ -1008,10 +1010,10 @@
   // Adjust the PIN keyboard visibility before the password textfield's one, so
   // that when both are about to be hidden the focus doesn't jump to the "1"
   // keyboard button, causing unexpected accessibility effects.
-  pin_view_->SetVisible(show_pinpad);
+  pin_view_->SetVisible(has_pinpad);
 
   password_view_->SetEnabled(has_password);
-  password_view_->SetEnabledOnEmptyPassword(has_tap);
+  password_view_->SetEnabledOnEmptyPassword(HasAuthMethod(AUTH_TAP));
   password_view_->SetFocusEnabledForChildViews(has_password);
   password_view_->SetVisible(!hide_auth && has_password);
   password_view_->layer()->SetOpacity(has_password ? 1 : 0);
@@ -1021,31 +1023,20 @@
     password_view_->RequestFocus();
 
   fingerprint_view_->SetVisible(has_fingerprint);
-  fingerprint_view_->SetCanUsePin(has_pin);
+  fingerprint_view_->SetCanUsePin(HasAuthMethod(AUTH_PIN));
   challenge_response_view_->SetVisible(has_challenge_response);
 
   int padding_view_height = kDistanceBetweenPasswordFieldAndPinKeyboardDp;
-  if (has_fingerprint && !show_pinpad) {
+  if (has_fingerprint && !has_pinpad) {
     padding_view_height = kDistanceBetweenPasswordFieldAndFingerprintViewDp;
-  } else if (has_challenge_response && !show_pinpad) {
+  } else if (has_challenge_response && !has_pinpad) {
     padding_view_height =
         kDistanceBetweenPasswordFieldAndChallengeResponseViewDp;
   }
   padding_below_password_view_->SetPreferredSize(
       gfx::Size(kNonEmptyWidthDp, padding_view_height));
 
-  // Note: |has_tap| must have higher priority than |has_pin| when
-  // determining the placeholder.
-  if (has_tap) {
-    password_view_->SetPlaceholderText(
-        l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_TAP_PLACEHOLDER));
-  } else if (has_pin) {
-    password_view_->SetPlaceholderText(
-        l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_PIN_PLACEHOLDER));
-  } else {
-    password_view_->SetPlaceholderText(
-        l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_PLACEHOLDER));
-  }
+  password_view_->SetPlaceholderText(GetPasswordViewPlaceholder());
   const std::string& user_display_email =
       current_user().basic_user_info.display_email;
   password_view_->SetAccessibleName(l10n_util::GetStringFUTF16(
@@ -1055,8 +1046,8 @@
   // Only the active auth user view has a password displayed. If that is the
   // case, then render the user view as if it was always focused, since clicking
   // on it will not do anything (such as swapping users).
-  user_view_->SetForceOpaque(has_password || hide_auth);
-  user_view_->SetTapEnabled(!has_password);
+  user_view_->SetForceOpaque(HasAuthMethod(AUTH_PASSWORD) || hide_auth);
+  user_view_->SetTapEnabled(!HasAuthMethod(AUTH_PASSWORD));
   // Tapping the user view will trigger the online sign-in flow when
   // |force_online_sign_in| is true.
   if (force_online_sign_in)
@@ -1105,8 +1096,9 @@
 void LoginAuthUserView::ApplyAnimationPostLayout() {
   DCHECK(cached_animation_state_);
 
-  bool has_password = HasAuthMethod(AUTH_PASSWORD);
-  bool has_pinpad = show_pinpad_;
+  bool has_password = ShouldShowPasswordField();
+  bool had_password = cached_animation_state_->had_password;
+  bool has_pinpad = ShouldShowPinPad();
   bool has_fingerprint = HasAuthMethod(AUTH_FINGERPRINT);
 
   ////////
@@ -1139,12 +1131,12 @@
   ////////
   // Fade the password view if it is being hidden or shown.
 
-  if (cached_animation_state_->had_password != has_password) {
+  if (had_password != has_password) {
     float opacity_start = 0, opacity_end = 1;
     if (!has_password)
       std::swap(opacity_start, opacity_end);
 
-    if (cached_animation_state_->had_password)
+    if (had_password)
       password_view_->SetVisible(true);
 
     password_view_->layer()->SetOpacity(opacity_start);
@@ -1155,7 +1147,7 @@
       settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
           login_constants::kChangeUserAnimationDurationMs));
       settings.SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN);
-      if (cached_animation_state_->had_password && !has_password) {
+      if (had_password && !has_password) {
         settings.AddObserver(
             new ClearPasswordAndHideAnimationObserver(password_view_));
       }
@@ -1361,4 +1353,49 @@
                          weak_factory_.GetWeakPtr()));
 }
 
+void LoginAuthUserView::UpdateInputFieldMode() {
+  if (!HasAuthMethod(AUTH_PASSWORD)) {
+    input_field_mode_ = InputFieldMode::DISABLED;
+    return;
+  }
+  if (!HasAuthMethod(AUTH_PIN)) {
+    input_field_mode_ = InputFieldMode::PASSWORD_ONLY;
+    return;
+  }
+
+  input_field_mode_ = InputFieldMode::PIN_AND_PASSWORD;
+  return;
+}
+
+bool LoginAuthUserView::ShouldShowPinPad() const {
+  if (auth_metadata_.virtual_keyboard_visible)
+    return false;
+  switch (input_field_mode_) {
+    case InputFieldMode::DISABLED:
+      return false;
+    case InputFieldMode::PASSWORD_ONLY:
+      return auth_metadata_.show_pinpad_for_pw;
+    case InputFieldMode::PIN_AND_PASSWORD:
+      return true;
+  }
+}
+
+bool LoginAuthUserView::ShouldShowPasswordField() const {
+  return input_field_mode_ == InputFieldMode::PASSWORD_ONLY ||
+         input_field_mode_ == InputFieldMode::PIN_AND_PASSWORD;
+}
+
+base::string16 LoginAuthUserView::GetPasswordViewPlaceholder() const {
+  // Note: |AUTH_TAP| must have higher priority than |AUTH_PIN| when
+  // determining the placeholder.
+  if (HasAuthMethod(AUTH_TAP))
+    return l10n_util::GetStringUTF16(
+        IDS_ASH_LOGIN_POD_PASSWORD_TAP_PLACEHOLDER);
+  if (input_field_mode_ == InputFieldMode::PIN_AND_PASSWORD)
+    return l10n_util::GetStringUTF16(
+        IDS_ASH_LOGIN_POD_PASSWORD_PIN_PLACEHOLDER);
+
+  return l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_PLACEHOLDER);
+}
+
 }  // namespace ash
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h
index 33aca56..e38ff89 100644
--- a/ash/login/ui/login_auth_user_view.h
+++ b/ash/login/ui/login_auth_user_view.h
@@ -53,6 +53,26 @@
                              // message to user.
   };
 
+  // Extra control parameters to be passed when setting the auth methods.
+  struct AuthMethodsMetadata {
+    explicit AuthMethodsMetadata() {}
+    // If the virtual keyboard is visible, the pinpad is hidden.
+    bool virtual_keyboard_visible = false;
+    // Whether to show the pinpad for the password field.
+    bool show_pinpad_for_pw = false;
+    // User's pin length to use for autosubmit.
+    size_t autosubmit_pin_length = 0;
+  };
+
+  // Possible states that the input field might be in.
+  // This is determined by the current authentication methods
+  // that a user has.
+  enum class InputFieldMode {
+    DISABLED,          // Not showing any input field.
+    PASSWORD_ONLY,     // No PIN set. Password only field.
+    PIN_AND_PASSWORD,  // PIN set.
+  };
+
   // TestApi is used for tests to get internal implementation details.
   class ASH_EXPORT TestApi {
    public:
@@ -104,10 +124,13 @@
   ~LoginAuthUserView() override;
 
   // Set the displayed set of auth methods. |auth_methods| contains or-ed
-  // together AuthMethod values. |show_pinpad| determines whether the pin pad
-  // should be visible.
-  void SetAuthMethods(uint32_t auth_methods, bool show_pinpad);
+  // together AuthMethod values. |auth_metadata| provides additional control
+  // parameters for the view.
+  void SetAuthMethods(
+      uint32_t auth_methods,
+      AuthMethodsMetadata auth_metadata = AuthMethodsMetadata());
   AuthMethods auth_methods() const { return auth_methods_; }
+  InputFieldMode input_field_mode() const { return input_field_mode_; }
 
   // Add an easy unlock icon.
   void SetEasyUnlockIcon(EasyUnlockIconId id,
@@ -183,10 +206,24 @@
   // starts the asynchronous authentication process against a security token.
   void AttemptAuthenticateWithChallengeResponse();
 
-  AuthMethods auth_methods_ = AUTH_NONE;
+  // Determines the mode of the input field based on the available
+  // authentication methods.
+  void UpdateInputFieldMode();
 
-  // Whether to show the pinpad. Sometimes hidden by the on screen keyboard
-  bool show_pinpad_ = false;
+  // Convenience methods to determine element visibility.
+  bool ShouldShowPinPad() const;
+  bool ShouldShowPasswordField() const;
+
+  // Convenience methods to determine UI text based on the InputFieldMode.
+  base::string16 GetPasswordViewPlaceholder() const;
+
+  // Authentication methods available and extra parameters that control the UI.
+  AuthMethods auth_methods_ = AUTH_NONE;
+  AuthMethodsMetadata auth_metadata_ = AuthMethodsMetadata();
+
+  // Controls which input field is currently being shown.
+  InputFieldMode input_field_mode_ = InputFieldMode::DISABLED;
+
   LoginUserView* user_view_ = nullptr;
   LoginPasswordView* password_view_ = nullptr;
   NonAccessibleView* password_view_container_ = nullptr;
diff --git a/ash/login/ui/login_auth_user_view_unittest.cc b/ash/login/ui/login_auth_user_view_unittest.cc
index cc3f8d2..1f8ea15 100644
--- a/ash/login/ui/login_auth_user_view_unittest.cc
+++ b/ash/login/ui/login_auth_user_view_unittest.cc
@@ -57,8 +57,15 @@
     SetWidget(CreateWidgetWithContent(container_));
   }
 
-  void SetAuthMethods(uint32_t auth_methods, bool show_pinpad) {
-    view_->SetAuthMethods(auth_methods, show_pinpad);
+  void SetAuthMethods(uint32_t auth_methods,
+                      bool show_pinpad_for_pw = false,
+                      bool virtual_keyboard_visible = false,
+                      size_t autosubmit_pin_length = 0) {
+    LoginAuthUserView::AuthMethodsMetadata auth_metadata;
+    auth_metadata.show_pinpad_for_pw = show_pinpad_for_pw;
+    auth_metadata.virtual_keyboard_visible = virtual_keyboard_visible;
+    auth_metadata.autosubmit_pin_length = autosubmit_pin_length;
+    view_->SetAuthMethods(auth_methods, auth_metadata);
   }
 
   LoginUserInfo user_;
@@ -74,7 +81,8 @@
 // Verifies showing the PIN keyboard makes the user view grow.
 TEST_F(LoginAuthUserViewUnittest, ShowingPinExpandsView) {
   gfx::Size start_size = view_->size();
-  SetAuthMethods(LoginAuthUserView::AUTH_PIN, true /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD |
+                 LoginAuthUserView::AUTH_PIN);
   container_->Layout();
   gfx::Size expanded_size = view_->size();
   EXPECT_GT(expanded_size.height(), start_size.height());
@@ -94,11 +102,11 @@
   EXPECT_FALSE(auth_test.user_view()->HasFocus());
 
   // If the user view is showing a password it must be opaque.
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD);
   EXPECT_TRUE(user_test.is_opaque());
-  SetAuthMethods(LoginAuthUserView::AUTH_NONE, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_NONE);
   EXPECT_FALSE(user_test.is_opaque());
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD);
   EXPECT_TRUE(user_test.is_opaque());
 }
 
@@ -118,8 +126,8 @@
   EXPECT_CALL(*client,
               AuthenticateUserWithEasyUnlock(
                   user_view->current_user().basic_user_info.account_id));
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | LoginAuthUserView::AUTH_TAP,
-                 false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD |
+                 LoginAuthUserView::AUTH_TAP);
   password_view->Clear();
 
   generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0);
@@ -137,7 +145,7 @@
 
   // When auth method is |AUTH_ONLINE_SIGN_IN|, the online sign-in message is
   // visible. The password field and PIN keyboard are invisible.
-  SetAuthMethods(LoginAuthUserView::AUTH_ONLINE_SIGN_IN, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_ONLINE_SIGN_IN);
   EXPECT_TRUE(online_sign_in_message->GetVisible());
   EXPECT_FALSE(password_view->GetVisible());
   EXPECT_FALSE(pin_view->GetVisible());
@@ -152,13 +160,13 @@
   base::RunLoop().RunUntilIdle();
 
   // The online sign-in message is invisible for all other auth methods.
-  SetAuthMethods(LoginAuthUserView::AUTH_NONE, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_NONE);
   EXPECT_FALSE(online_sign_in_message->GetVisible());
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD);
   EXPECT_FALSE(online_sign_in_message->GetVisible());
-  SetAuthMethods(LoginAuthUserView::AUTH_PIN, true /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PIN);
   EXPECT_FALSE(online_sign_in_message->GetVisible());
-  SetAuthMethods(LoginAuthUserView::AUTH_TAP, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_TAP);
   EXPECT_FALSE(online_sign_in_message->GetVisible());
 }
 
@@ -171,20 +179,20 @@
   };
 
   // Set a password.
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD);
   password_test.textfield()->SetText(base::ASCIIToUTF16("Hello"));
 
   // Enable some other auth method (PIN), password is not cleared.
   view_->CaptureStateForAnimationPreLayout();
-  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | LoginAuthUserView::AUTH_PIN,
-                 true /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD |
+                 LoginAuthUserView::AUTH_PIN);
   EXPECT_TRUE(has_password());
   view_->ApplyAnimationPostLayout();
   EXPECT_TRUE(has_password());
 
   // Disable password, password is cleared.
   view_->CaptureStateForAnimationPreLayout();
-  SetAuthMethods(LoginAuthUserView::AUTH_NONE, false /*show_pinpad*/);
+  SetAuthMethods(LoginAuthUserView::AUTH_NONE);
   EXPECT_TRUE(has_password());
   view_->ApplyAnimationPostLayout();
   EXPECT_FALSE(has_password());
diff --git a/ash/public/cpp/login_types.h b/ash/public/cpp/login_types.h
index ddeeb36..140f743 100644
--- a/ash/public/cpp/login_types.h
+++ b/ash/public/cpp/login_types.h
@@ -341,6 +341,8 @@
   kChangeTime,
   // Update values on the timezone settings page.
   kChangeTimezone,
+  // Online login flow.
+  kOnlineLogin,
 };
 
 // Parameters and callbacks for a security token PIN request that is to be shown
diff --git a/base/BUILD.gn b/base/BUILD.gn
index e4ca016..0b0f01a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2122,6 +2122,7 @@
       "trace_event/trace_config.h",
       "trace_event/trace_config_category_filter.cc",
       "trace_event/trace_config_category_filter.h",
+      "trace_event/trace_conversion_helper.h",
       "trace_event/trace_event.h",
       "trace_event/trace_event_filter.cc",
       "trace_event/trace_event_filter.h",
@@ -3318,6 +3319,7 @@
       "trace_event/trace_arguments_unittest.cc",
       "trace_event/trace_category_unittest.cc",
       "trace_event/trace_config_unittest.cc",
+      "trace_event/trace_conversion_helper_unittest.cc",
       "trace_event/trace_event_filter_test_utils.cc",
       "trace_event/trace_event_filter_test_utils.h",
       "trace_event/trace_event_unittest.cc",
diff --git a/base/PRESUBMIT.py b/base/PRESUBMIT.py
index 0303041..33ec547 100644
--- a/base/PRESUBMIT.py
+++ b/base/PRESUBMIT.py
@@ -43,10 +43,10 @@
     r'^#include "base/trace_event/(?!base_tracing\.h)',
   ]
 
-  white_list = [
+  files_to_check = [
     r".*\.(h|cc|mm)$",
   ]
-  black_list = [
+  files_to_skip = [
     r".*[\\/]test[\\/].*",
     r".*[\\/]trace_event[\\/].*",
     r".*[\\/]tracing[\\/].*",
@@ -56,8 +56,8 @@
   def FilterFile(affected_file):
     return input_api.FilterSourceFile(
       affected_file,
-      white_list=white_list,
-      black_list=black_list)
+      files_to_check=files_to_check,
+      files_to_skip=files_to_skip)
 
   locations = []
   for f in input_api.AffectedSourceFiles(FilterFile):
diff --git a/base/android/java/src/org/chromium/base/IntentUtils.java b/base/android/java/src/org/chromium/base/IntentUtils.java
index 70c20c9..8e64fbd 100644
--- a/base/android/java/src/org/chromium/base/IntentUtils.java
+++ b/base/android/java/src/org/chromium/base/IntentUtils.java
@@ -365,7 +365,6 @@
      * Creates a temporary copy of the extra Bundle, which is required as
      * Intent#getBinderExtra() doesn't exist, but Bundle.getBinder() does.
      */
-    @VisibleForTesting
     public static IBinder safeGetBinderExtra(Intent intent, String name) {
         if (!intent.hasExtra(name)) return null;
         Bundle extras = intent.getExtras();
@@ -381,7 +380,6 @@
      * @param name Key.
      * @param binder Binder object.
      */
-    @VisibleForTesting
     public static void safePutBinderExtra(Intent intent, String name, IBinder binder) {
         if (intent == null) return;
         Bundle bundle = new Bundle();
diff --git a/base/android/java/src/org/chromium/base/ThreadUtils.java b/base/android/java/src/org/chromium/base/ThreadUtils.java
index fd49999..b81c04f 100644
--- a/base/android/java/src/org/chromium/base/ThreadUtils.java
+++ b/base/android/java/src/org/chromium/base/ThreadUtils.java
@@ -8,8 +8,6 @@
 import android.os.Looper;
 import android.os.Process;
 
-import androidx.annotation.VisibleForTesting;
-
 import org.chromium.base.annotations.CalledByNative;
 
 import java.util.concurrent.Callable;
@@ -174,7 +172,6 @@
      * @return The result of the callable
      */
     @Deprecated
-    @VisibleForTesting
     public static <T> T runOnUiThreadBlockingNoException(Callable<T> c) {
         try {
             return runOnUiThreadBlocking(c);
@@ -310,7 +307,6 @@
      * @param task The Runnable to run
      * @param delayMillis The delay in milliseconds until the Runnable will be run
      */
-    @VisibleForTesting
     @Deprecated
     public static void postOnUiThreadDelayed(Runnable task, long delayMillis) {
         getUiThreadHandler().postDelayed(task, delayMillis);
diff --git a/base/debug/elf_reader_unittest.cc b/base/debug/elf_reader_unittest.cc
index 5226d89..5cba894 100644
--- a/base/debug/elf_reader_unittest.cc
+++ b/base/debug/elf_reader_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/debug/test_elf_image_builder.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/native_library.h"
-#include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -162,10 +161,6 @@
     case TestElfImageBuilder::NON_RELOCATABLE:
       EXPECT_EQ(0u, GetRelocationOffset(image.elf_start()));
       break;
-
-    default:
-      NOTREACHED();
-      break;
   }
 }
 
diff --git a/base/trace_event/trace_conversion_helper.h b/base/trace_event/trace_conversion_helper.h
new file mode 100644
index 0000000..44b84aa
--- /dev/null
+++ b/base/trace_event/trace_conversion_helper.h
@@ -0,0 +1,111 @@
+// Copyright 2020 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 BASE_TRACE_EVENT_TRACE_CONVERSION_HELPER_H_
+#define BASE_TRACE_EVENT_TRACE_CONVERSION_HELPER_H_
+
+#include <sstream>
+#include <string>
+
+#include "base/strings/string_number_conversions.h"
+
+namespace base {
+
+namespace trace_event {
+
+// Helpers for base::trace_event::ValueToString.
+namespace internal {
+
+// Return std::string representation given by |value|'s ostream operator<<.
+template <typename ValueType>
+std::string OstreamValueToString(const ValueType& value) {
+  std::stringstream ss;
+  ss << value;
+  return ss.str();
+}
+
+// Helper class to mark call priority. Lower number has precedence:
+//
+// Example:
+//   void foo(ValueToStringPriority<1>);
+//   void foo(ValueToStringPriority<3>);
+//   foo(ValueToStringPriority<0>());  // Calls |foo(ValueToStringPriority<1>)|.
+template <int N>
+class ValueToStringPriority : public ValueToStringPriority<N + 1> {};
+template <>
+// The number must be the same as in the fallback version of
+// |ValueToStringHelper|.
+class ValueToStringPriority<4> {};
+
+// Use SFINAE to decide how to extract a string from the given parameter.
+
+// Check if |value| can be used as a parameter of |base::NumberToString|. If
+// std::string is not constructible from the returned value of
+// |base::NumberToString| cause compilation error.
+//
+// |base::NumberToString| does not do locale specific formatting and should be
+// faster than using |std::ostream::operator<<|.
+template <typename ValueType>
+decltype(base::NumberToString(std::declval<const ValueType>()), std::string())
+ValueToStringHelper(ValueToStringPriority<0>,
+                    const ValueType& value,
+                    std::string /* unused */) {
+  return base::NumberToString(value);
+}
+
+// If there is |ValueType::ToString| whose return value can be used to construct
+// |std::string|, use this. Else use other methods.
+template <typename ValueType>
+decltype(std::string(std::declval<const ValueType>().ToString()))
+ValueToStringHelper(ValueToStringPriority<1>,
+                    const ValueType& value,
+                    std::string /* unused */) {
+  return value.ToString();
+}
+
+// If |std::ostream::operator<<| can be used, use it. Useful for |void*|.
+template <typename ValueType>
+decltype(
+    std::declval<std::ostream>().operator<<(std::declval<const ValueType>()),
+    std::string())
+ValueToStringHelper(ValueToStringPriority<2>,
+                    const ValueType& value,
+                    std::string /* unused */) {
+  return OstreamValueToString(value);
+}
+
+// Use |ValueType::operator<<| if applicable.
+template <typename ValueType>
+decltype(operator<<(std::declval<std::ostream&>(),
+                    std::declval<const ValueType>()),
+         std::string())
+ValueToStringHelper(ValueToStringPriority<3>,
+                    const ValueType& value,
+                    std::string /* unused */) {
+  return OstreamValueToString(value);
+}
+
+// Fallback returns the |fallback_value|. Needs to have |ValueToStringPriority|
+// with the highest number (to be called last).
+template <typename ValueType>
+std::string ValueToStringHelper(ValueToStringPriority<4>,
+                                const ValueType& /* unused */,
+                                std::string fallback_value) {
+  return fallback_value;
+}
+
+}  // namespace internal
+
+// The function to be used.
+template <typename ValueType>
+std::string ValueToString(const ValueType& value,
+                          std::string fallback_value = "<value>") {
+  return internal::ValueToStringHelper(internal::ValueToStringPriority<0>(),
+                                       value, std::move(fallback_value));
+}
+
+}  // namespace trace_event
+}  // namespace base
+
+#endif  // BASE_TRACE_EVENT_TRACE_CONVERSION_HELPER_H_
diff --git a/base/trace_event/trace_conversion_helper_unittest.cc b/base/trace_event/trace_conversion_helper_unittest.cc
new file mode 100644
index 0000000..c7fd7e0
--- /dev/null
+++ b/base/trace_event/trace_conversion_helper_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2020 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 "base/trace_event/trace_conversion_helper.h"
+
+#include <stddef.h>
+
+#include <utility>
+
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace trace_event {
+
+TEST(TraceEventConversionHelperTest, OstreamValueToString) {
+  std::string zero = internal::OstreamValueToString(0);
+  EXPECT_EQ("0", zero);
+}
+
+class UseFallback {};
+
+TEST(TraceEventConversionHelperTest, UseFallback) {
+  std::string answer = ValueToString(UseFallback(), "fallback");
+  EXPECT_EQ("fallback", answer);
+}
+
+// std::ostream::operator<<
+TEST(TraceEventConversionHelperTest, StdOstream) {
+  const char* literal = "hello literal";
+  EXPECT_EQ(literal, ValueToString(literal));
+  std::string str = "hello std::string";
+  EXPECT_EQ(str, ValueToString(str));
+  EXPECT_EQ("1", ValueToString(true));
+}
+
+// base::NumberToString
+TEST(TraceEventConversionHelperTest, Number) {
+  EXPECT_EQ("3.14159", ValueToString(3.14159));
+  EXPECT_EQ("0", ValueToString(0.f));
+  EXPECT_EQ("42", ValueToString(42));
+}
+
+class UseToString {
+ public:
+  std::string ToString() const { return "UseToString::ToString"; }
+};
+
+TEST(TraceEventConversionHelperTest, UseToString) {
+  std::string answer = ValueToString(UseToString());
+  EXPECT_EQ("UseToString::ToString", answer);
+}
+
+class UseFallbackNonConstTostring {
+ public:
+  std::string ToString() { return "don't return me, not const"; }
+};
+
+TEST(TraceEventConversionHelperTest, UseFallbackNonConstToString) {
+  std::string answer = ValueToString(UseFallbackNonConstTostring(), "fallback");
+  EXPECT_EQ("fallback", answer);
+}
+
+class ConfusingToStringAPI {
+ public:
+  ConfusingToStringAPI ToString() const { return ConfusingToStringAPI(); }
+};
+
+TEST(TraceEventConversionHelperTest, ConfusingToStringAPI) {
+  std::string answer = ValueToString(ConfusingToStringAPI(), "fallback");
+  EXPECT_EQ("fallback", answer);
+}
+
+// std::ostream::operator<<
+TEST(TraceEventConversionHelperTest, UseOstreamOperator) {
+  // Test that the output is the same as when calling OstreamValueToString.
+  // Different platforms may represent the pointer differently, thus we don't
+  // compare with a value.
+  EXPECT_EQ(internal::OstreamValueToString((void*)0x123),
+            ValueToString((void*)0x123));
+}
+
+class UseOperatorLessLess {};
+
+std::ostream& operator<<(std::ostream& os, const UseOperatorLessLess&) {
+  os << "UseOperatorLessLess";
+  return os;
+}
+
+TEST(TraceEventConversionHelperTest, UseOperatorLessLess) {
+  std::string answer = ValueToString(UseOperatorLessLess());
+  EXPECT_EQ("UseOperatorLessLess", answer);
+}
+
+class HasBoth {
+ public:
+  std::string ToString() const { return "HasBoth::ToString"; }
+};
+
+std::ostream& operator<<(std::ostream& os, const HasBoth&) {
+  os << "HasBoth::OperatorLessLess";
+  return os;
+}
+
+TEST(TraceEventConversionHelperTest, HasBoth) {
+  std::string answer = ValueToString(HasBoth());
+  EXPECT_EQ("HasBoth::ToString", answer);
+}
+
+}  // namespace trace_event
+}  // namespace base
diff --git a/base/trace_event/traced_value.h b/base/trace_event/traced_value.h
index a7e7ea4..a708ada 100644
--- a/base/trace_event/traced_value.h
+++ b/base/trace_event/traced_value.h
@@ -231,14 +231,6 @@
   std::string ToFormattedJSON() const;
 };
 
-// Return std::string representation given by |value|'s ostream operator<<.
-template <typename T>
-std::string ValueToString(const T& value) {
-  std::stringstream ss;
-  ss << value;
-  return ss.str();
-}
-
 }  // namespace trace_event
 }  // namespace base
 
diff --git a/base/trace_event/traced_value_unittest.cc b/base/trace_event/traced_value_unittest.cc
index 1caf27bb..652db8f 100644
--- a/base/trace_event/traced_value_unittest.cc
+++ b/base/trace_event/traced_value_unittest.cc
@@ -15,11 +15,6 @@
 namespace base {
 namespace trace_event {
 
-TEST(TraceEventArgumentTest, ValueToString) {
-  std::string zero = ValueToString(0);
-  EXPECT_EQ("0", zero);
-}
-
 TEST(TraceEventArgumentTest, InitializerListCreatedFlatDictionary) {
   std::string json;
   TracedValue::Build({{"bool_var", true},
diff --git a/base/util/timer/wall_clock_timer.h b/base/util/timer/wall_clock_timer.h
index 8c955fe..752a7b1 100644
--- a/base/util/timer/wall_clock_timer.h
+++ b/base/util/timer/wall_clock_timer.h
@@ -27,8 +27,9 @@
 //
 // Comparison with OneShotTimer: WallClockTimer runs |user_task_| after |delay_|
 // expires according to usual time, while OneShotTimer runs |user_task_| after
-// |delay_| expires according to TimeTicks which freezes when power suspends
-// (desktop falls asleep).
+// |delay_| expires according to TimeTicks which may freeze on some platforms
+// when power suspends (desktop falls asleep). On platforms where TimeTicks
+// don't freeze, the WallClockTimer has the same behavior as OneShotTimer.
 //
 // The API is not thread safe. All methods must be called from the same
 // sequence (not necessarily the construction sequence), except for the
diff --git a/base/util/timer/wall_clock_timer_unittest.cc b/base/util/timer/wall_clock_timer_unittest.cc
index 961f5c0..1fc91dd 100644
--- a/base/util/timer/wall_clock_timer_unittest.cc
+++ b/base/util/timer/wall_clock_timer_unittest.cc
@@ -216,4 +216,67 @@
   ::testing::Mock::VerifyAndClearExpectations(&callback);
 }
 
+// On some platforms, TickClock will never freeze. WallClockTimer are still
+// supported on those platforms.
+TEST_F(WallClockTimerTest, NonStopTickClock) {
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  // Set up a WallClockTimer that will fire in one minute.
+  WallClockTimer wall_clock_timer(&clock_,
+                                  task_environment_.GetMockTickClock());
+  constexpr auto delay = base::TimeDelta::FromMinutes(1);
+  const auto start_time = base::Time::Now();
+  const auto run_time = start_time + delay;
+  clock_.SetNow(start_time);
+  wall_clock_timer.Start(FROM_HERE, run_time, callback.Get());
+  EXPECT_EQ(wall_clock_timer.desired_run_time(), start_time + delay);
+
+  // Pretend that time jumps forward 30 seconds while the machine is suspended.
+  constexpr auto past_time = base::TimeDelta::FromSeconds(30);
+
+  // Fastword with both clocks even the power is suspended.
+  mock_power_monitor_source_->Suspend();
+  clock_.SetNow(clock_.Now() + past_time);
+  task_environment_.FastForwardBy(past_time);
+  mock_power_monitor_source_->Resume();
+
+  // Ensure that the timer has not yet fired.
+  ::testing::Mock::VerifyAndClearExpectations(&callback);
+  EXPECT_EQ(wall_clock_timer.desired_run_time(), start_time + delay);
+
+  // Expect that the timer fires at the desired run time.
+  EXPECT_CALL(callback, Run());
+  // Both Time::Now() and |task_environment_| MockTickClock::Now()
+  // go forward by (|delay| - |past_time|):
+  FastForwardBy(delay - past_time);
+  ::testing::Mock::VerifyAndClearExpectations(&callback);
+  EXPECT_FALSE(wall_clock_timer.IsRunning());
+}
+
+TEST_F(WallClockTimerTest, NonStopTickClockWithLongPause) {
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  // Set up a WallClockTimer that will fire in one minute.
+  WallClockTimer wall_clock_timer(&clock_,
+                                  task_environment_.GetMockTickClock());
+  constexpr auto delay = base::TimeDelta::FromMinutes(1);
+  const auto start_time = base::Time::Now();
+  const auto run_time = start_time + delay;
+  clock_.SetNow(start_time);
+  wall_clock_timer.Start(FROM_HERE, run_time, callback.Get());
+  EXPECT_EQ(wall_clock_timer.desired_run_time(), start_time + delay);
+
+  // Pretend that time jumps forward 60 seconds while the machine is suspended.
+  constexpr auto past_time = base::TimeDelta::FromSeconds(60);
+
+  // Fastword with both clocks even the power is suspended. Timer fires at the
+  // moment of power resume.
+  EXPECT_CALL(callback, Run());
+  mock_power_monitor_source_->Suspend();
+  clock_.SetNow(clock_.Now() + past_time);
+  task_environment_.FastForwardBy(past_time);
+  mock_power_monitor_source_->Resume();
+
+  ::testing::Mock::VerifyAndClearExpectations(&callback);
+  EXPECT_FALSE(wall_clock_timer.IsRunning());
+}
+
 }  // namespace util
diff --git a/build/android/lint/baseline.xml b/build/android/lint/baseline.xml
index 630a63a..92209fe 100644
--- a/build/android/lint/baseline.xml
+++ b/build/android/lint/baseline.xml
@@ -254,7 +254,7 @@
         errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java"
-            line="294"
+            line="285"
             column="53"/>
     </issue>
 
@@ -331,7 +331,7 @@
         errorLine2="                       ~~">
         <location
             file="chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java"
-            line="219"
+            line="220"
             column="24"/>
     </issue>
 
@@ -342,7 +342,7 @@
         errorLine2="                                                ~~">
         <location
             file="chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogHelper.java"
-            line="117"
+            line="123"
             column="49"/>
     </issue>
 
@@ -392,17 +392,6 @@
 
     <issue
         id="WrongConstant"
-        message="Must be one of: ApplicationState.UNKNOWN, ApplicationState.HAS_RUNNING_ACTIVITIES, ApplicationState.HAS_PAUSED_ACTIVITIES, ApplicationState.HAS_STOPPED_ACTIVITIES, ApplicationState.HAS_DESTROYED_ACTIVITIES"
-        errorLine1="        onApplicationStateChange(0 /* unused */);"
-        errorLine2="                                 ~">
-        <location
-            file="net/android/java/src/org/chromium/net/RegistrationPolicyApplicationStatus.java"
-            line="21"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: PasswordsState.UNCHECKED, PasswordsState.CHECKING, PasswordsState.SAFE, PasswordsState.COMPROMISED_EXIST, PasswordsState.OFFLINE, PasswordsState.NO_PASSWORDS, PasswordsState.SIGNED_OUT, PasswordsState.QUOTA_LIMIT, PasswordsState.ERROR"
         errorLine1="        return 0;"
         errorLine2="               ~">
@@ -496,7 +485,7 @@
         errorLine2="                                                                            ~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java"
-            line="272"
+            line="273"
             column="77"/>
     </issue>
 
@@ -705,7 +694,7 @@
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java"
-            line="588"
+            line="604"
             column="55"/>
     </issue>
 
@@ -833,39 +822,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    ThreadUtils.postOnUiThreadDelayed(this, RETRY_DELAY_MS);"
-        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
-            line="393"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        if (sAppDetailsDelegate != null) sAppDetailsDelegate.destroy();"
-        errorLine2="                                                             ~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java"
-            line="69"
-            column="62"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        sAppDetailsDelegate.getAppDetailsAsynchronously("
-        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java"
-            line="104"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="            mHandler.onOptionsItemSelected(menuItem);"
         errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1046,7 +1002,7 @@
         errorLine2="                          ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="238"
+            line="237"
             column="27"/>
     </issue>
 
@@ -1057,7 +1013,7 @@
         errorLine2="                              ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="239"
+            line="238"
             column="31"/>
     </issue>
 
@@ -1068,7 +1024,7 @@
         errorLine2="                              ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="240"
+            line="239"
             column="31"/>
     </issue>
 
@@ -1079,7 +1035,7 @@
         errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="470"
+            line="469"
             column="30"/>
     </issue>
 
@@ -1090,7 +1046,7 @@
         errorLine2="                                                ~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="562"
+            line="558"
             column="49"/>
     </issue>
 
@@ -1101,7 +1057,7 @@
         errorLine2="                                       ~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="563"
+            line="559"
             column="40"/>
     </issue>
 
@@ -1112,7 +1068,7 @@
         errorLine2="                                                                  ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="578"
+            line="574"
             column="67"/>
     </issue>
 
@@ -1123,7 +1079,7 @@
         errorLine2="                        ~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="616"
+            line="612"
             column="25"/>
     </issue>
 
@@ -1134,7 +1090,7 @@
         errorLine2="                                                                        ~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="633"
+            line="629"
             column="73"/>
     </issue>
 
@@ -1145,7 +1101,7 @@
         errorLine2="                                                                      ~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="654"
+            line="650"
             column="71"/>
     </issue>
 
@@ -1156,7 +1112,7 @@
         errorLine2="                                                   ~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="672"
+            line="668"
             column="52"/>
     </issue>
 
@@ -1167,7 +1123,7 @@
         errorLine2="                       ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="692"
+            line="687"
             column="24"/>
     </issue>
 
@@ -1178,7 +1134,7 @@
         errorLine2="                              ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="693"
+            line="688"
             column="31"/>
     </issue>
 
@@ -1189,7 +1145,7 @@
         errorLine2="                              ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="694"
+            line="689"
             column="31"/>
     </issue>
 
@@ -1200,18 +1156,18 @@
         errorLine2="                                                                     ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="703"
+            line="698"
             column="70"/>
     </issue>
 
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="                verifiedIndex, suggestion.hashCode(), elapsedTimeSinceInputChange);"
+        errorLine1="                verifiedIndex, suggestion.hashCode(), getElapsedTimeSinceInputChange());"
         errorLine2="                                          ~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="711"
+            line="703"
             column="43"/>
     </issue>
 
@@ -1222,7 +1178,7 @@
         errorLine2="                                               ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="713"
+            line="705"
             column="48"/>
     </issue>
 
@@ -1233,7 +1189,7 @@
         errorLine2="                           ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="736"
+            line="728"
             column="28"/>
     </issue>
 
@@ -1244,7 +1200,7 @@
         errorLine2="                                                        ~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="854"
+            line="846"
             column="57"/>
     </issue>
 
@@ -1255,7 +1211,7 @@
         errorLine2="                                    ~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="941"
+            line="933"
             column="37"/>
     </issue>
 
@@ -1266,7 +1222,7 @@
         errorLine2="                              ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="942"
+            line="934"
             column="31"/>
     </issue>
 
@@ -1277,7 +1233,7 @@
         errorLine2="                                   ~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="963"
+            line="955"
             column="36"/>
     </issue>
 
@@ -1288,7 +1244,7 @@
         errorLine2="                       ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="978"
+            line="970"
             column="24"/>
     </issue>
 
@@ -1299,7 +1255,7 @@
         errorLine2="                               ~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="980"
+            line="972"
             column="32"/>
     </issue>
 
@@ -1310,7 +1266,7 @@
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="980"
+            line="972"
             column="65"/>
     </issue>
 
@@ -1321,7 +1277,7 @@
         errorLine2="                                                                                  ~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="1160"
+            line="1150"
             column="83"/>
     </issue>
 
@@ -1332,73 +1288,7 @@
         errorLine2="                           ~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java"
-            line="1161"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable&lt;String>() {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="181"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                final AutofillProfile address = new AutofillProfile("
-        errorLine2="                                                ^">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="188"
-            column="49"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable&lt;String>() {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="213"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                final CreditCard card = new CreditCard("
-        errorLine2="                                        ^">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="216"
-            column="41"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable&lt;List&lt;AutofillProfile>>() {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="319"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable&lt;List&lt;CreditCard>>() {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/autofill/AutofillDataProvider.java"
-            line="340"
+            line="1151"
             column="28"/>
     </issue>
 
@@ -3154,116 +3044,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="            mClientManager.setShouldGetPageLoadMetricsForSession(session, true);"
-        errorLine2="            ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="228"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        IntentUtils.safePutBinderExtra(tempIntent, CustomTabsIntent.EXTRA_SESSION, sessionBinder);"
-        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="246"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                mClientManager.setHideDomainForSession(session, hidden);"
-        errorLine2="                ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="280"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                mClientManager.setSpeculateLoadOnCellularForSession(session, prerender);"
-        errorLine2="                ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="287"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                mClientManager.setSendNavigationInfoForSession(session, true);"
-        errorLine2="                ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="293"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                mClientManager.setSendBottomBarScrollingStateForSessionn(session, true);"
-        errorLine2="                ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="301"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                setIgnoreUrlFragmentsForSession(session, value);"
-        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="314"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                mClientManager.setAllowParallelRequestForSession(session, true);"
-        errorLine2="                ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="391"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                if (success) mClientManager.setAllowResourcePrefetchForSession(session, true);"
-        errorLine2="                             ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="402"
-            column="30"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        int uid = mClientManager.getUidForSession(session);"
-        errorLine2="                  ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/customtabs/ChromeCustomTabsConnection.java"
-            line="863"
-            column="19"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        DownloadManagerService.getDownloadManagerService().onDownloadFailed(downloadItem, reason);"
         errorLine2="                                                           ~~~~~~~~~~~~~~~~">
         <location
@@ -3275,55 +3055,11 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="            mOfflinePageUrl = offlinePage.getUrl();"
-        errorLine2="            ~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java"
-            line="108"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            mOfflinePageUrl = offlinePage.getUrl();"
-        errorLine2="                                          ~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java"
-            line="108"
-            column="43"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            long pageCreationTimeMs = offlinePage.getCreationTimeMs();"
-        errorLine2="                                                  ~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java"
-            line="117"
-            column="51"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                Date creationDate = new Date(offlinePage.getCreationTimeMs());"
-        errorLine2="                                                         ~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java"
-            line="119"
-            column="58"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        mOverviewListLayout = (OverviewListLayout) mLayoutManager.getOverviewListLayout();"
         errorLine2="                                                                  ~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="816"
+            line="823"
             column="67"/>
     </issue>
 
@@ -3550,17 +3286,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException("
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="base/android/java/src/org/chromium/base/task/DefaultTaskExecutor.java"
-            line="66"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        if (!AndroidSyncSettings.get().isChromeSyncEnabled()) {"
         errorLine2="                                       ~~~~~~~~~~~~~~~~~~~">
         <location
@@ -3946,39 +3671,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        int scrollTo = mSnapScrollHelper.calculateSnapPosition(initialScroll);"
-        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
-            line="511"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        assert scrollTo == mSnapScrollHelper.calculateSnapPosition(scrollTo);"
-        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
-            line="514"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        ThreadUtils.postOnUiThreadDelayed(this, TIMEOUT_MS);"
-        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java"
-            line="74"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        setKeyboardDelegate(new ActivityKeyboardVisibilityDelegate(getActivity()));"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~">
         <location
@@ -4001,72 +3693,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable&lt;Boolean>() {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/icing/GSAContextHelper.java"
-            line="100"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            singleOfflinePage.putParcelable(FETCHED_URI_KEY, Uri.parse(page.getUrl()));"
-        errorLine2="                                                                            ~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/GetAllPagesV1Handler.java"
-            line="80"
-            column="77"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            singleOfflinePage.putLong(DOWNLOAD_TIMESTAMP_KEY, page.getCreationTimeMs());"
-        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/GetAllPagesV1Handler.java"
-            line="81"
-            column="68"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            singleOfflinePage.putLong(LAST_ACCESSED_TIMESTAMP_KEY, page.getLastAccessTimeMs());"
-        errorLine2="                                                                        ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/GetAllPagesV1Handler.java"
-            line="82"
-            column="73"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            singleOfflinePage.putCharSequence(TITLE_KEY, page.getTitle());"
-        errorLine2="                                                              ~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/GetAllPagesV1Handler.java"
-            line="83"
-            column="63"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            if (item.getUrl().equals(mTab.getUrlString())) {"
-        errorLine2="                     ~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/GetPagesByNamespaceForLivePageSharingCallback.java"
-            line="36"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="                    ? UrlUtilities.urlsMatchIgnoringFragments(speculatedUrl, url)"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -4364,17 +3990,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        ThreadUtils.postOnUiThreadDelayed(mThrottlingIntervalTask, mThrottlingIntervalMs);"
-        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="base/android/java/src/org/chromium/base/memory/MemoryPressureMonitor.java"
-            line="227"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        save();"
         errorLine2="        ~~~~">
         <location
@@ -4441,127 +4056,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        String offlinePath = offlinePage.getFilePath();"
-        errorLine2="                                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="440"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                offlinePageBridge.isTemporaryNamespace(offlinePage.getClientId().getNamespace());"
-        errorLine2="                                                                   ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="443"
-            column="68"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        String offlinePath = offlinePage.getFilePath();"
-        errorLine2="                                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="461"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        String offlinePath = offlinePage.getFilePath();"
-        errorLine2="                                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="496"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                offlinePage.getOfflineId(), publishPageCallback);"
-        errorLine2="                            ~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="539"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        final String pageUrl = page.getUrl();"
-        errorLine2="                                    ~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="560"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        final String pageTitle = page.getTitle();"
-        errorLine2="                                      ~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="561"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        final File offlinePageFile = new File(page.getFilePath());"
-        errorLine2="                                                   ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="562"
-            column="52"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        sharePage(window, pageUrl, pageTitle, page.getFilePath(), offlinePageFile, shareCallback);"
-        errorLine2="                                                   ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="563"
-            column="52"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        LoadUrlParams params = new LoadUrlParams(offlinePage.getUrl(), transitionTypeForReload);"
-        errorLine2="                                                             ~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="784"
-            column="62"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                if (page.getClientId().getNamespace().equals(OfflinePageBridge.LAST_N_NAMESPACE)) {"
-        errorLine2="                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
-            line="887"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        return VersionNumberGetter.getInstance().getCurrentlyUsedVersion(getContext());"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
@@ -4650,72 +4144,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="                            logEntry.getAutofilledValue(), logEntry.getProfileFullName());"
-        errorLine2="                                     ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/policy/providers/PartnerProvider.java"
-            line="78"
-            column="38"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                            logEntry.getAutofilledValue(), logEntry.getProfileFullName());"
-        errorLine2="                                                                    ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/policy/providers/PartnerProvider.java"
-            line="78"
-            column="69"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        AutofillLogger.setLogger(autofillLogger);"
-        errorLine2="                       ~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/policy/providers/PartnerProvider.java"
-            line="82"
-            column="24"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            terminateIncognitoSession();"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/policy/providers/PartnerProvider.java"
-            line="106"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                        IntentUtils.safePutBinderExtra("
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java"
-            line="221"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                        IntentUtils.safePutBinderExtra("
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java"
-            line="208"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="                IconProvider.getIcon(context, R.drawable.ic_vpn_key_grey),"
         errorLine2="                             ~~~~~~~">
         <location
@@ -4980,50 +4408,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="public class PhoneskyDetailsDelegate extends AppDetailsDelegate"
-        errorLine2="                                             ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/banner/PhoneskyDetailsDelegate.java"
-            line="42"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                observer.onAppDetailsRetrieved(data);"
-        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/banner/PhoneskyDetailsDelegate.java"
-            line="104"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        AppData data = new AppData(url, packageName);"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/banner/PhoneskyDetailsDelegate.java"
-            line="155"
-            column="24"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        data.setPackageInfo(title, imageUrl, rating, installText, detailsIntent, purchaseIntent);"
-        errorLine2="             ~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/banner/PhoneskyDetailsDelegate.java"
-            line="156"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        return getBrowserStartupController().isRunningInServiceManagerMode();"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -5035,182 +4419,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        UniqueIdentificationGeneratorFactory.registerGenerator(SyncController.GENERATOR_ID,"
-        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java"
-            line="172"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        UniqueIdentificationGeneratorFactory.registerGenerator(SyncController.GENERATOR_ID,"
-        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/init/ProcessInitializationHandlerInternal.java"
-            line="44"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        LocationUtils.setFactory(() -> new LocationUtilsInternal(mExternalAuthUtils));"
-        errorLine2="                      ~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/init/ProcessInitializationHandlerInternal.java"
-            line="51"
-            column="23"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            page = new OfflinePageItem(mPage.getUrl(), mPage.getOfflineId(),"
-        errorLine2="                                             ~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="39"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            page = new OfflinePageItem(mPage.getUrl(), mPage.getOfflineId(),"
-        errorLine2="                                                             ~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="39"
-            column="62"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getClientId().getNamespace(), mPage.getClientId().getId(),"
-        errorLine2="                          ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="40"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getClientId().getNamespace(), mPage.getClientId().getId(),"
-        errorLine2="                                                              ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="40"
-            column="63"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getTitle(), newFilePath, mPage.getFileSize(), mPage.getCreationTimeMs(),"
-        errorLine2="                          ~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="41"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getTitle(), newFilePath, mPage.getFileSize(), mPage.getCreationTimeMs(),"
-        errorLine2="                                                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="41"
-            column="58"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getTitle(), newFilePath, mPage.getFileSize(), mPage.getCreationTimeMs(),"
-        errorLine2="                                                                              ~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="41"
-            column="79"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getAccessCount(), mPage.getLastAccessTimeMs(), mPage.getRequestOrigin());"
-        errorLine2="                          ~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="42"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getAccessCount(), mPage.getLastAccessTimeMs(), mPage.getRequestOrigin());"
-        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="42"
-            column="51"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="                    mPage.getAccessCount(), mPage.getLastAccessTimeMs(), mPage.getRequestOrigin());"
-        errorLine2="                                                                               ~~~~~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java"
-            line="42"
-            column="80"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        requestCoordinatorBridge.getRequestsInQueue(new Callback&lt;SavePageRequest[]&gt;() {"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/QueryPagesV1Handler.java"
-            line="94"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            ClientId clientId = page.getClientId();"
-        errorLine2="                                     ~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/QueryPagesV1Handler.java"
-            line="128"
-            column="38"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="            singleUriResult.putParcelable(FETCHED_URI_KEY, Uri.parse(page.getUrl()));"
-        errorLine2="                                                                          ~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/QueryPagesV1Handler.java"
-            line="141"
-            column="75"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        String distillerUrl = DomDistillerUrlUtils.getDistillerViewUrlFromUrl("
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -5233,34 +4441,12 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="        requestCoordinatorBridge.getRequestsInQueue(queuedRequests -> {"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~">
+        errorLine1="                new SettingsSecureBasedIdentificationGenerator(getContext()), false);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/RemovePagesV1Handler.java"
-            line="76"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        requestCoordinatorBridge.getRequestsInQueue(queuedRequests -> {"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/org/chromium/chrome/browser/offlinepages/RemovePagesV2Handler.java"
-            line="74"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
-        errorLine1="        super(context);"
-        errorLine2="        ~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/omaha/RequestGeneratorImpl.java"
-            line="36"
-            column="9"/>
+            file="chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java"
+            line="52"
+            column="17"/>
     </issue>
 
     <issue
@@ -5303,7 +4489,7 @@
         errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java"
-            line="202"
+            line="203"
             column="25"/>
     </issue>
 
@@ -5453,17 +4639,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="                &amp;&amp; TextUtils.equals(item.getClientId().getNamespace(),"
-        errorLine2="                                         ~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsOfflineModelObserver.java"
-            line="129"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="                requestId, new AwContents.VisualStateCallback() {"
         errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -5644,7 +4819,7 @@
         errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java"
-            line="94"
+            line="95"
             column="22"/>
     </issue>
 
@@ -5655,7 +4830,7 @@
         errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java"
-            line="96"
+            line="97"
             column="22"/>
     </issue>
 
@@ -5673,17 +4848,6 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="            tile.setOfflinePageOfflineId(item == null ? null : item.getOfflineId());"
-        errorLine2="                                                                    ~~~~~~~~~~~~">
-        <location
-            file="chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java"
-            line="614"
-            column="69"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within private scope"
         errorLine1="        return suggestion.getType() == OmniboxSuggestionType.TILE_SUGGESTION;"
         errorLine2="                          ~~~~~~~">
         <location
@@ -6453,50 +5617,6 @@
 
     <issue
         id="SupportAnnotationUsage"
-        message="This annotation does not apply for type org.chromium.base.Callback&lt;java.lang.Integer>; expected int or long"
-        errorLine1="            @LocationSettingsDialogOutcome Callback&lt;Integer> callback) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/location/LocationUtilsInternal.java"
-            line="96"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="SupportAnnotationUsage"
-        message="This annotation does not apply for type org.chromium.base.Callback&lt;java.lang.Integer>; expected int or long"
-        errorLine1="        @LocationSettingsDialogOutcome"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/location/LocationUtilsInternal.java"
-            line="123"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="SupportAnnotationUsage"
-        message="This annotation does not apply for type org.chromium.base.Callback&lt;java.lang.Integer>; expected int or long"
-        errorLine1="                WindowAndroid window, @LocationSettingsDialogOutcome Callback&lt;Integer> callback,"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/location/LocationUtilsInternal.java"
-            line="129"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="SupportAnnotationUsage"
-        message="This annotation does not apply for type org.chromium.base.Callback&lt;java.lang.Integer>; expected int or long"
-        errorLine1="                WindowAndroid window, @LocationSettingsDialogOutcome Callback&lt;Integer> callback,"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="clank/java/src/com/google/android/apps/chrome/location/LocationUtilsInternal.java"
-            line="143"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="SupportAnnotationUsage"
         message="This annotation does not apply for type String; expected int or long"
         errorLine1="        @QuickActionCategory"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~">
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 7b5f2a1..12e30c6 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -948,12 +948,7 @@
 if (enable_java_templates) {
   template("android_lint") {
     action_with_pydeps(target_name) {
-      forward_variables_from(invoker,
-                             [
-                               "data_deps",
-                               "public_deps",
-                               "testonly",
-                             ])
+      forward_variables_from(invoker, [ "testonly" ])
       if (!defined(deps)) {
         deps = []
       }
@@ -982,6 +977,7 @@
               "${_target_label}__header",
             ]
           } else {
+            # Keep non-java deps as they may generate files used by lint.
             deps += [ _dep ]
           }
         }
@@ -999,15 +995,16 @@
         _suppressions_file = "//build/android/lint/suppressions.xml"
       }
 
-      _min_sdk_version = default_min_sdk_version
       if (defined(invoker.min_sdk_version)) {
         _min_sdk_version = invoker.min_sdk_version
+      } else {
+        _min_sdk_version = default_min_sdk_version
       }
 
       _lint_binary_path = "$lint_android_sdk_root/cmdline-tools/latest/bin/lint"
       _cache_dir = "$root_build_dir/android_lint_cache"
 
-      # Save these generated xml files in a consistent location for debugging.
+      # Save generated xml files in a consistent location for debugging.
       _lint_gen_dir = "$target_gen_dir/$target_name"
 
       script = "//build/android/gyp/lint.py"
diff --git a/build/util/PRESUBMIT.py b/build/util/PRESUBMIT.py
index 271afbb..6100379 100644
--- a/build/util/PRESUBMIT.py
+++ b/build/util/PRESUBMIT.py
@@ -7,7 +7,7 @@
 
 
 def _GetBlacklist(input_api):
-  blacklist = []
+  files_to_skip = []
   affected_files = input_api.change.AffectedFiles()
   version_script_change = next(
       (f for f in affected_files
@@ -15,7 +15,7 @@
       None)
 
   if version_script_change is None:
-    blacklist.append('version_test\\.py$')
+    files_to_skip.append('version_test\\.py$')
 
   android_chrome_version_script_change = next(
       (f for f in affected_files if re.search(
@@ -23,21 +23,21 @@
           '\\/android_chrome_version_test\\.py$', f.LocalPath())), None)
 
   if android_chrome_version_script_change is None:
-    blacklist.append('android_chrome_version_test\\.py$')
+    files_to_skip.append('android_chrome_version_test\\.py$')
 
-  return blacklist
+  return files_to_skip
 
 
 def _GetPythonUnitTests(input_api, output_api):
   # No need to test if files are unchanged
-  blacklist = _GetBlacklist(input_api)
+  files_to_skip = _GetBlacklist(input_api)
 
   return input_api.canned_checks.GetUnitTestsRecursively(
       input_api,
       output_api,
       input_api.PresubmitLocalPath(),
-      whitelist=['.*_test\\.py$'],
-      blacklist=blacklist)
+      files_to_check=['.*_test\\.py$'],
+      files_to_skip=files_to_skip)
 
 
 def CommonChecks(input_api, output_api):
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py
index 28ac4ed6..c375a37 100644
--- a/cc/PRESUBMIT.py
+++ b/cc/PRESUBMIT.py
@@ -21,7 +21,8 @@
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
 
-def CheckAsserts(input_api, output_api, allowlist=CC_SOURCE_FILES, denylist=None):
+def CheckAsserts(input_api, output_api, allowlist=CC_SOURCE_FILES,
+                 denylist=None):
   denylist = tuple(denylist or input_api.DEFAULT_FILES_TO_SKIP)
   source_file_filter = lambda x: input_api.FilterSourceFile(x, allowlist,
       denylist)
diff --git a/chrome/PRESUBMIT.py b/chrome/PRESUBMIT.py
index 19f7f55..578b4b7b 100644
--- a/chrome/PRESUBMIT.py
+++ b/chrome/PRESUBMIT.py
@@ -36,9 +36,9 @@
 
 def _CheckChangeLintsClean(input_api, output_api):
   """Makes sure that the chrome/ code is cpplint clean."""
-  black_list = input_api.DEFAULT_BLACK_LIST + EXCLUDE
+  files_to_skip = input_api.DEFAULT_FILES_TO_SKIP + EXCLUDE
   sources = lambda x: input_api.FilterSourceFile(
-    x, white_list=INCLUDE_CPP_FILES_ONLY, black_list=black_list)
+    x, files_to_check=INCLUDE_CPP_FILES_ONLY, files_to_skip=files_to_skip)
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, sources)
 
@@ -80,7 +80,7 @@
   ios_macros = []
   def SourceFilter(affected_file):
     return input_api.FilterSourceFile(affected_file, INCLUDE_SOURCE_FILES_ONLY,
-                                      input_api.DEFAULT_BLACK_LIST)
+                                      input_api.DEFAULT_FILES_TO_SKIP)
   for f in input_api.AffectedSourceFiles(SourceFilter):
     ios_macros.extend(_CheckNoOSIOSMacrosInChromeFile(input_api, f))
 
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 5d310a2..a15d8d8 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1251,7 +1251,6 @@
   "java/src/org/chromium/chrome/browser/payments/BasicCardUtils.java",
   "java/src/org/chromium/chrome/browser/payments/CardEditor.java",
   "java/src/org/chromium/chrome/browser/payments/ContactEditor.java",
-  "java/src/org/chromium/chrome/browser/payments/PaymentAppComparator.java",
   "java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryDelegate.java",
   "java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryInterface.java",
   "java/src/org/chromium/chrome/browser/payments/PaymentAppService.java",
@@ -1287,6 +1286,7 @@
   "java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java",
   "java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java",
   "java/src/org/chromium/chrome/browser/payments/ui/LineItem.java",
+  "java/src/org/chromium/chrome/browser/payments/ui/PaymentAppComparator.java",
   "java/src/org/chromium/chrome/browser/payments/ui/PaymentInformation.java",
   "java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestBottomBar.java",
   "java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java
index 30f916c..74d881d 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java
@@ -40,7 +40,6 @@
     private static final String INTENT_IDENTFIER = "INTENT";
     private static final String BUY_MOVIE_TICKETS_INTENT = "BUY_MOVIE_TICKET";
     private static final String RENT_CAR_INTENT = "RENT_CAR";
-    private static final String PASSWORD_CHANGE_INTENT = "PASSWORD_CHANGE";
     private static final String FLIGHTS_INTENT = "FLIGHTS_CHECKIN";
     private static final String FOOD_ORDERING_INTENT = "FOOD_ORDERING";
     private static final String VOICE_SEARCH_INTENT = "TELEPORT";
@@ -238,10 +237,6 @@
                 termsTextView.setText(R.string.autofill_assistant_init_message_short);
                 titleTextView.setText(R.string.autofill_assistant_init_message_rent_car);
                 break;
-            case PASSWORD_CHANGE_INTENT:
-                termsTextView.setText(R.string.autofill_assistant_init_message_short);
-                titleTextView.setText(R.string.autofill_assistant_init_message_password_change);
-                break;
             case SHOPPING_INTENT:
             case SHOPPING_ASSISTED_CHECKOUT_INTENT:
                 termsTextView.setText(R.string.autofill_assistant_init_message_short);
diff --git a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd b/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd
index c7168cf..d122756 100644
--- a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd
+++ b/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd
@@ -177,9 +177,6 @@
       <message name="IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_RENT_CAR" desc="Onboarding message describing autofill assistant's capability for car rentals.">
         Rent a car\nin just a few taps
       </message>
-      <message name="IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_PASSWORD_CHANGE" desc="Onboarding message describing autofill assistant's capability for password change.">
-        Let Google Assistant help you\nchange your password
-      </message>
       <message name="IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_BUY_MOVIE_TICKETS" desc="Onboarding message describing autofill assistant's capability for movie tickets.">
         Buy movie tickets\nin just a few taps
       </message>
diff --git a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings_grd/IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_PASSWORD_CHANGE.png.sha1 b/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings_grd/IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_PASSWORD_CHANGE.png.sha1
deleted file mode 100644
index 457235a..0000000
--- a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings_grd/IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE_PASSWORD_CHANGE.png.sha1
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index 0bf4a95..ade54a9 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -75,7 +75,7 @@
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout;
-import org.chromium.chrome.browser.feed.FeedSurfaceCoordinator;
+import org.chromium.chrome.browser.feed.FeedSurfaceMediator;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -988,7 +988,7 @@
         Assert.assertEquals(expectedRecordCount,
                 RecordHistogram.getHistogramTotalCountForTesting(
                         StartSurfaceConfiguration.getHistogramName(
-                                FeedSurfaceCoordinator.FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA,
+                                FeedSurfaceMediator.FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA,
                                 isInstantStart)));
         Assert.assertEquals(isInstantReturn() ? 1 : 0,
                 RecordHistogram.getHistogramTotalCountForTesting(
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
index a53f66b..e42f2c2 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -47,7 +47,6 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.user_education.UserEducationHelper;
-import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.util.GlobalDiscardableReferencePool;
 import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
@@ -64,9 +63,6 @@
  * Provides a surface that displays an interest feed rendered list of content suggestions.
  */
 public class FeedSurfaceCoordinator implements FeedSurfaceProvider {
-    @VisibleForTesting
-    public static final String FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA = "FeedContentFirstLoadedTime";
-
     private final Activity mActivity;
     private final SnackbarManager mSnackbarManager;
     @Nullable
@@ -502,9 +498,7 @@
     }
 
     public void onOverviewShownAtLaunch(long activityCreationTimeMs) {
-        StartSurfaceConfiguration.recordHistogram(FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA,
-                mMediator.getContentFirstAvailableTimeMs() - activityCreationTimeMs,
-                mIsPlaceholderShown);
+        mMediator.onOverviewShownAtLaunch(activityCreationTimeMs, mIsPlaceholderShown);
     }
 
     Tracker getFeatureEngagementTracker() {
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index faae547..38a93cb 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -39,6 +39,7 @@
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninPromoUtil;
 import org.chromium.chrome.browser.suggestions.SuggestionsMetrics;
+import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
 import org.chromium.components.browser_ui.widget.listmenu.ListMenu;
 import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties;
 import org.chromium.components.feature_engagement.Tracker;
@@ -56,10 +57,14 @@
  * A mediator for the {@link FeedSurfaceCoordinator} responsible for interacting with the
  * native library and handling business logic.
  */
-class FeedSurfaceMediator implements NewTabPageLayout.ScrollDelegate,
-                                     ContextMenuManager.TouchEnabledDelegate,
-                                     TemplateUrlServiceObserver, ListMenu.Delegate,
-                                     HomepagePromoStateListener, IdentityManager.Observer {
+@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+public class FeedSurfaceMediator
+        implements NewTabPageLayout.ScrollDelegate, ContextMenuManager.TouchEnabledDelegate,
+                   TemplateUrlServiceObserver, ListMenu.Delegate, HomepagePromoStateListener,
+                   IdentityManager.Observer {
+    @VisibleForTesting
+    public static final String FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA = "FeedContentFirstLoadedTime";
+
     private static final float IPH_TRIGGER_BAR_TRANSITION_FRACTION = 1.0f;
     private static final float IPH_STREAM_MIN_SCROLL_FRACTION = 0.10f;
     private static final float IPH_FEED_HEADER_MAX_POS_FRACTION = 0.35f;
@@ -85,7 +90,17 @@
     private int mThumbnailWidth;
     private int mThumbnailHeight;
     private int mThumbnailScrollY;
+
+    /** Whether the Feed content is loading. */
+    private boolean mIsLoadingFeed;
+    /** Cached parameters for recording the histogram of "FeedContentFirstLoadedTime". */
+    private boolean mIsInstantStart;
+    private long mActivityCreationTimeMs;
     private long mContentFirstAvailableTimeMs;
+    // Whether missing a histogram record when onOverviewShownAtLaunch() is called. It is possible
+    // that Feed content is still loading at that time and the {@link mContentFirstAvailableTimeMs}
+    // hasn't been set yet.
+    private boolean mHasPendingUmaRecording;
 
     /**
      * @param coordinator The {@link FeedSurfaceCoordinator} that interacts with this class.
@@ -145,6 +160,7 @@
         }
 
         if (mFeedEnabled) {
+            mIsLoadingFeed = true;
             mCoordinator.createStream();
             if (mSnapScrollHelper != null) {
                 mSnapScrollHelper.setView(mCoordinator.getStream().getView());
@@ -191,7 +207,12 @@
             public void onAddFinished() {
                 if (mContentFirstAvailableTimeMs == 0) {
                     mContentFirstAvailableTimeMs = SystemClock.elapsedRealtime();
+                    if (mHasPendingUmaRecording) {
+                        maybeRecordContentLoadingTime();
+                        mHasPendingUmaRecording = false;
+                    }
                 }
+                mIsLoadingFeed = false;
             }
         };
         stream.addOnContentChangedListener(mStreamContentChangedListener);
@@ -569,10 +590,6 @@
         updateSectionHeader();
     }
 
-    long getContentFirstAvailableTimeMs() {
-        return mContentFirstAvailableTimeMs;
-    }
-
     /**
      * The {@link SignInPromo} for the Feed.
      * TODO(huayinz): Update content and visibility through a ModelChangeProcessor.
@@ -618,4 +635,22 @@
     SignInPromo getSignInPromoForTesting() {
         return mSignInPromo;
     }
+
+    void onOverviewShownAtLaunch(long activityCreationTimeMs, boolean isInstantStart) {
+        assert mActivityCreationTimeMs == 0;
+        mActivityCreationTimeMs = activityCreationTimeMs;
+        mIsInstantStart = isInstantStart;
+
+        if (!maybeRecordContentLoadingTime() && mIsLoadingFeed) {
+            mHasPendingUmaRecording = true;
+        }
+    }
+
+    private boolean maybeRecordContentLoadingTime() {
+        if (mActivityCreationTimeMs == 0 || mContentFirstAvailableTimeMs == 0) return false;
+
+        StartSurfaceConfiguration.recordHistogram(FEED_CONTENT_FIRST_LOADED_TIME_MS_UMA,
+                mContentFirstAvailableTimeMs - mActivityCreationTimeMs, mIsInstantStart);
+        return true;
+    }
 }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
index ceccb17..2b40ba1 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
@@ -168,8 +168,10 @@
      *  Clear all the data related to all surfaces.
      */
     public static void clearAll() {
+        FeedStreamSurface[] surfaces = null;
         if (sSurfaces != null) {
-            for (FeedStreamSurface surface : sSurfaces) {
+            surfaces = sSurfaces.toArray(new FeedStreamSurface[sSurfaces.size()]);
+            for (FeedStreamSurface surface : surfaces) {
                 surface.surfaceClosed();
             }
             sSurfaces = null;
@@ -179,6 +181,12 @@
         if (processScope != null) {
             processScope.resetAccount();
         }
+
+        if (surfaces != null) {
+            for (FeedStreamSurface surface : surfaces) {
+                surface.surfaceOpened();
+            }
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/PRESUBMIT.py b/chrome/android/java/src/PRESUBMIT.py
index ebbd009..4f60ad2 100644
--- a/chrome/android/java/src/PRESUBMIT.py
+++ b/chrome/android/java/src/PRESUBMIT.py
@@ -52,8 +52,7 @@
 
 
 def _CheckNotificationConstructors(input_api, output_api):
-  # "Blacklist" because the following files are excluded from the check.
-  blacklist = (
+  files_to_skip = (
       'chrome/android/java/src/org/chromium/chrome/browser/notifications/'
       'ChromeNotificationWrapperBuilder.java',
       'chrome/android/java/src/org/chromium/chrome/browser/notifications/'
@@ -70,14 +69,13 @@
 
   See https://crbug.com/678670 for more information.
   '''
-  return _CheckReIgnoreComment(input_api, output_api, error_msg, blacklist,
+  return _CheckReIgnoreComment(input_api, output_api, error_msg, files_to_skip,
                                NEW_NOTIFICATION_BUILDER_RE)
 
 
 def _CheckAlertDialogBuilder(input_api, output_api):
-  # "Blacklist" because the following files are excluded from the check. In
-  # general, preference and FRE related UIs are not relevant to VR mode.
-  blacklist = (
+  # In general, preference and FRE related UIs are not relevant to VR mode.
+  files_to_skip = (
       BROWSER_ROOT + 'browserservices/ClearDataDialogActivity.java',
       BROWSER_ROOT + 'browsing_data/ConfirmImportantSitesDialogFragment.java',
       BROWSER_ROOT + 'browsing_data/OtherFormsOfHistoryDialogFragment.java',
@@ -117,7 +115,7 @@
   //src/chrome/android/java/src/org/chromium/chrome/browser/vr/VR_JAVA_OWNERS
   '''
   error_files = []
-  result = _CheckReIgnoreComment(input_api, output_api, error_msg, blacklist,
+  result = _CheckReIgnoreComment(input_api, output_api, error_msg, files_to_skip,
                                  NEW_ALERTDIALOG_BUILDER_RE, error_files)
 
   wrong_builder_errors = []
@@ -142,8 +140,7 @@
 
 
 def _CheckCompatibleAlertDialogBuilder(input_api, output_api):
-  # "Blacklist" because the following files are excluded from the check.
-  blacklist = (
+  files_to_skip = (
       BROWSER_ROOT + 'autofill/AutofillPopupBridge.java',
       BROWSER_ROOT + 'autofill/keyboard_accessory/'
                      'AutofillKeyboardAccessoryBridge.java',
@@ -171,11 +168,11 @@
   If you are in doubt, contact
   //src/chrome/android/java/src/org/chromium/chrome/browser/vr/VR_JAVA_OWNERS
   '''
-  return _CheckReIgnoreComment(input_api, output_api, error_msg, blacklist,
+  return _CheckReIgnoreComment(input_api, output_api, error_msg, files_to_skip,
                                NEW_COMPATIBLE_ALERTDIALOG_BUILDER_RE)
 
 
-def _CheckReIgnoreComment(input_api, output_api, error_msg, blacklist,
+def _CheckReIgnoreComment(input_api, output_api, error_msg, files_to_skip,
                           regular_expression, error_files=None):
 
   def CheckLine(current_file, line_number, line, problems, error_files):
@@ -191,7 +188,7 @@
 
   problems = []
   sources = lambda x: input_api.FilterSourceFile(
-      x, white_list=(r'.*\.java$',), black_list=blacklist)
+      x, files_to_check=(r'.*\.java$',), files_to_skip=files_to_skip)
   for f in input_api.AffectedFiles(include_deletes=False,
                                    file_filter=sources):
     previous_line = ''
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java
index 2f86dad..adb89c8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.autofill;
 
-import androidx.annotation.VisibleForTesting;
-
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 
@@ -26,12 +24,10 @@
             mProfileFullName = profileFullName;
         }
 
-        @VisibleForTesting
         public String getAutofilledValue() {
             return mAutofilledValue;
         }
 
-        @VisibleForTesting
         public String getProfileFullName() {
             return mProfileFullName;
         }
@@ -48,12 +44,10 @@
     private static Logger sLogger;
     private static Logger sLoggerForTest;
 
-    @VisibleForTesting
     public static void setLogger(Logger logger) {
         sLogger = logger;
     }
 
-    @VisibleForTesting
     public static void setLoggerForTesting(Logger logger) {
         sLoggerForTest = logger;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java
index dbe7d45..d0f1447 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java
@@ -7,8 +7,6 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 
-import androidx.annotation.VisibleForTesting;
-
 /**
  * Stores information about a particular app.
  */
@@ -30,7 +28,6 @@
      * @param siteUrl     URL for the site requesting the banner.
      * @param packageName Name of the package associated with the app.
      */
-    @VisibleForTesting
     public AppData(String siteUrl, String packageName) {
         mSiteUrl = siteUrl;
         mPackageName = packageName;
@@ -110,7 +107,6 @@
      * @param detailsIntent     Intent to fire to launch the details page for the app
      * @param installIntent     Intent to fire to trigger the purchase/install process.
      */
-    @VisibleForTesting
     public void setPackageInfo(String title, String imageUrl, float rating,
             String installButtonText, PendingIntent detailsIntent, Intent installIntent) {
         mTitle = title;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java
index 3c9f4e9..4dc3bbc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java
@@ -4,12 +4,9 @@
 
 package org.chromium.chrome.browser.banners;
 
-import androidx.annotation.VisibleForTesting;
-
 /**
  * Fetches data about the given app.
  */
-@VisibleForTesting
 public abstract class AppDetailsDelegate {
     /**
      * Class to inform when the app's details have been retrieved.
@@ -19,7 +16,6 @@
          * Called when the task has finished.
          * @param data Data about the requested package.  Will be null if retrieval failed.
          */
-        @VisibleForTesting
         public void onAppDetailsRetrieved(AppData data);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index ce99b0e..5c6e617 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -303,7 +303,8 @@
             }
         };
 
-        new Thread(inflateTask).start();
+        // Run inflation task on UI thread due to threading issues in M85. See crbug.com/1112352
+        inflateTask.run();
     }
 
     private void onLayoutInflated(ViewGroup mainView) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
index 4f8c5fb..3ce0238 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -198,7 +198,7 @@
 
     private final HiddenTabHolder mHiddenTabHolder = new HiddenTabHolder();
     protected final SessionDataHolder mSessionDataHolder;
-    @VisibleForTesting
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
     final ClientManager mClientManager;
     protected final boolean mLogRequests;
     private final AtomicBoolean mWarmupHasBeenCalled = new AtomicBoolean();
@@ -1082,7 +1082,6 @@
         return ExternalAuthUtils.getInstance().isGoogleSigned(packageName);
     }
 
-    @VisibleForTesting
     void setIgnoreUrlFragmentsForSession(CustomTabsSessionToken session, boolean value) {
         mClientManager.setIgnoreFragmentsForSession(session, value);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java
index 356478f..9780f57 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java
@@ -49,7 +49,6 @@
      * @param force         if set to true, will override any existing generator for this type. Else
      *                      discards calls where a generator exists.
      */
-    @VisibleForTesting
     public static void registerGenerator(String generatorType, UniqueIdentificationGenerator gen,
                                          boolean force) {
         synchronized (LOCK) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
index f551cae..3016eee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.offlinepages;
 
-import androidx.annotation.VisibleForTesting;
-
 /**
  * Simple object representing an offline page.
  */
@@ -37,61 +35,51 @@
     }
 
     /** @return URL of the offline page. */
-    @VisibleForTesting
     public String getUrl() {
         return mUrl;
     }
 
     /** @return offline id for this offline page. */
-    @VisibleForTesting
     public long getOfflineId() {
         return mOfflineId;
     }
 
     /** @return Client Id related to the offline page. */
-    @VisibleForTesting
     public ClientId getClientId() {
         return mClientId;
     }
 
     /** @return Title of the page. */
-    @VisibleForTesting
     public String getTitle() {
         return mTitle;
     }
 
     /** @return File Path to the offline copy of the page. */
-    @VisibleForTesting
     public String getFilePath() {
         return mFilePath;
     }
 
     /** @return Size of the offline copy of the page. */
-    @VisibleForTesting
     public long getFileSize() {
         return mFileSize;
     }
 
     /** @return Time in milliseconds the offline page was created. */
-    @VisibleForTesting
     public long getCreationTimeMs() {
         return mCreationTimeMs;
     }
 
     /** @return Number of times that the offline page has been accessed. */
-    @VisibleForTesting
     public int getAccessCount() {
         return mAccessCount;
     }
 
     /** @return Last time in milliseconds the offline page has been accessed. */
-    @VisibleForTesting
     public long getLastAccessTimeMs() {
         return mLastAccessTimeMs;
     }
 
     /** @return The originating application of the request. */
-    @VisibleForTesting
     public String getRequestOrigin() {
         return mRequestOrigin;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java
index 583115d4..83dc5ab 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java
@@ -51,8 +51,7 @@
      *
      * @return A list of {@link SavePageRequest} representing all the queued requests.
      */
-    @VisibleForTesting
-    public void getRequestsInQueue(Callback<SavePageRequest[]> callback) {
+    void getRequestsInQueue(Callback<SavePageRequest[]> callback) {
         RequestCoordinatorBridgeJni.get().getRequestsInQueue(mProfile, callback);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java
index 3f63211..49f45c7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java
@@ -45,8 +45,7 @@
 
     private final Context mApplicationContext;
 
-    @VisibleForTesting
-    public RequestGenerator(Context context) {
+    protected RequestGenerator(Context context) {
         mApplicationContext = context.getApplicationContext();
         UniqueIdentificationGeneratorFactory.registerGenerator(
                 SettingsSecureBasedIdentificationGenerator.GENERATOR_ID,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index dd4807d..dc5dbde 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -32,7 +32,6 @@
 import org.chromium.chrome.browser.payments.ui.ContactDetailsSection;
 import org.chromium.chrome.browser.payments.ui.LineItem;
 import org.chromium.chrome.browser.payments.ui.PaymentInformation;
-import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.OptionSection.FocusChangedObserver;
 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI;
 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.SelectionResult;
 import org.chromium.chrome.browser.payments.ui.PaymentUIsManager;
@@ -49,7 +48,6 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.ui.favicon.FaviconHelper;
-import org.chromium.components.autofill.Completable;
 import org.chromium.components.autofill.EditableOption;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
 import org.chromium.components.embedder_support.util.UrlConstants;
@@ -113,7 +111,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -129,7 +126,7 @@
                    PaymentAppFactoryDelegate, PaymentAppFactoryParams,
                    PaymentRequestUpdateEventListener, PaymentApp.AbortCallback,
                    PaymentApp.InstrumentDetailsCallback,
-                   PaymentResponseHelper.PaymentResponseRequesterDelegate, FocusChangedObserver,
+                   PaymentResponseHelper.PaymentResponseRequesterDelegate,
                    NormalizedAddressRequestDelegate, PaymentDetailsConverter.MethodChecker,
                    PaymentUIsManager.Delegate {
     /**
@@ -234,13 +231,7 @@
         void onRendererClosedMojoConnection();
     }
 
-    /** Limit in the number of suggested items in a section. */
-    public static final int SUGGESTIONS_LIMIT = 4;
-
     private static final String TAG = "PaymentRequest";
-    // Reverse order of the comparator to sort in descending order of completeness scores.
-    private static final Comparator<Completable> COMPLETENESS_COMPARATOR =
-            (a, b) -> (PaymentAppComparator.compareCompletablesByCompleteness(b, a));
 
     private ComponentPaymentRequestImpl mComponentPaymentRequestImpl;
 
@@ -250,8 +241,6 @@
     private boolean mRequestPayerPhone;
     private boolean mRequestPayerEmail;
 
-    private final Comparator<PaymentApp> mPaymentAppComparator;
-
     private static PaymentRequestServiceObserverForTest sObserverForTest;
     private static boolean sIsLocalCanMakePaymentQueryQuotaEnforcedForTest;
 
@@ -452,8 +441,7 @@
 
         if (sObserverForTest != null) sObserverForTest.onPaymentRequestCreated(this);
         mPaymentUIsManager = new PaymentUIsManager(/*delegate=*/this,
-                /*params=*/this, mWebContents, mIsOffTheRecord);
-        mPaymentAppComparator = new PaymentAppComparator(/*params=*/this);
+                /*params=*/this, mWebContents, mIsOffTheRecord, mJourneyLogger);
     }
 
     // Implement ComponentPaymentRequestDelegate:
@@ -628,7 +616,7 @@
                 && (mURLPaymentMethodIdentifiersSupported
                         || mSkipUiForNonUrlPaymentMethodIdentifiers)
                 && mPaymentUIsManager.getPaymentMethodsSection().getSize() >= 1
-                && onlySingleAppCanProvideAllRequiredInformation()
+                && mPaymentUIsManager.onlySingleAppCanProvideAllRequiredInformation()
                 // Skip to payment app only if it can be pre-selected.
                 && selectedApp != null
                 // Skip to payment app only if user gesture is provided when it is required to
@@ -636,37 +624,6 @@
                 && (mIsUserGestureShow || !selectedApp.isUserGestureRequiredToSkipUi());
     }
 
-    /**
-     * @return true when there is exactly one available payment app which can provide all requested
-     * information including shipping address and payer's contact information whenever needed.
-     */
-    private boolean onlySingleAppCanProvideAllRequiredInformation() {
-        assert mPaymentUIsManager.getPaymentMethodsSection() != null;
-
-        if (!mRequestShipping && !mRequestPayerName && !mRequestPayerPhone && !mRequestPayerEmail) {
-            return mPaymentUIsManager.getPaymentMethodsSection().getSize() == 1
-                    && !((PaymentApp) mPaymentUIsManager.getPaymentMethodsSection().getItem(0))
-                                .isAutofillInstrument();
-        }
-
-        boolean anAppCanProvideAllInfo = false;
-        int sectionSize = mPaymentUIsManager.getPaymentMethodsSection().getSize();
-        for (int i = 0; i < sectionSize; i++) {
-            PaymentApp app = (PaymentApp) mPaymentUIsManager.getPaymentMethodsSection().getItem(i);
-            if ((!mRequestShipping || app.handlesShippingAddress())
-                    && (!mRequestPayerName || app.handlesPayerName())
-                    && (!mRequestPayerPhone || app.handlesPayerPhone())
-                    && (!mRequestPayerEmail || app.handlesPayerEmail())) {
-                // There is more than one available app that can provide all merchant requested
-                // information information.
-                if (anAppCanProvideAllInfo) return false;
-
-                anAppCanProvideAllInfo = true;
-            }
-        }
-        return anAppCanProvideAllInfo;
-    }
-
     /** @return Whether the UI was built. */
     private boolean buildUI(ChromeActivity activity) {
         // Payment methods section must be ready before building the rest of the UI. This is because
@@ -711,7 +668,7 @@
         }
 
         if (shouldShowShippingSection() && !mWaitForUpdatedDetails) {
-            createShippingSection(activity, mPaymentUIsManager.getAutofillProfiles());
+            mPaymentUIsManager.createShippingSectionForPaymentRequestUI(activity);
         }
 
         if (shouldShowContactSection()) {
@@ -748,8 +705,7 @@
 
         // Add the callback to change the label of shipping addresses depending on the focus.
         if (mRequestShipping) {
-            mPaymentUIsManager.getPaymentRequestUI().setShippingAddressSectionFocusChangedObserver(
-                    this);
+            mPaymentUIsManager.setShippingAddressSectionFocusChangedObserverForPaymentRequestUI();
         }
 
         mPaymentUIsManager.getAddressEditor().setEditorDialog(
@@ -764,73 +720,6 @@
         return true;
     }
 
-    private void createShippingSection(
-            Context context, List<AutofillProfile> unmodifiableProfiles) {
-        List<AutofillAddress> addresses = new ArrayList<>();
-
-        for (int i = 0; i < unmodifiableProfiles.size(); i++) {
-            AutofillProfile profile = unmodifiableProfiles.get(i);
-            mPaymentUIsManager.getAddressEditor().addPhoneNumberIfValid(profile.getPhoneNumber());
-
-            // Only suggest addresses that have a street address.
-            if (!TextUtils.isEmpty(profile.getStreetAddress())) {
-                addresses.add(new AutofillAddress(context, profile));
-            }
-        }
-
-        // Suggest complete addresses first.
-        Collections.sort(addresses, COMPLETENESS_COMPARATOR);
-
-        // Limit the number of suggestions.
-        addresses = addresses.subList(0, Math.min(addresses.size(), SUGGESTIONS_LIMIT));
-
-        // Load the validation rules for each unique region code.
-        Set<String> uniqueCountryCodes = new HashSet<>();
-        for (int i = 0; i < addresses.size(); ++i) {
-            String countryCode = AutofillAddress.getCountryCode(addresses.get(i).getProfile());
-            if (!uniqueCountryCodes.contains(countryCode)) {
-                uniqueCountryCodes.add(countryCode);
-                PersonalDataManager.getInstance().loadRulesForAddressNormalization(countryCode);
-            }
-        }
-
-        // Automatically select the first address if one is complete and if the merchant does
-        // not require a shipping address to calculate shipping costs.
-        boolean hasCompleteShippingAddress = !addresses.isEmpty() && addresses.get(0).isComplete();
-        int firstCompleteAddressIndex = SectionInformation.NO_SELECTION;
-        if (mPaymentUIsManager.getUiShippingOptions().getSelectedItem() != null
-                && hasCompleteShippingAddress) {
-            firstCompleteAddressIndex = 0;
-
-            // The initial label for the selected shipping address should not include the
-            // country.
-            addresses.get(firstCompleteAddressIndex).setShippingAddressLabelWithoutCountry();
-        }
-
-        // Log the number of suggested shipping addresses and whether at least one of them is
-        // complete.
-        mJourneyLogger.setNumberOfSuggestionsShown(
-                Section.SHIPPING_ADDRESS, addresses.size(), hasCompleteShippingAddress);
-
-        int missingFields = 0;
-        if (addresses.isEmpty()) {
-            // All fields are missing.
-            missingFields = AutofillAddress.CompletionStatus.INVALID_RECIPIENT
-                    | AutofillAddress.CompletionStatus.INVALID_PHONE_NUMBER
-                    | AutofillAddress.CompletionStatus.INVALID_ADDRESS;
-        } else {
-            missingFields = addresses.get(0).getMissingFieldsOfShippingProfile();
-        }
-        if (missingFields != 0) {
-            RecordHistogram.recordSparseHistogram(
-                    "PaymentRequest.MissingShippingFields", missingFields);
-        }
-
-        mPaymentUIsManager.setShippingAddressesSection(
-                new SectionInformation(PaymentRequestUI.DataType.SHIPPING_ADDRESSES,
-                        firstCompleteAddressIndex, addresses));
-    }
-
     // Implement ComponentPaymentRequestDelegate:
     /**
      * Called by the merchant website to show the payment request to the user.
@@ -1285,7 +1174,7 @@
         // Do not create shipping section When UI is not built yet. This happens when the show
         // promise gets resolved before all apps are ready.
         if (mPaymentUIsManager.getPaymentRequestUI() != null && shouldShowShippingSection()) {
-            createShippingSection(chromeActivity, mPaymentUIsManager.getAutofillProfiles());
+            mPaymentUIsManager.createShippingSectionForPaymentRequestUI(chromeActivity);
         }
 
         mWaitForUpdatedDetails = false;
@@ -1452,24 +1341,7 @@
     @Override
     public void getSectionInformation(@PaymentRequestUI.DataType final int optionType,
             final Callback<SectionInformation> callback) {
-        SectionInformation result = null;
-        switch (optionType) {
-            case PaymentRequestUI.DataType.SHIPPING_ADDRESSES:
-                result = mPaymentUIsManager.getShippingAddressesSection();
-                break;
-            case PaymentRequestUI.DataType.SHIPPING_OPTIONS:
-                result = mPaymentUIsManager.getUiShippingOptions();
-                break;
-            case PaymentRequestUI.DataType.CONTACT_DETAILS:
-                result = mPaymentUIsManager.getContactSection();
-                break;
-            case PaymentRequestUI.DataType.PAYMENT_METHODS:
-                result = mPaymentUIsManager.getPaymentMethodsSection();
-                break;
-            default:
-                assert false;
-        }
-        mHandler.post(callback.bind(result));
+        mPaymentUIsManager.getSectionInformation(optionType, callback);
     }
 
     @Override
@@ -1518,7 +1390,7 @@
                     && mPaymentUIsManager.getShippingAddressesSection() == null) {
                 ChromeActivity activity = ChromeActivity.fromWebContents(mWebContents);
                 assert activity != null;
-                createShippingSection(activity, mPaymentUIsManager.getAutofillProfiles());
+                mPaymentUIsManager.createShippingSectionForPaymentRequestUI(activity);
             }
             if (shouldShowContactSection() && mPaymentUIsManager.getContactSection() == null) {
                 ChromeActivity activity = ChromeActivity.fromWebContents(mWebContents);
@@ -1533,7 +1405,7 @@
                 AutofillPaymentInstrument card = (AutofillPaymentInstrument) paymentApp;
 
                 if (!card.isComplete()) {
-                    editCard(card);
+                    mPaymentUIsManager.editCard(card);
                     return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
                 }
             }
@@ -1551,53 +1423,14 @@
     @PaymentRequestUI.SelectionResult
     public int onSectionEditOption(@PaymentRequestUI.DataType int optionType, EditableOption option,
             Callback<PaymentInformation> callback) {
-        if (optionType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES) {
-            // Log the edit of a shipping address.
-            mJourneyLogger.incrementSelectionEdits(Section.SHIPPING_ADDRESS);
-            mPaymentUIsManager.editAddress((AutofillAddress) option);
-            mPaymentUIsManager.setPaymentInformationCallback(callback);
-
-            return PaymentRequestUI.SelectionResult.ASYNCHRONOUS_VALIDATION;
-        }
-
-        if (optionType == PaymentRequestUI.DataType.CONTACT_DETAILS) {
-            mJourneyLogger.incrementSelectionEdits(Section.CONTACT_INFO);
-            mPaymentUIsManager.editContactOnPaymentRequestUI((AutofillContact) option);
-            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
-        }
-
-        if (optionType == PaymentRequestUI.DataType.PAYMENT_METHODS) {
-            editCard((AutofillPaymentInstrument) option);
-            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
-        }
-
-        assert false;
-        return PaymentRequestUI.SelectionResult.NONE;
+        return mPaymentUIsManager.onSectionEditOption(optionType, option, callback);
     }
 
     @Override
     @PaymentRequestUI.SelectionResult
     public int onSectionAddOption(
             @PaymentRequestUI.DataType int optionType, Callback<PaymentInformation> callback) {
-        if (optionType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES) {
-            mPaymentUIsManager.editAddress(null);
-            mPaymentUIsManager.setPaymentInformationCallback(callback);
-            // Log the add of shipping address.
-            mJourneyLogger.incrementSelectionAdds(Section.SHIPPING_ADDRESS);
-            return PaymentRequestUI.SelectionResult.ASYNCHRONOUS_VALIDATION;
-        } else if (optionType == PaymentRequestUI.DataType.CONTACT_DETAILS) {
-            mPaymentUIsManager.editContactOnPaymentRequestUI(null);
-            // Log the add of contact info.
-            mJourneyLogger.incrementSelectionAdds(Section.CONTACT_INFO);
-            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
-        } else if (optionType == PaymentRequestUI.DataType.PAYMENT_METHODS) {
-            editCard(null);
-            // Log the add of credit card.
-            mJourneyLogger.incrementSelectionAdds(Section.PAYMENT_METHOD);
-            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
-        }
-
-        return PaymentRequestUI.SelectionResult.NONE;
+        return mPaymentUIsManager.onSectionAddOption(optionType, callback);
     }
 
     @Override
@@ -1610,43 +1443,6 @@
         return mPaymentUIsManager.shouldShowContactSection();
     }
 
-    private void editCard(final AutofillPaymentInstrument toEdit) {
-        if (toEdit != null) {
-            // Log the edit of a credit card.
-            mJourneyLogger.incrementSelectionEdits(Section.PAYMENT_METHOD);
-        }
-        mPaymentUIsManager.getCardEditor().edit(toEdit, new Callback<AutofillPaymentInstrument>() {
-            @Override
-            public void onResult(AutofillPaymentInstrument editedCard) {
-                if (mPaymentUIsManager.getPaymentRequestUI() == null) return;
-
-                if (editedCard != null) {
-                    // A partial or complete card came back from the editor (could have been from
-                    // adding/editing or cancelling out of the edit flow).
-                    if (!editedCard.isComplete()) {
-                        // If the card is not complete, unselect it (editor can return incomplete
-                        // information when cancelled).
-                        mPaymentUIsManager.getPaymentMethodsSection().setSelectedItemIndex(
-                                SectionInformation.NO_SELECTION);
-                    } else if (toEdit == null) {
-                        // Card is complete and we were in the "Add flow": add an item to the list.
-                        mPaymentUIsManager.getPaymentMethodsSection().addAndSelectItem(editedCard);
-                    }
-                    // If card is complete and (toEdit != null), no action needed: the card was
-                    // already selected in the UI.
-                }
-                // If |editedCard| is null, the user has cancelled out of the "Add flow". No action
-                // to take (if another card was selected prior to the add flow, it will stay
-                // selected).
-
-                mPaymentUIsManager.updateAppModifiedTotals();
-                mPaymentUIsManager.getPaymentRequestUI().updateSection(
-                        PaymentRequestUI.DataType.PAYMENT_METHODS,
-                        mPaymentUIsManager.getPaymentMethodsSection());
-            }
-        });
-    }
-
     @Override
     public void onInstrumentDetailsLoadingWithoutUI() {
         if (getClient() == null || mPaymentUIsManager.getPaymentRequestUI() == null
@@ -2232,7 +2028,7 @@
             }
         }
 
-        Collections.sort(mPendingApps, mPaymentAppComparator);
+        mPaymentUIsManager.rankPaymentAppsForPaymentRequestUI(mPendingApps);
 
         // Possibly pre-select the first app on the list.
         int selection = !mPendingApps.isEmpty() && mPendingApps.get(0).canPreselect()
@@ -2457,28 +2253,6 @@
     }
 
     @Override
-    public void onFocusChanged(@PaymentRequestUI.DataType int dataType, boolean willFocus) {
-        assert dataType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES;
-
-        if (mPaymentUIsManager.getShippingAddressesSection().getSelectedItem() == null) return;
-
-        AutofillAddress selectedAddress =
-                (AutofillAddress) mPaymentUIsManager.getShippingAddressesSection()
-                        .getSelectedItem();
-
-        // The label should only include the country if the view is focused.
-        if (willFocus) {
-            selectedAddress.setShippingAddressLabelWithCountry();
-        } else {
-            selectedAddress.setShippingAddressLabelWithoutCountry();
-        }
-
-        mPaymentUIsManager.getPaymentRequestUI().updateSection(
-                PaymentRequestUI.DataType.SHIPPING_ADDRESSES,
-                mPaymentUIsManager.getShippingAddressesSection());
-    }
-
-    @Override
     public void onAddressNormalized(AutofillProfile profile) {
         PaymentRequestClient client = getClient();
         if (client == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java
index cee3b3d..d0f2e1b3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java
@@ -14,7 +14,6 @@
 import org.chromium.chrome.browser.payments.AutofillAddress;
 import org.chromium.chrome.browser.payments.AutofillContact;
 import org.chromium.chrome.browser.payments.ContactEditor;
-import org.chromium.chrome.browser.payments.PaymentRequestImpl;
 import org.chromium.components.payments.JourneyLogger;
 import org.chromium.components.payments.Section;
 
@@ -138,7 +137,7 @@
             if (isNewSuggestion) uniqueContacts.add(contact);
 
             // Limit the number of suggestions.
-            if (uniqueContacts.size() == PaymentRequestImpl.SUGGESTIONS_LIMIT) break;
+            if (uniqueContacts.size() == PaymentUIsManager.SUGGESTIONS_LIMIT) break;
         }
 
         // Automatically select the first address if it is complete.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppComparator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentAppComparator.java
similarity index 97%
rename from chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppComparator.java
rename to chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentAppComparator.java
index 740afcf..a0d2594 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppComparator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentAppComparator.java
@@ -2,8 +2,9 @@
 // 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.payments;
+package org.chromium.chrome.browser.payments.ui;
 
+import org.chromium.chrome.browser.payments.PaymentPreferencesUtil;
 import org.chromium.components.autofill.Completable;
 import org.chromium.components.payments.PaymentApp;
 import org.chromium.components.payments.PaymentRequestParams;
@@ -11,7 +12,7 @@
 
 import java.util.Comparator;
 
-/** A comparator that is used to rank the payment apps to be listed in the payment sheet. */
+/** A comparator that is used to rank the payment apps to be listed on the PaymentRequest UI. */
 /* package */ class PaymentAppComparator implements Comparator<PaymentApp> {
     private final PaymentRequestParams mParams;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUIsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUIsManager.java
index b827ebc..15f69e6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUIsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUIsManager.java
@@ -4,12 +4,15 @@
 
 package org.chromium.chrome.browser.payments.ui;
 
+import android.content.Context;
 import android.os.Handler;
+import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Callback;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.autofill.PersonalDataManager;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
@@ -19,6 +22,7 @@
 import org.chromium.chrome.browser.payments.AutofillContact;
 import org.chromium.chrome.browser.payments.AutofillPaymentAppCreator;
 import org.chromium.chrome.browser.payments.AutofillPaymentAppFactory;
+import org.chromium.chrome.browser.payments.AutofillPaymentInstrument;
 import org.chromium.chrome.browser.payments.CardEditor;
 import org.chromium.chrome.browser.payments.ContactEditor;
 import org.chromium.chrome.browser.payments.PaymentRequestImpl;
@@ -27,14 +31,18 @@
 import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator;
 import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator.PaymentHandlerUiObserver;
 import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator.PaymentHandlerWebContentsObserver;
+import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.OptionSection.FocusChangedObserver;
+import org.chromium.components.autofill.Completable;
 import org.chromium.components.autofill.EditableOption;
 import org.chromium.components.payments.CurrencyFormatter;
+import org.chromium.components.payments.JourneyLogger;
 import org.chromium.components.payments.PaymentApp;
 import org.chromium.components.payments.PaymentAppType;
 import org.chromium.components.payments.PaymentFeatureList;
 import org.chromium.components.payments.PaymentOptionsUtils;
 import org.chromium.components.payments.PaymentRequestLifecycleObserver;
 import org.chromium.components.payments.PaymentRequestParams;
+import org.chromium.components.payments.Section;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.payments.mojom.PayerDetail;
 import org.chromium.payments.mojom.PaymentCurrencyAmount;
@@ -48,6 +56,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -62,8 +71,16 @@
  * should be moved into this class.
  */
 public class PaymentUIsManager implements SettingsAutofillAndPaymentsObserver.Observer,
-                                          PaymentRequestLifecycleObserver,
-                                          PaymentHandlerUiObserver {
+                                          PaymentRequestLifecycleObserver, PaymentHandlerUiObserver,
+                                          FocusChangedObserver {
+    /** Limit in the number of suggested items in a section. */
+    /* package */ static final int SUGGESTIONS_LIMIT = 4;
+
+    // Reverse order of the comparator to sort in descending order of completeness scores.
+    private static final Comparator<Completable> COMPLETENESS_COMPARATOR =
+            (a, b) -> (PaymentAppComparator.compareCompletablesByCompleteness(b, a));
+    private final Comparator<PaymentApp> mPaymentAppComparator;
+
     private final boolean mIsOffTheRecord;
     private final Handler mHandler = new Handler();
     private final Queue<Runnable> mRetryQueue = new LinkedList<>();
@@ -89,6 +106,7 @@
     private boolean mHaveRequestedAutofillData = true;
     private List<AutofillProfile> mAutofillProfiles;
     private Boolean mCanUserAddCreditCard;
+    private final JourneyLogger mJourneyLogger;
 
     /** The delegate of this class. */
     public interface Delegate {
@@ -160,9 +178,10 @@
      * @param params The parameters of the payment request specified by the merchant.
      * @param webContents The WebContents of the merchant page.
      * @param isOffTheRecord Whether merchant page is in an isOffTheRecord tab.
+     * @param journeyLogger The logger of the user journey.
      */
     public PaymentUIsManager(Delegate delegate, PaymentRequestParams params,
-            WebContents webContents, boolean isOffTheRecord) {
+            WebContents webContents, boolean isOffTheRecord, JourneyLogger journeyLogger) {
         mDelegate = delegate;
         mParams = params;
 
@@ -172,10 +191,12 @@
         // PaymentRequest card editor does not show the organization name in the dropdown with the
         // billing address labels.
         mCardEditor = new CardEditor(webContents, mAddressEditor, /*includeOrgLabel=*/false);
+        mJourneyLogger = journeyLogger;
 
         mPaymentUisShowStateReconciler = new PaymentUisShowStateReconciler();
         mCurrencyFormatterMap = new HashMap<>();
         mIsOffTheRecord = isOffTheRecord;
+        mPaymentAppComparator = new PaymentAppComparator(/*params=*/mParams);
     }
 
     /**
@@ -761,9 +782,9 @@
 
     /**
      * Edit the contact information on the PaymentRequest UI.
-     * @param toEdit The information to edit.
+     * @param toEdit The information to edit, allowed to be null.
      **/
-    public void editContactOnPaymentRequestUI(final AutofillContact toEdit) {
+    public void editContactOnPaymentRequestUI(@Nullable final AutofillContact toEdit) {
         mContactEditor.edit(toEdit, new Callback<AutofillContact>() {
             @Override
             public void onResult(AutofillContact editedContact) {
@@ -802,9 +823,9 @@
 
     /**
      * Edit the address on the PaymentRequest UI.
-     * @param toEdit The address to edit.
+     * @param toEdit The address to be updated with, allowed to be null.
      */
-    public void editAddress(final AutofillAddress toEdit) {
+    public void editAddress(@Nullable final AutofillAddress toEdit) {
         mAddressEditor.edit(toEdit, new Callback<AutofillAddress>() {
             @Override
             public void onResult(AutofillAddress editedAddress) {
@@ -854,4 +875,252 @@
             }
         });
     }
+
+    /** Create a shipping section for PaymentRequest UI. */
+    public void createShippingSectionForPaymentRequestUI(Context context) {
+        List<AutofillAddress> addresses = new ArrayList<>();
+
+        for (int i = 0; i < mAutofillProfiles.size(); i++) {
+            AutofillProfile profile = mAutofillProfiles.get(i);
+            mAddressEditor.addPhoneNumberIfValid(profile.getPhoneNumber());
+
+            // Only suggest addresses that have a street address.
+            if (!TextUtils.isEmpty(profile.getStreetAddress())) {
+                addresses.add(new AutofillAddress(context, profile));
+            }
+        }
+
+        // Suggest complete addresses first.
+        Collections.sort(addresses, COMPLETENESS_COMPARATOR);
+
+        // Limit the number of suggestions.
+        addresses = addresses.subList(0, Math.min(addresses.size(), SUGGESTIONS_LIMIT));
+
+        // Load the validation rules for each unique region code.
+        Set<String> uniqueCountryCodes = new HashSet<>();
+        for (int i = 0; i < addresses.size(); ++i) {
+            String countryCode = AutofillAddress.getCountryCode(addresses.get(i).getProfile());
+            if (!uniqueCountryCodes.contains(countryCode)) {
+                uniqueCountryCodes.add(countryCode);
+                PersonalDataManager.getInstance().loadRulesForAddressNormalization(countryCode);
+            }
+        }
+
+        // Automatically select the first address if one is complete and if the merchant does
+        // not require a shipping address to calculate shipping costs.
+        boolean hasCompleteShippingAddress = !addresses.isEmpty() && addresses.get(0).isComplete();
+        int firstCompleteAddressIndex = SectionInformation.NO_SELECTION;
+        if (mUiShippingOptions.getSelectedItem() != null && hasCompleteShippingAddress) {
+            firstCompleteAddressIndex = 0;
+
+            // The initial label for the selected shipping address should not include the
+            // country.
+            addresses.get(firstCompleteAddressIndex).setShippingAddressLabelWithoutCountry();
+        }
+
+        // Log the number of suggested shipping addresses and whether at least one of them is
+        // complete.
+        mJourneyLogger.setNumberOfSuggestionsShown(
+                Section.SHIPPING_ADDRESS, addresses.size(), hasCompleteShippingAddress);
+
+        int missingFields = 0;
+        if (addresses.isEmpty()) {
+            // All fields are missing.
+            missingFields = AutofillAddress.CompletionStatus.INVALID_RECIPIENT
+                    | AutofillAddress.CompletionStatus.INVALID_PHONE_NUMBER
+                    | AutofillAddress.CompletionStatus.INVALID_ADDRESS;
+        } else {
+            missingFields = addresses.get(0).getMissingFieldsOfShippingProfile();
+        }
+        if (missingFields != 0) {
+            RecordHistogram.recordSparseHistogram(
+                    "PaymentRequest.MissingShippingFields", missingFields);
+        }
+
+        mShippingAddressesSection = new SectionInformation(
+                PaymentRequestUI.DataType.SHIPPING_ADDRESSES, firstCompleteAddressIndex, addresses);
+    }
+
+    /**
+     * Rank the payment apps for PaymentRequest UI.
+     * @param paymentApps A list of payment apps to be ranked in place.
+     */
+    public void rankPaymentAppsForPaymentRequestUI(List<PaymentApp> paymentApps) {
+        Collections.sort(paymentApps, mPaymentAppComparator);
+    }
+
+    /**
+     * Edit the credit cards on the PaymentRequest UI.
+     * @param toEdit The AutofillPaymentInstrument whose credit card is to replace those on the UI,
+     *         allowed to be null.
+     */
+    public void editCard(@Nullable final AutofillPaymentInstrument toEdit) {
+        if (toEdit != null) {
+            // Log the edit of a credit card.
+            mJourneyLogger.incrementSelectionEdits(Section.PAYMENT_METHOD);
+        }
+        mCardEditor.edit(toEdit, new Callback<AutofillPaymentInstrument>() {
+            @Override
+            public void onResult(AutofillPaymentInstrument editedCard) {
+                if (mPaymentRequestUI == null) return;
+
+                if (editedCard != null) {
+                    // A partial or complete card came back from the editor (could have been from
+                    // adding/editing or cancelling out of the edit flow).
+                    if (!editedCard.isComplete()) {
+                        // If the card is not complete, unselect it (editor can return incomplete
+                        // information when cancelled).
+                        mPaymentMethodsSection.setSelectedItemIndex(
+                                SectionInformation.NO_SELECTION);
+                    } else if (toEdit == null) {
+                        // Card is complete and we were in the "Add flow": add an item to the list.
+                        mPaymentMethodsSection.addAndSelectItem(editedCard);
+                    }
+                    // If card is complete and (toEdit != null), no action needed: the card was
+                    // already selected in the UI.
+                }
+                // If |editedCard| is null, the user has cancelled out of the "Add flow". No action
+                // to take (if another card was selected prior to the add flow, it will stay
+                // selected).
+
+                updateAppModifiedTotals();
+                mPaymentRequestUI.updateSection(
+                        PaymentRequestUI.DataType.PAYMENT_METHODS, mPaymentMethodsSection);
+            }
+        });
+    }
+
+    /** See {@link PaymentRequestUI.getSelectionInformation}. */
+    public void getSectionInformation(@PaymentRequestUI.DataType final int optionType,
+            final Callback<SectionInformation> callback) {
+        SectionInformation result = null;
+        switch (optionType) {
+            case PaymentRequestUI.DataType.SHIPPING_ADDRESSES:
+                result = mShippingAddressesSection;
+                break;
+            case PaymentRequestUI.DataType.SHIPPING_OPTIONS:
+                result = mUiShippingOptions;
+                break;
+            case PaymentRequestUI.DataType.CONTACT_DETAILS:
+                result = mContactSection;
+                break;
+            case PaymentRequestUI.DataType.PAYMENT_METHODS:
+                result = mPaymentMethodsSection;
+                break;
+            default:
+                assert false;
+        }
+        mHandler.post(callback.bind(result));
+    }
+
+    // Implement PaymentRequestSection.FocusChangedObserver:
+    @Override
+    public void onFocusChanged(@PaymentRequestUI.DataType int dataType, boolean willFocus) {
+        assert dataType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES;
+
+        if (mShippingAddressesSection.getSelectedItem() == null) return;
+
+        AutofillAddress selectedAddress =
+                (AutofillAddress) mShippingAddressesSection.getSelectedItem();
+
+        // The label should only include the country if the view is focused.
+        if (willFocus) {
+            selectedAddress.setShippingAddressLabelWithCountry();
+        } else {
+            selectedAddress.setShippingAddressLabelWithoutCountry();
+        }
+
+        mPaymentRequestUI.updateSection(
+                PaymentRequestUI.DataType.SHIPPING_ADDRESSES, mShippingAddressesSection);
+    }
+
+    /** See {@link PaymentRequestUI.Client.onSectionAddOption}. */
+    public int onSectionAddOption(
+            @PaymentRequestUI.DataType int optionType, Callback<PaymentInformation> callback) {
+        if (optionType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES) {
+            editAddress(null);
+            mPaymentInformationCallback = callback;
+            // Log the add of shipping address.
+            mJourneyLogger.incrementSelectionAdds(Section.SHIPPING_ADDRESS);
+            return PaymentRequestUI.SelectionResult.ASYNCHRONOUS_VALIDATION;
+        } else if (optionType == PaymentRequestUI.DataType.CONTACT_DETAILS) {
+            editContactOnPaymentRequestUI(null);
+            // Log the add of contact info.
+            mJourneyLogger.incrementSelectionAdds(Section.CONTACT_INFO);
+            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
+        } else if (optionType == PaymentRequestUI.DataType.PAYMENT_METHODS) {
+            editCard(null);
+            // Log the add of credit card.
+            mJourneyLogger.incrementSelectionAdds(Section.PAYMENT_METHOD);
+            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
+        }
+
+        return PaymentRequestUI.SelectionResult.NONE;
+    }
+
+    @PaymentRequestUI.SelectionResult
+    public int onSectionEditOption(@PaymentRequestUI.DataType int optionType, EditableOption option,
+            Callback<PaymentInformation> callback) {
+        if (optionType == PaymentRequestUI.DataType.SHIPPING_ADDRESSES) {
+            // Log the edit of a shipping address.
+            mJourneyLogger.incrementSelectionEdits(Section.SHIPPING_ADDRESS);
+            editAddress((AutofillAddress) option);
+            mPaymentInformationCallback = callback;
+
+            return PaymentRequestUI.SelectionResult.ASYNCHRONOUS_VALIDATION;
+        }
+
+        if (optionType == PaymentRequestUI.DataType.CONTACT_DETAILS) {
+            mJourneyLogger.incrementSelectionEdits(Section.CONTACT_INFO);
+            editContactOnPaymentRequestUI((AutofillContact) option);
+            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
+        }
+
+        if (optionType == PaymentRequestUI.DataType.PAYMENT_METHODS) {
+            editCard((AutofillPaymentInstrument) option);
+            return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
+        }
+
+        assert false;
+        return PaymentRequestUI.SelectionResult.NONE;
+    }
+
+    /** Set a change observer for the shipping address section on the PaymentRequest UI. */
+    public void setShippingAddressSectionFocusChangedObserverForPaymentRequestUI() {
+        mPaymentRequestUI.setShippingAddressSectionFocusChangedObserver(this);
+    }
+
+    /**
+     * @return true when there is exactly one available payment app which can provide all requested
+     * information including shipping address and payer's contact information whenever needed.
+     */
+    public boolean onlySingleAppCanProvideAllRequiredInformation() {
+        assert mPaymentMethodsSection != null;
+
+        if (!PaymentOptionsUtils.requestAnyInformation(mParams.getPaymentOptions())) {
+            return mPaymentMethodsSection.getSize() == 1
+                    && !((PaymentApp) mPaymentMethodsSection.getItem(0)).isAutofillInstrument();
+        }
+
+        boolean anAppCanProvideAllInfo = false;
+        int sectionSize = mPaymentMethodsSection.getSize();
+        for (int i = 0; i < sectionSize; i++) {
+            PaymentApp app = (PaymentApp) mPaymentMethodsSection.getItem(i);
+            if ((!PaymentOptionsUtils.requestShipping(mParams.getPaymentOptions())
+                        || app.handlesShippingAddress())
+                    && (!PaymentOptionsUtils.requestPayerName(mParams.getPaymentOptions())
+                            || app.handlesPayerName())
+                    && (!PaymentOptionsUtils.requestPayerPhone(mParams.getPaymentOptions())
+                            || app.handlesPayerPhone())
+                    && (!PaymentOptionsUtils.requestPayerEmail(mParams.getPaymentOptions())
+                            || app.handlesPayerEmail())) {
+                // There is more than one available app that can provide all merchant requested
+                // information information.
+                if (anAppCanProvideAllInfo) return false;
+
+                anAppCanProvideAllInfo = true;
+            }
+        }
+        return anAppCanProvideAllInfo;
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java
index 1fb617c..de77547 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java
@@ -16,10 +16,12 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.safe_browsing.SafeBrowsingApiBridge;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
@@ -34,6 +36,7 @@
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@Features.DisableFeatures({ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS})
 public final class SafeBrowsingTest {
     @Rule
     public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
index ceac214..b840207 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -318,8 +318,11 @@
      */
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.SPLIT_CACHE_BY_NETWORK_ISOLATION_KEY)
-    public void testSafeBrowsingMainResource() throws Exception {
+    @DisableFeatures({ChromeFeatureList.SPLIT_CACHE_BY_NETWORK_ISOLATION_KEY,
+            ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS})
+
+    public void
+    testSafeBrowsingMainResource() throws Exception {
         testSafeBrowsingMainResource(true /* afterNative */, false /* splitCacheEnabled */);
     }
 
@@ -330,6 +333,7 @@
     @Test
     @SmallTest
     @EnableFeatures(ChromeFeatureList.SPLIT_CACHE_BY_NETWORK_ISOLATION_KEY)
+    @DisableFeatures(ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS)
     public void testSafeBrowsingMainResourceWithSplitCache() throws Exception {
         testSafeBrowsingMainResource(true /* afterNative */, true /* splitCacheEnabled */);
     }
@@ -340,6 +344,7 @@
      */
     @Test
     @SmallTest
+    @DisableFeatures({ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS})
     public void testSafeBrowsingSubresource() throws Exception {
         testSafeBrowsingSubresource(true);
     }
@@ -350,8 +355,10 @@
      */
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.SPLIT_CACHE_BY_NETWORK_ISOLATION_KEY)
-    public void testSafeBrowsingMainResourceBeforeNative() throws Exception {
+    @DisableFeatures({ChromeFeatureList.SPLIT_CACHE_BY_NETWORK_ISOLATION_KEY,
+            ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS})
+    public void
+    testSafeBrowsingMainResourceBeforeNative() throws Exception {
         testSafeBrowsingMainResource(false /* afterNative */, false /* splitCacheEnabled */);
     }
 
@@ -361,6 +368,7 @@
      */
     @Test
     @SmallTest
+    @Features.DisableFeatures({ChromeFeatureList.SAFE_BROWSING_DELAYED_WARNINGS})
     public void testSafeBrowsingSubresourceBeforeNative() throws Exception {
         testSafeBrowsingSubresource(false);
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurfaceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurfaceTest.java
index e5904df..10cf8911 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurfaceTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurfaceTest.java
@@ -38,6 +38,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Captor;
+import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -590,12 +591,17 @@
     @SmallTest
     public void testClearAll() {
         FeedStreamSurface.startup();
+        InOrder order = Mockito.inOrder(mFeedStreamSurfaceJniMock, mProcessScope);
         mFeedStreamSurface.surfaceOpened();
-        verify(mFeedStreamSurfaceJniMock).surfaceOpened(anyLong(), any(FeedStreamSurface.class));
+        order.verify(mFeedStreamSurfaceJniMock)
+                .surfaceOpened(anyLong(), any(FeedStreamSurface.class));
 
         FeedStreamSurface.clearAll();
-        verify(mFeedStreamSurfaceJniMock).surfaceClosed(anyLong(), any(FeedStreamSurface.class));
-        verify(mProcessScope).resetAccount();
+        order.verify(mFeedStreamSurfaceJniMock)
+                .surfaceClosed(anyLong(), any(FeedStreamSurface.class));
+        order.verify(mProcessScope).resetAccount();
+        order.verify(mFeedStreamSurfaceJniMock)
+                .surfaceOpened(anyLong(), any(FeedStreamSurface.class));
     }
 
     @Test
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ea32c54..4eba640 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6060,6 +6060,9 @@
         <message name="IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK" desc="The text of the link in the password sheet that opens the password management section.">
           Manage passwords
         </message>
+        <message name="IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD" desc="The text of the link in the password sheet that opens a bottom sheet which shows all saved passwords from any origin.">
+          Use other password
+        </message>
         <message name="IDS_PASSWORD_MANAGER_ACCESSORY_GENERATE_PASSWORD_BUTTON_TITLE" desc="Text for the button used to generate a password.">
           Suggest strong password
         </message>
diff --git a/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD.png.sha1 b/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD.png.sha1
new file mode 100644
index 0000000..8f1c92d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD.png.sha1
@@ -0,0 +1 @@
+813869837d077ccb1dc094eaf062345de9c70116
\ No newline at end of file
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp
index 3927896..2d1e688 100644
--- a/chrome/app/profiles_strings.grdp
+++ b/chrome/app/profiles_strings.grdp
@@ -667,6 +667,9 @@
     <message name="IDS_PROFILE_PICKER_ASK_ON_STARTUP" desc="Text for the checkbox on the profile picker main view">
       Ask on startup
     </message>
+    <message name="IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON" desc="Text for the profile picker main view button that launches guest session.">
+      Browse as Guest
+    </message>
     <message name="IDS_PROFILE_PICKER_BACK_BUTTON_LABEL" desc="Label for a button that navigates user to the previous page">
       Back
     </message>
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1
new file mode 100644
index 0000000..fbd2c11
--- /dev/null
+++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1
@@ -0,0 +1 @@
+12998557c02a35e50d016c53c9ab9bc3a778c724
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c7ed1f0..10fff30 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2787,6 +2787,10 @@
       "password_check/android/password_check_bridge.h",
       "password_manager/android/account_chooser_dialog_android.cc",
       "password_manager/android/account_chooser_dialog_android.h",
+      "password_manager/android/all_passwords_bottom_sheet_controller.cc",
+      "password_manager/android/all_passwords_bottom_sheet_controller.h",
+      "password_manager/android/all_passwords_bottom_sheet_view.cc",
+      "password_manager/android/all_passwords_bottom_sheet_view.h",
       "password_manager/android/auto_signin_first_run_dialog_android.cc",
       "password_manager/android/auto_signin_first_run_dialog_android.h",
       "password_manager/android/auto_signin_prompt_controller.cc",
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.cc b/chrome/browser/autofill/manual_filling_controller_impl.cc
index 616cb0a..977ea9c 100644
--- a/chrome/browser/autofill/manual_filling_controller_impl.cc
+++ b/chrome/browser/autofill/manual_filling_controller_impl.cc
@@ -297,6 +297,7 @@
   switch (action) {
     case AccessoryAction::GENERATE_PASSWORD_MANUAL:
     case AccessoryAction::MANAGE_PASSWORDS:
+    case AccessoryAction::USE_OTHER_PASSWORD:
     case AccessoryAction::GENERATE_PASSWORD_AUTOMATIC:
     case AccessoryAction::TOGGLE_SAVE_PASSWORDS:
       return GetPasswordController();
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
index 62a0c79..d498242 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
@@ -81,14 +81,13 @@
 
 void SetPolicy(policy::PolicyMap* policies,
                const char* key,
-               std::unique_ptr<base::Value> value) {
+               base::Value value) {
   policies->Set(key, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                 policy::POLICY_SOURCE_PLATFORM, std::move(value), nullptr);
 }
 
 void EnableBrowserSwitcher(policy::PolicyMap* policies) {
-  SetPolicy(policies, policy::key::kBrowserSwitcherEnabled,
-            std::make_unique<base::Value>(true));
+  SetPolicy(policies, policy::key::kBrowserSwitcherEnabled, base::Value(true));
 }
 
 }  // namespace
@@ -128,7 +127,7 @@
     policy::PolicyMap policies;
     EnableBrowserSwitcher(&policies);
     SetPolicy(&policies, policy::key::kBrowserSwitcherUseIeSitelist,
-              std::make_unique<base::Value>(use_ie_sitelist));
+              base::Value(use_ie_sitelist));
     provider_.UpdateChromePolicy(policies);
     base::RunLoop().RunUntilIdle();
   }
@@ -137,7 +136,7 @@
     policy::PolicyMap policies;
     EnableBrowserSwitcher(&policies);
     SetPolicy(&policies, policy::key::kBrowserSwitcherExternalSitelistUrl,
-              std::make_unique<base::Value>(url));
+              base::Value(url));
     provider_.UpdateChromePolicy(policies);
     base::RunLoop().RunUntilIdle();
   }
@@ -368,12 +367,12 @@
                        ExternalGreylistFetchAndParseAfterStartup) {
   policy::PolicyMap policies;
   EnableBrowserSwitcher(&policies);
-  auto url_list = std::make_unique<base::ListValue>();
-  url_list->Append("*");
+  base::Value url_list(base::Value::Type::LIST);
+  url_list.Append("*");
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlList,
             std::move(url_list));
   SetPolicy(&policies, policy::key::kBrowserSwitcherExternalGreylistUrl,
-            std::make_unique<base::Value>(kAValidUrl));
+            base::Value(kAValidUrl));
   policy_provider().UpdateChromePolicy(policies);
   base::RunLoop().RunUntilIdle();
 
@@ -513,23 +512,23 @@
   policy::PolicyMap policies;
   EnableBrowserSwitcher(&policies);
   SetPolicy(&policies, policy::key::kAlternativeBrowserPath,
-            std::make_unique<base::Value>("IExplore.exe"));
-  auto alt_params = std::make_unique<base::ListValue>();
-  alt_params->Append(base::Value("--bogus-flag"));
+            base::Value("IExplore.exe"));
+  base::Value alt_params(base::Value::Type::LIST);
+  alt_params.Append("--bogus-flag");
   SetPolicy(&policies, policy::key::kAlternativeBrowserParameters,
             std::move(alt_params));
   SetPolicy(&policies, policy::key::kBrowserSwitcherChromePath,
-            std::make_unique<base::Value>("chrome.exe"));
-  auto chrome_params = std::make_unique<base::ListValue>();
-  chrome_params->Append(base::Value("--force-dark-mode"));
+            base::Value("chrome.exe"));
+  base::Value chrome_params(base::Value::Type::LIST);
+  chrome_params.Append("--force-dark-mode");
   SetPolicy(&policies, policy::key::kBrowserSwitcherChromeParameters,
             std::move(chrome_params));
-  auto url_list = std::make_unique<base::ListValue>();
-  url_list->Append(base::Value("example.com"));
+  base::Value url_list(base::Value::Type::LIST);
+  url_list.Append("example.com");
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlList,
             std::move(url_list));
-  auto greylist = std::make_unique<base::ListValue>();
-  greylist->Append(base::Value("foo.example.com"));
+  base::Value greylist(base::Value::Type::LIST);
+  greylist.Append("foo.example.com");
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlGreylist,
             std::move(greylist));
   policy_provider().UpdateChromePolicy(policies);
@@ -580,13 +579,11 @@
   policy::PolicyMap policies;
   EnableBrowserSwitcher(&policies);
   SetPolicy(&policies, policy::key::kBrowserSwitcherExternalSitelistUrl,
-            std::make_unique<base::Value>(
-                net::FilePathToFileURL(external_sitelist_path).spec()));
+            base::Value(net::FilePathToFileURL(external_sitelist_path).spec()));
   SetPolicy(&policies, policy::key::kBrowserSwitcherExternalGreylistUrl,
-            std::make_unique<base::Value>(
-                net::FilePathToFileURL(external_greylist_path).spec()));
+            base::Value(net::FilePathToFileURL(external_greylist_path).spec()));
   SetPolicy(&policies, policy::key::kBrowserSwitcherUseIeSitelist,
-            std::make_unique<base::Value>(true));
+            base::Value(true));
   policy_provider().UpdateChromePolicy(policies);
   base::RunLoop().RunUntilIdle();
   BrowserSwitcherServiceWin::SetIeemSitelistUrlForTesting(
diff --git a/chrome/browser/browsing_data/access_context_audit_service.cc b/chrome/browser/browsing_data/access_context_audit_service.cc
index 09b70a9..ced41ab 100644
--- a/chrome/browser/browsing_data/access_context_audit_service.cc
+++ b/chrome/browser/browsing_data/access_context_audit_service.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/browsing_data/access_context_audit_service.h"
 #include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
+#include "base/updateable_sequenced_task_runner.h"
 #include "chrome/browser/browsing_data/access_context_audit_database.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -28,10 +28,13 @@
 
   // Tests may have provided a task runner already.
   if (!database_task_runner_) {
-    database_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
-        {base::MayBlock(), base::WithBaseSyncPrimitives(),
-         base::TaskPriority::USER_VISIBLE,
-         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+    // Task runner is set to block shutdown as content settings are checked on
+    // service shutdown and records which should not be persisted are removed.
+    database_task_runner_ =
+        base::ThreadPool::CreateUpdateableSequencedTaskRunner(
+            {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+             base::ThreadPolicy::PREFER_BACKGROUND,
+             base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
   }
 
   if (!database_task_runner_->PostTask(
@@ -81,10 +84,25 @@
 
 void AccessContextAuditService::GetAllAccessRecords(
     AccessContextRecordsCallback callback) {
+  if (!user_visible_tasks_in_progress++)
+    database_task_runner_->UpdatePriority(base::TaskPriority::USER_VISIBLE);
+
   database_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&AccessContextAuditDatabase::GetAllRecords, database_),
-      std::move(callback));
+      base::BindOnce(
+          &AccessContextAuditService::CompleteGetAllAccessRecordsInternal,
+          weak_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void AccessContextAuditService::CompleteGetAllAccessRecordsInternal(
+    AccessContextRecordsCallback callback,
+    std::vector<AccessContextAuditDatabase::AccessRecord> records) {
+  DCHECK_GT(user_visible_tasks_in_progress, 0);
+  if (!--user_visible_tasks_in_progress)
+    database_task_runner_->UpdatePriority(base::TaskPriority::BEST_EFFORT);
+
+  std::move(callback).Run(std::move(records));
 }
 
 void AccessContextAuditService::Shutdown() {
@@ -161,7 +179,7 @@
 }
 
 void AccessContextAuditService::SetTaskRunnerForTesting(
-    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+    scoped_refptr<base::UpdateableSequencedTaskRunner> task_runner) {
   DCHECK(!database_task_runner_);
   database_task_runner_ = std::move(task_runner);
 }
diff --git a/chrome/browser/browsing_data/access_context_audit_service.h b/chrome/browser/browsing_data/access_context_audit_service.h
index ad27d64..954bd5f 100644
--- a/chrome/browser/browsing_data/access_context_audit_service.h
+++ b/chrome/browser/browsing_data/access_context_audit_service.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_BROWSING_DATA_ACCESS_CONTEXT_AUDIT_SERVICE_H_
 #define CHROME_BROWSER_BROWSING_DATA_ACCESS_CONTEXT_AUDIT_SERVICE_H_
 
+#include "base/updateable_sequenced_task_runner.h"
 #include "chrome/browser/browsing_data/access_context_audit_database.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/browsing_data/content/local_shared_objects_container.h"
@@ -46,6 +47,11 @@
   // |callback|.
   void GetAllAccessRecords(AccessContextRecordsCallback callback);
 
+  // Called on completion of GetAllAccessRecords.
+  void CompleteGetAllAccessRecordsInternal(
+      AccessContextRecordsCallback callback,
+      std::vector<AccessContextAuditDatabase::AccessRecord> records);
+
   // KeyedService:
   void Shutdown() override;
 
@@ -63,7 +69,7 @@
   // Override internal task runner with provided task runner. Must be called
   // before Init().
   void SetTaskRunnerForTesting(
-      scoped_refptr<base::SequencedTaskRunner> task_runner);
+      scoped_refptr<base::UpdateableSequencedTaskRunner> task_runner);
 
  private:
   friend class AccessContextAuditServiceTest;
@@ -73,7 +79,9 @@
   void ClearSessionOnlyRecords();
 
   scoped_refptr<AccessContextAuditDatabase> database_;
-  scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
+  scoped_refptr<base::UpdateableSequencedTaskRunner> database_task_runner_;
+
+  int user_visible_tasks_in_progress = 0;
 
   base::Clock* clock_;
   Profile* profile_;
@@ -83,6 +91,7 @@
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
       history_observer_{this};
 
+  base::WeakPtrFactory<AccessContextAuditService> weak_factory_{this};
   DISALLOW_COPY_AND_ASSIGN(AccessContextAuditService);
 };
 
diff --git a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
index 3d1f821..bd92371 100644
--- a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
+++ b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/scoped_temp_dir.h"
 #include "base/i18n/time_formatting.h"
+#include "base/test/bind_test_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/test_simple_task_runner.h"
@@ -105,8 +106,7 @@
       content::BrowserContext* context) {
     std::unique_ptr<AccessContextAuditService> service(
         new AccessContextAuditService(static_cast<Profile*>(context)));
-    service->SetTaskRunnerForTesting(
-        browser_task_environment_.GetMainThreadTaskRunner());
+    service->SetTaskRunnerForTesting(task_runner_);
     service->Init(temp_directory_.GetPath(), cookie_manager(),
                   history_service());
     return service;
@@ -116,9 +116,12 @@
     feature_list_.InitWithFeatures(
         {features::kClientStorageAccessContextAuditing}, {});
 
+    task_runner_ = base::ThreadPool::CreateUpdateableSequencedTaskRunner(
+        {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+         base::ThreadPolicy::PREFER_BACKGROUND,
+         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+
     ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
-    task_runner_ = scoped_refptr<base::TestSimpleTaskRunner>(
-        new base::TestSimpleTaskRunner);
 
     TestingProfile::Builder builder;
     builder.AddTestingFactory(
@@ -133,18 +136,28 @@
             base::Unretained(this)));
     builder.SetPath(temp_directory_.GetPath());
     profile_ = builder.Build();
+    FlushSequencedTaskRunner();
     browser_task_environment_.RunUntilIdle();
   }
 
-  void AccessRecordCallback(
-      std::vector<AccessContextAuditDatabase::AccessRecord> records) {
-    records_ = records;
+  std::vector<AccessContextAuditDatabase::AccessRecord> GetAllAccessRecords() {
+    base::RunLoop run_loop;
+    std::vector<AccessContextAuditDatabase::AccessRecord> records_out;
+    service()->GetAllAccessRecords(base::BindLambdaForTesting(
+        [&](std::vector<AccessContextAuditDatabase::AccessRecord> records) {
+          records_out = records;
+          run_loop.QuitWhenIdle();
+        }));
+    run_loop.Run();
+    return records_out;
   }
 
-  std::vector<AccessContextAuditDatabase::AccessRecord> GetReturnedRecords() {
-    return records_;
+  void FlushSequencedTaskRunner() {
+    base::RunLoop run_loop;
+    task_runner_->PostTask(FROM_HERE, base::BindLambdaForTesting(
+                                          [&]() { run_loop.QuitWhenIdle(); }));
+    run_loop.Run();
   }
-  void ClearReturnedRecords() { records_.clear(); }
 
   TestCookieManager* cookie_manager() { return &cookie_manager_; }
   base::SimpleTestClock* clock() { return &clock_; }
@@ -163,7 +176,7 @@
   history::HistoryService* history_service_;
   base::test::ScopedFeatureList feature_list_;
 
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::UpdateableSequencedTaskRunner> task_runner_;
   std::vector<AccessContextAuditDatabase::AccessRecord> records_;
 };
 
@@ -191,16 +204,11 @@
                                 kTopFrameOrigin);
 
   // Ensure that the record of these accesses is correctly returned.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-
-  EXPECT_EQ(2u, GetReturnedRecords().size());
-  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+  auto records = GetAllAccessRecords();
+  EXPECT_EQ(2u, records.size());
+  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin, records);
   CheckContainsCookieRecord(test_non_persistent_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+                            records);
 
   // Check that informing the service of non-deletion changes to the cookies
   // via the CookieChangeInterface is a no-op.
@@ -211,16 +219,11 @@
       *test_non_persistent_cookie, net::CookieAccessResult(),
       net::CookieChangeCause::OVERWRITE));
 
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-
-  EXPECT_EQ(2u, GetReturnedRecords().size());
-  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+  records = GetAllAccessRecords();
+  EXPECT_EQ(2u, records.size());
+  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin, records);
   CheckContainsCookieRecord(test_non_persistent_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+                            records);
 
   // Check that a repeated access correctly updates associated timestamp.
   base::Time repeat_cookie_access_time =
@@ -230,17 +233,11 @@
   service()->RecordCookieAccess({*test_cookie, *test_non_persistent_cookie},
                                 kTopFrameOrigin);
 
-  ClearReturnedRecords();
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-
-  EXPECT_EQ(2u, GetReturnedRecords().size());
-  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+  records = GetAllAccessRecords();
+  EXPECT_EQ(2u, records.size());
+  CheckContainsCookieRecord(test_cookie.get(), kTopFrameOrigin, records);
   CheckContainsCookieRecord(test_non_persistent_cookie.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+                            records);
 
   // Inform the service the cookies have been deleted and check they are no
   // longer returned.
@@ -250,13 +247,8 @@
   service()->OnCookieChange(net::CookieChangeInfo(
       *test_non_persistent_cookie, net::CookieAccessResult(),
       net::CookieChangeCause::EXPLICIT));
-  ClearReturnedRecords();
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-
-  EXPECT_EQ(0u, GetReturnedRecords().size());
+  records = GetAllAccessRecords();
+  EXPECT_EQ(0u, records.size());
 }
 
 TEST_F(AccessContextAuditServiceTest, ExpiredCookies) {
@@ -269,11 +261,7 @@
   service()->RecordCookieAccess({*test_cookie_expired},
                                 url::Origin::Create(kTestURL));
 
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(0u, GetReturnedRecords().size());
+  EXPECT_EQ(0u, GetAllAccessRecords().size());
 }
 
 TEST_F(AccessContextAuditServiceTest, HistoryDeletion) {
@@ -305,11 +293,7 @@
                                     kNoRemainingHistoryEntriesOrigin);
 
   // Ensure all records have been initially recorded.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(4u, GetReturnedRecords().size());
+  EXPECT_EQ(4u, GetAllAccessRecords().size());
 
   // Add history entries for all three URLs, then remove history entries for
   // URL1 and URL3. This will fire a history deletion event where the shared
@@ -331,16 +315,12 @@
 
   // Confirm that the records for the origin of URL3 have been removed, but the
   // records for the shared origin of URL1 & URL2 remain.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(2u, GetReturnedRecords().size());
+  auto records = GetAllAccessRecords();
+  EXPECT_EQ(2u, records.size());
   CheckContainsCookieRecord(test_cookie.get(), kHistoryEntriesRemainingOrigin,
-                            GetReturnedRecords());
+                            records);
   CheckContainsStorageAPIRecord(kTestStorageOrigin, kTestStorageType,
-                                kHistoryEntriesRemainingOrigin,
-                                GetReturnedRecords());
+                                kHistoryEntriesRemainingOrigin, records);
 }
 
 TEST_F(AccessContextAuditServiceTest, AllHistoryDeletion) {
@@ -376,11 +356,7 @@
       kNoHistoryEntryOrigin);
 
   // Check access has been initially recorded.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(4u, GetReturnedRecords().size());
+  EXPECT_EQ(4u, GetAllAccessRecords().size());
 
   // Expire all history and confirm that all records are removed.
   base::RunLoop run_loop;
@@ -390,11 +366,7 @@
       /*user_initiated*/ true, run_loop.QuitClosure(), &task_tracker);
   run_loop.Run();
 
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(0u, GetReturnedRecords().size());
+  EXPECT_EQ(0u, GetAllAccessRecords().size());
 }
 
 TEST_F(AccessContextAuditServiceTest, TimeRangeHistoryDeletion) {
@@ -457,11 +429,7 @@
   service()->RecordStorageAPIAccess(kOrigin2, kTestStorageType1, kOrigin2);
 
   // Ensure all records have been initially recorded.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(6u, GetReturnedRecords().size());
+  EXPECT_EQ(6u, GetAllAccessRecords().size());
 
   // Expire history in target time range.
   base::RunLoop run_loop;
@@ -473,15 +441,11 @@
   run_loop.Run();
 
   // Ensure records have been removed as expected.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(2u, GetReturnedRecords().size());
+  auto records = GetAllAccessRecords();
+  EXPECT_EQ(2u, records.size());
   CheckContainsCookieRecord(cookie_accessed_outside_range.get(), kOrigin1,
-                            GetReturnedRecords());
-  CheckContainsStorageAPIRecord(kOrigin1, kTestStorageType2, kOrigin1,
-                                GetReturnedRecords());
+                            records);
+  CheckContainsStorageAPIRecord(kOrigin1, kTestStorageType2, kOrigin1, records);
 }
 
 TEST_F(AccessContextAuditServiceTest, SessionOnlyRecords) {
@@ -526,11 +490,7 @@
       kTopFrameOrigin);
 
   // Ensure all records have been initially recorded.
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-  EXPECT_EQ(5u, GetReturnedRecords().size());
+  EXPECT_EQ(5u, GetAllAccessRecords().size());
 
   // Apply Session Only exception.
   HostContentSettingsMapFactory::GetForProfile(profile())
@@ -543,18 +503,12 @@
   // correctly removed.
   service()->ClearSessionOnlyRecords();
 
-  ClearReturnedRecords();
-  service()->GetAllAccessRecords(
-      base::BindOnce(&AccessContextAuditServiceTest::AccessRecordCallback,
-                     base::Unretained(this)));
-  browser_task_environment_.RunUntilIdle();
-
-  ASSERT_EQ(3u, GetReturnedRecords().size());
+  auto records = GetAllAccessRecords();
+  ASSERT_EQ(3u, records.size());
   CheckContainsCookieRecord(test_cookie_persistent.get(), kTopFrameOrigin,
-                            GetReturnedRecords());
+                            records);
   CheckContainsCookieRecord(test_cookie_session_only_explicit.get(),
-                            kTopFrameOrigin, GetReturnedRecords());
+                            kTopFrameOrigin, records);
   CheckContainsStorageAPIRecord(url::Origin::Create(GURL(kTestPersistentURL)),
-                                kTestStorageType, kTopFrameOrigin,
-                                GetReturnedRecords());
+                                kTestStorageType, kTopFrameOrigin, records);
 }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index fdfefcd..b399364 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -2800,7 +2800,6 @@
   deps = [
     ":chromeos",
     "//base",
-    "//dbus",
   ]
 }
 
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc
index 9b47ba8..cbfc90f 100644
--- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
 #include "components/arc/arc_prefs.h"
 #include "components/arc/arc_service_manager.h"
@@ -34,18 +33,14 @@
   ArcBootPhaseMonitorBridgeTest()
       : scoped_user_manager_(
             std::make_unique<chromeos::FakeChromeUserManager>()),
+        arc_service_manager_(std::make_unique<ArcServiceManager>()),
+        arc_session_manager_(
+            CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>(
+                base::BindRepeating(FakeArcSession::Create)))),
+        testing_profile_(std::make_unique<TestingProfile>()),
         record_uma_counter_(0) {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     chromeos::SessionManagerClient::InitializeFakeInMemory();
 
-    arc_service_manager_ = std::make_unique<ArcServiceManager>();
-    arc_session_manager_ = CreateTestArcSessionManager(
-      std::make_unique<ArcSessionRunner>(
-      base::BindRepeating(FakeArcSession::Create)));
-    testing_profile_ = std::make_unique<TestingProfile>();
-
     SetArcAvailableCommandLineForTesting(
         base::CommandLine::ForCurrentProcess());
 
@@ -63,11 +58,7 @@
 
   ~ArcBootPhaseMonitorBridgeTest() override {
     boot_phase_monitor_bridge_->Shutdown();
-    testing_profile_.reset();
-    arc_session_manager_.reset();
-    arc_service_manager_.reset();
     chromeos::SessionManagerClient::Shutdown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
  protected:
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc
index afc6ebb..bb9d31e1 100644
--- a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc
+++ b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc
@@ -10,10 +10,8 @@
 #include "base/values.h"
 #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
-#include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_prefs.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/arc_util.h"
@@ -29,20 +27,16 @@
  public:
   ArcBootPhaseThrottleObserverTest()
       : scoped_user_manager_(
-            std::make_unique<chromeos::FakeChromeUserManager>()) {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
-    arc_session_manager_ =
-        CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>(
-            base::BindRepeating(FakeArcSession::Create)));
-    testing_profile_ = std::make_unique<TestingProfile>();
-
+            std::make_unique<chromeos::FakeChromeUserManager>()),
+        arc_session_manager_(
+            std::make_unique<ArcSessionRunner>(
+                base::Bind(FakeArcSession::Create)),
+            std::make_unique<AdbSideloadingAvailabilityDelegateImpl>()) {
     // Setup and login profile
     SetArcAvailableCommandLineForTesting(
         base::CommandLine::ForCurrentProcess());
-    const AccountId account_id(AccountId::FromUserEmailGaiaId(
-        testing_profile_->GetProfileUserName(), ""));
+    const AccountId account_id(
+        AccountId::FromUserEmailGaiaId(profile()->GetProfileUserName(), ""));
     auto* user_manager = static_cast<chromeos::FakeChromeUserManager*>(
         user_manager::UserManager::Get());
     user_manager->AddUser(account_id);
@@ -51,38 +45,32 @@
     // By default, ARC is not started for opt-in.
     arc_session_manager()->set_directly_started_for_testing(true);
 
-    ArcBootPhaseMonitorBridge::GetForBrowserContextForTesting(
-        testing_profile_.get());
+    ArcBootPhaseMonitorBridge::GetForBrowserContextForTesting(profile());
     observer()->StartObserving(
-        testing_profile_.get(),
+        profile(),
         ArcBootPhaseThrottleObserver::ObserverStateChangedCallback());
   }
 
-  void TearDown() override {
-    observer()->StopObserving();
-    testing_profile_.reset();
-    arc_session_manager_.reset();
-    chromeos::DBusThreadManager::Shutdown();
-  }
+  void TearDown() override { observer()->StopObserving(); }
 
  protected:
   sync_preferences::TestingPrefServiceSyncable* GetPrefs() {
-    return testing_profile_->GetTestingPrefService();
+    return testing_profile_.GetTestingPrefService();
   }
 
   ArcBootPhaseThrottleObserver* observer() { return &observer_; }
 
-  ArcSessionManager* arc_session_manager() {
-    return arc_session_manager_.get();
-  }
+  TestingProfile* profile() { return &testing_profile_; }
+
+  ArcSessionManager* arc_session_manager() { return &arc_session_manager_; }
 
  private:
   content::BrowserTaskEnvironment task_environment_;
   user_manager::ScopedUserManager scoped_user_manager_;
   ArcServiceManager arc_service_manager_;
-  std::unique_ptr<ArcSessionManager> arc_session_manager_;
+  ArcSessionManager arc_session_manager_;
   ArcBootPhaseThrottleObserver observer_;
-  std::unique_ptr<TestingProfile> testing_profile_;
+  TestingProfile testing_profile_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcBootPhaseThrottleObserverTest);
 };
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc
index 1d97a3e..a0029e2 100644
--- a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc
+++ b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/throttle_observer.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_prefs.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/arc_util.h"
@@ -30,17 +29,13 @@
 class ArcInstanceThrottleTest : public testing::Test {
  public:
   ArcInstanceThrottleTest()
-      : disable_cpu_restriction_counter_(0),
+      : arc_service_manager_(std::make_unique<ArcServiceManager>()),
+        arc_session_manager_(
+            CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>(
+                base::BindRepeating(FakeArcSession::Create)))),
+        testing_profile_(std::make_unique<TestingProfile>()),
+        disable_cpu_restriction_counter_(0),
         enable_cpu_restriction_counter_(0) {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
-    arc_service_manager_ = std::make_unique<ArcServiceManager>();
-    arc_session_manager_ =
-        CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>(
-            base::BindRepeating(FakeArcSession::Create)));
-    testing_profile_ = std::make_unique<TestingProfile>();
-
     SetArcAvailableCommandLineForTesting(
         base::CommandLine::ForCurrentProcess());
 
@@ -53,13 +48,6 @@
         std::make_unique<TestDelegateImpl>(this));
   }
 
-  ~ArcInstanceThrottleTest() override {
-    testing_profile_.reset();
-    arc_session_manager_.reset();
-    arc_service_manager_.reset();
-    chromeos::DBusThreadManager::Shutdown();
-  }
-
  protected:
   sync_preferences::TestingPrefServiceSyncable* GetPrefs() {
     return testing_profile_->GetTestingPrefService();
diff --git a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
index 7353c38..b92c4cf 100644
--- a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_prefs.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/arc_util.h"
@@ -43,9 +42,6 @@
             std::make_unique<chromeos::FakeChromeUserManager>()) {}
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     SetArcAvailableCommandLineForTesting(
         base::CommandLine::ForCurrentProcess());
     ArcSessionManager::SetUiEnabledForTesting(false);
@@ -80,7 +76,6 @@
     BrowserWithTestWindowTest::TearDown();
     arc_session_manager_.reset();
     arc_service_manager_.reset();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   chromeos::FakeChromeUserManager* GetFakeUserManager() {
diff --git a/chrome/browser/chromeos/arc/session/arc_play_store_enabled_preference_handler_unittest.cc b/chrome/browser/chromeos/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
index f12090c..1d48d9e 100644
--- a/chrome/browser/chromeos/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
+++ b/chrome/browser/chromeos/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/dbus/upstart/upstart_client.h"
 #include "components/arc/arc_prefs.h"
@@ -55,9 +54,6 @@
             std::make_unique<chromeos::FakeChromeUserManager>()) {}
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     chromeos::SessionManagerClient::InitializeFakeInMemory();
     chromeos::UpstartClient::InitializeFake();
 
@@ -99,7 +95,6 @@
     profile_.reset();
     chromeos::UpstartClient::Shutdown();
     chromeos::SessionManagerClient::Shutdown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   TestingProfile* profile() const { return profile_.get(); }
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
index 30f0597..1c777ab 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -462,15 +462,11 @@
   if (chromeos::SessionManagerClient::Get())
     chromeos::SessionManagerClient::Get()->AddObserver(this);
   ResetStabilityMetrics();
-  chromeos::DBusThreadManager::Get()->GetConciergeClient()->AddVmObserver(this);
 }
 
 ArcSessionManager::~ArcSessionManager() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  chromeos::DBusThreadManager::Get()->GetConciergeClient()->RemoveVmObserver(
-      this);
-
   if (chromeos::SessionManagerClient::Get())
     chromeos::SessionManagerClient::Get()->RemoveObserver(this);
 
@@ -967,25 +963,6 @@
   return playstore_launcher_.get();
 }
 
-void ArcSessionManager::OnVmStarted(
-    const vm_tools::concierge::VmStartedSignal& vm_signal) {
-  // When an ARCVM starts, store the vm info.
-  if (vm_signal.name() == kArcVmName)
-    vm_info_ = vm_signal.vm_info();
-}
-
-void ArcSessionManager::OnVmStopped(
-    const vm_tools::concierge::VmStoppedSignal& vm_signal) {
-  // When an ARCVM stops, clear the stored vm info.
-  if (vm_signal.name() == kArcVmName)
-    vm_info_ = base::nullopt;
-}
-
-const base::Optional<vm_tools::concierge::VmInfo>&
-ArcSessionManager::GetVmInfo() const {
-  return vm_info_;
-}
-
 bool ArcSessionManager::RequestEnableImpl() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(profile_);
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.h b/chrome/browser/chromeos/arc/session/arc_session_manager.h
index ff6fbf9..1e3afe52 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.h
@@ -20,7 +20,6 @@
 #include "chrome/browser/chromeos/arc/session/adb_sideloading_availability_delegate_impl.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.h"
 #include "chrome/browser/chromeos/policy/android_management_client.h"
-#include "chromeos/dbus/concierge_client.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "components/arc/mojom/auth.mojom.h"
 #include "components/arc/session/arc_session_runner.h"
@@ -48,8 +47,7 @@
 // This class is responsible for handing stages of ARC life-cycle.
 class ArcSessionManager : public ArcSessionRunner::Observer,
                           public ArcSupportHost::ErrorDelegate,
-                          public chromeos::SessionManagerClient::Observer,
-                          public chromeos::ConciergeClient::VmObserver {
+                          public chromeos::SessionManagerClient::Observer {
  public:
   // Represents each State of ARC session.
   // NOT_INITIALIZED: represents the state that the Profile is not yet ready
@@ -284,16 +282,6 @@
     property_files_dest_dir_ = property_files_dest_dir;
   }
 
-  // chromeos::ConciergeClient::VmObserver overrides.
-  void OnVmStarted(
-      const vm_tools::concierge::VmStartedSignal& vm_signal) override;
-  void OnVmStopped(
-      const vm_tools::concierge::VmStoppedSignal& vm_signal) override;
-
-  // Getter for |vm_info_|.
-  // If ARCVM is not running, return base::nullopt.
-  const base::Optional<vm_tools::concierge::VmInfo>& GetVmInfo() const;
-
  private:
   // Reports statuses of OptIn flow to UMA.
   class ScopedOptInFlowTracker;
@@ -429,8 +417,6 @@
   base::FilePath property_files_source_dir_;
   base::FilePath property_files_dest_dir_;
 
-  base::Optional<vm_tools::concierge::VmInfo> vm_info_;
-
   // Must be the last member.
   base::WeakPtrFactory<ArcSessionManager> weak_ptr_factory_{this};
 
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
index e5c2354..6d9d19c 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
@@ -46,7 +46,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/dbus/upstart/upstart_client.h"
@@ -128,9 +127,6 @@
   ArcSessionManagerInLoginScreenTest()
       : user_manager_enabler_(
             std::make_unique<chromeos::FakeChromeUserManager>()) {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     chromeos::SessionManagerClient::InitializeFakeInMemory();
 
     ArcSessionManager::SetUiEnabledForTesting(false);
@@ -147,7 +143,6 @@
     arc_session_manager_.reset();
     arc_service_manager_.reset();
     chromeos::SessionManagerClient::Shutdown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
  protected:
@@ -207,7 +202,6 @@
   ~ArcSessionManagerTestBase() override = default;
 
   void SetUp() override {
-    chromeos::DBusThreadManager::Initialize();
     chromeos::PowerManagerClient::InitializeFake();
     chromeos::SessionManagerClient::InitializeFakeInMemory();
     chromeos::UpstartClient::InitializeFake();
@@ -241,7 +235,6 @@
     chromeos::UpstartClient::Shutdown();
     chromeos::SessionManagerClient::Shutdown();
     chromeos::PowerManagerClient::Shutdown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   chromeos::FakeChromeUserManager* GetFakeUserManager() const {
@@ -988,60 +981,6 @@
   arc_session_manager()->Shutdown();
 }
 
-// Tests that |vm_info| is initialized with base::nullopt.
-TEST_F(ArcSessionManagerTest, GetVmInfo_InitialValue) {
-  const auto& vm_info = arc_session_manager()->GetVmInfo();
-  EXPECT_EQ(base::nullopt, vm_info);
-}
-
-// Tests that |vm_info| is updated with that from VmStartedSignal.
-TEST_F(ArcSessionManagerTest, GetVmInfo_WithVmStarted) {
-  vm_tools::concierge::VmStartedSignal vm_signal;
-  vm_signal.set_name(kArcVmName);
-  vm_signal.mutable_vm_info()->set_seneschal_server_handle(1000UL);
-  arc_session_manager()->OnVmStarted(vm_signal);
-
-  const auto& vm_info = arc_session_manager()->GetVmInfo();
-  ASSERT_NE(base::nullopt, vm_info);
-  EXPECT_EQ(1000UL, vm_info->seneschal_server_handle());
-}
-
-// Tests that |vm_info| remains as base::nullopt after VM stops.
-TEST_F(ArcSessionManagerTest, GetVmInfo_WithVmStopped) {
-  vm_tools::concierge::VmStoppedSignal vm_signal;
-  vm_signal.set_name(kArcVmName);
-  arc_session_manager()->OnVmStopped(vm_signal);
-
-  const auto& vm_info = arc_session_manager()->GetVmInfo();
-  EXPECT_EQ(base::nullopt, vm_info);
-}
-
-// Tests that |vm_info| is reset to base::nullopt after VM starts and stops.
-TEST_F(ArcSessionManagerTest, GetVmInfo_WithVmStarted_ThenStopped) {
-  vm_tools::concierge::VmStartedSignal start_signal;
-  start_signal.set_name(kArcVmName);
-  start_signal.mutable_vm_info()->set_seneschal_server_handle(1000UL);
-  arc_session_manager()->OnVmStarted(start_signal);
-
-  vm_tools::concierge::VmStoppedSignal stop_signal;
-  stop_signal.set_name(kArcVmName);
-  arc_session_manager()->OnVmStopped(stop_signal);
-
-  const auto& vm_info = arc_session_manager()->GetVmInfo();
-  EXPECT_EQ(base::nullopt, vm_info);
-}
-
-// Tests that |vm_info| is not updated with non-ARCVM VmStartedSignal.
-TEST_F(ArcSessionManagerTest, GetVmInfo_WithNonVmStarted) {
-  vm_tools::concierge::VmStartedSignal non_vm_signal;
-  non_vm_signal.set_name("non-ARCVM");
-  non_vm_signal.mutable_vm_info()->set_seneschal_server_handle(1000UL);
-  arc_session_manager()->OnVmStarted(non_vm_signal);
-
-  const auto& vm_info = arc_session_manager()->GetVmInfo();
-  EXPECT_EQ(base::nullopt, vm_info);
-}
-
 class ArcSessionManagerArcAlwaysStartTest : public ArcSessionManagerTest {
  public:
   ArcSessionManagerArcAlwaysStartTest() = default;
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc
index de75853..184e7bb 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc
@@ -58,6 +58,10 @@
       if (user_manager::UserManager::Get()->IsUserLoggedIn())
         return user_manager::UserManager::Get()->GetActiveUser()->IsChild();
       return IsDeviceOwnedByChild();
+    case SupervisedAction::kOnlineLogin:
+      if (!features::IsParentAccessCodeForOnlineLoginEnabled())
+        return false;
+      return IsDeviceOwnedByChild();
   }
 }
 
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h
index 50fe0c6..476165e 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h
@@ -43,7 +43,9 @@
     // the settings page (in-session) and the tray bubble (out-session).
     kUpdateClock,
     // Change timezone from the settings page.
-    kUpdateTimezone
+    kUpdateTimezone,
+    // Online login with Gaia.
+    kOnlineLogin
   };
 
   // Registers preferences.
diff --git a/chrome/browser/chromeos/guest_os/guest_os_share_path.cc b/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
index f0aafef..5358124 100644
--- a/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
+++ b/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
@@ -9,7 +9,6 @@
 #include "base/files/file_util.h"
 #include "base/optional.h"
 #include "base/task/thread_pool.h"
-#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
@@ -24,7 +23,6 @@
 #include "chromeos/dbus/concierge/concierge_service.pb.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/seneschal_client.h"
-#include "components/arc/arc_util.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -331,15 +329,6 @@
     request.set_handle(
         plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)
             ->seneschal_server_handle());
-  } else if (vm_name == arc::kArcVmName) {
-    const auto& vm_info = arc::ArcSessionManager::Get()->GetVmInfo();
-    if (!vm_info) {
-      LOG(WARNING) << "ARCVM not running, cannot share paths";
-      std::move(callback).Run(base::FilePath(), false,
-                              "ARCVM not running, cannot share paths");
-      return;
-    }
-    request.set_handle(vm_info->seneschal_server_handle());
   } else {
     // Restart VM if not currently running.
     auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
@@ -377,14 +366,6 @@
     request.set_handle(
         plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)
             ->seneschal_server_handle());
-  } else if (vm_name == arc::kArcVmName) {
-    const auto& vm_info = arc::ArcSessionManager::Get()->GetVmInfo();
-    if (!vm_info) {
-      LOG(WARNING) << "ARCVM not running, cannot unshare paths";
-      std::move(callback).Run(true, "ARCVM not running, cannot unshare paths");
-      return;
-    }
-    request.set_handle(vm_info->seneschal_server_handle());
   } else {
     auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
     base::Optional<crostini::VmInfo> vm_info =
diff --git a/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
index 0e15c17..25f276b 100644
--- a/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
+++ b/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
@@ -9,8 +9,6 @@
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
-#include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
@@ -33,9 +31,6 @@
 #include "chromeos/dbus/seneschal/seneschal_service.pb.h"
 #include "chromeos/disks/disk_mount_manager.h"
 #include "components/account_id/account_id.h"
-#include "components/arc/arc_util.h"
-#include "components/arc/session/arc_session_runner.h"
-#include "components/arc/test/fake_arc_session.h"
 #include "components/drive/drive_pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
@@ -266,15 +261,9 @@
 
     g_browser_process->platform_part()
         ->InitializeSchedulerConfigurationManager();
-
-    // Create ArcSessionManager for ARCVM testing.
-    arc_session_manager_ = arc::CreateTestArcSessionManager(
-        std::make_unique<arc::ArcSessionRunner>(
-            base::BindRepeating(arc::FakeArcSession::Create)));
   }
 
   void TearDown() override {
-    arc_session_manager_.reset();
     g_browser_process->platform_part()->ShutdownSchedulerConfigurationManager();
     // Shutdown GuestOsSharePath to schedule FilePathWatchers to be destroyed,
     // then run thread bundle to ensure they are.
@@ -310,7 +299,6 @@
   base::test::ScopedFeatureList features_;
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
   AccountId account_id_;
-  std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
 
  private:
   std::unique_ptr<ScopedTestingLocalState> local_state_;
@@ -368,28 +356,6 @@
   run_loop()->Run();
 }
 
-// Tests that ARCVM can share path.
-TEST_F(GuestOsSharePathTest, SuccessArcvm) {
-  SetUpVolume();
-
-  // Set up VmInfo in |arc_session_manager_| to simulate a running ARCVM.
-  vm_tools::concierge::VmStartedSignal start_signal;
-  start_signal.set_name(arc::kArcVmName);
-  start_signal.mutable_vm_info()->set_seneschal_server_handle(1000UL);
-  arc_session_manager_->OnVmStarted(start_signal);
-
-  guest_os_share_path_->SharePath(
-      arc::kArcVmName, drivefs_.Append("root").Append("ArcvmTest"), PERSIST_NO,
-      base::BindOnce(&GuestOsSharePathTest::SharePathCallback,
-                     base::Unretained(this), arc::kArcVmName, Persist::NO,
-                     SeneschalClientCalled::YES,
-                     &vm_tools::seneschal::SharePathRequest::DRIVEFS_MY_DRIVE,
-                     "ArcvmTest", Success::YES, ""));
-  // Also validate the seneschal server handle.
-  EXPECT_EQ(1000UL, fake_seneschal_client_->last_share_path_request().handle());
-  run_loop()->Run();
-}
-
 TEST_F(GuestOsSharePathTest, SuccessDriveFsMyDrive) {
   SetUpVolume();
   guest_os_share_path_->SharePath(
@@ -790,30 +756,6 @@
   run_loop()->Run();
 }
 
-// Tests that it cannot unshare path when ARCVM is not running.
-TEST_F(GuestOsSharePathTest, UnsharePathArcvmNotRunning) {
-  SetUpVolume();
-  DictionaryPrefUpdate update(profile()->GetPrefs(),
-                              prefs::kGuestOSPathsSharedToVms);
-  base::DictionaryValue* shared_paths = update.Get();
-  base::Value vms(base::Value::Type::LIST);
-  vms.Append(base::Value(arc::kArcVmName));
-  shared_paths->SetKey(shared_path_.value(), std::move(vms));
-
-  // Remove VmInfo from |arc_session_manager_| to simulate a stopped ARCVM.
-  vm_tools::concierge::VmStoppedSignal stop_signal;
-  stop_signal.set_name(arc::kArcVmName);
-  arc_session_manager_->OnVmStopped(stop_signal);
-
-  guest_os_share_path_->UnsharePath(
-      arc::kArcVmName, shared_path_, true,
-      base::BindOnce(&GuestOsSharePathTest::UnsharePathCallback,
-                     base::Unretained(this), shared_path_, Persist::NO,
-                     SeneschalClientCalled::NO, "", Success::YES,
-                     "ARCVM not running, cannot unshare paths"));
-  run_loop()->Run();
-}
-
 TEST_F(GuestOsSharePathTest, UnsharePathInvalidPath) {
   SetUpVolume();
   base::FilePath invalid("invalid/path");
diff --git a/chrome/browser/chromeos/lock_screen_apps/app_manager_impl_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/app_manager_impl_unittest.cc
index 4ab9322..54fb42a8 100644
--- a/chrome/browser/chromeos/lock_screen_apps/app_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/lock_screen_apps/app_manager_impl_unittest.cc
@@ -31,7 +31,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/session/arc_session.h"
 #include "content/public/test/browser_task_environment.h"
@@ -143,9 +142,6 @@
   ~LockScreenAppManagerImplTest() override = default;
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     // Initialize command line so chromeos::NoteTakingHelper thinks note taking
     // on lock screen is enabled.
     command_line_ = std::make_unique<base::test::ScopedCommandLine>();
@@ -181,11 +177,8 @@
     // destruction.
     app_manager_.reset();
 
-    lock_screen_profile_creator_.reset();
     chromeos::NoteTakingHelper::Shutdown();
-    arc_session_manager_.reset();
     extensions::ExtensionSystem::Get(profile())->Shutdown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   void InitExtensionSystem(Profile* profile) {
diff --git a/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
index 40434dbd6..eeab6c6 100644
--- a/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
+++ b/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
@@ -30,7 +30,6 @@
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/session/arc_session.h"
 #include "components/crx_file/id_util.h"
@@ -215,9 +214,6 @@
   ~LockScreenProfileCreatorImplTest() override {}
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
         extensions::switches::kAllowlistedExtensionID,
         crx_file::id_util::GenerateId("test_app"));
@@ -243,11 +239,8 @@
   }
 
   void TearDown() override {
-    lock_screen_profile_creator_.reset();
-    arc_session_manager_.reset();
     chromeos::NoteTakingHelper::Shutdown();
     TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr);
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   UnittestProfileManager* profile_manager() { return profile_manager_; }
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc
index 802ed840..3d995c8 100644
--- a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc
+++ b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc
@@ -38,7 +38,6 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power_manager/suspend.pb.h"
 #include "components/arc/arc_service_manager.h"
@@ -384,10 +383,6 @@
   ~LockScreenAppStateTest() override = default;
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
-
     command_line_ = std::make_unique<base::test::ScopedCommandLine>();
     command_line_->GetProcessCommandLine()->InitFromArgv({""});
     SetUpCommandLine(command_line_->GetProcessCommandLine());
@@ -438,19 +433,18 @@
   }
 
   void TearDown() override {
+    extensions::ExtensionSystem::Get(profile())->Shutdown();
+
     state_controller_->RemoveObserver(&observer_);
     state_controller_->Shutdown();
-    focus_cycler_delegate_.reset();
+    chromeos::NoteTakingHelper::Shutdown();
+
+    session_manager_.reset();
     app_manager_ = nullptr;
     lock_screen_profile_creator_ = nullptr;
-    extensions::ExtensionSystem::Get(profile())->Shutdown();
-    chromeos::NoteTakingHelper::Shutdown();
-    arc_session_manager_.reset();
-    session_manager_.reset();
     app_window_.reset();
     BrowserWithTestWindowTest::TearDown();
-    command_line_.reset();
-    chromeos::DBusThreadManager::Shutdown();
+    focus_cycler_delegate_.reset();
   }
 
   TestingProfile* CreateProfile() override {
diff --git a/chrome/browser/chromeos/login/eula_browsertest.cc b/chrome/browser/chromeos/login/eula_browsertest.cc
index 1d8ab896..cdb550b 100644
--- a/chrome/browser/chromeos/login/eula_browsertest.cc
+++ b/chrome/browser/chromeos/login/eula_browsertest.cc
@@ -75,14 +75,13 @@
 const test::UIPath kEulaTPMPassword = {"oobe-eula-md", "eula-password"};
 const test::UIPath kUsageStats = {"oobe-eula-md", "usageStats"};
 const test::UIPath kAdditionalTermsLink = {"oobe-eula-md", "additionalTerms"};
-const test::UIPath kAdditionalTermsDialog = {"oobe-eula-md", "additional-tos"};
+const test::UIPath kAdditionalTermsDialog = {"oobe-eula-md", "additionalToS"};
 const test::UIPath kAdditionalTermsClose = {"oobe-eula-md",
                                             "close-additional-tos"};
-const test::UIPath kInstallationSettingsLink = {"oobe-eula-md",
-                                                "installationSettings"};
-const test::UIPath kInstallationSettingsDialog = {"oobe-eula-md",
-                                                  "installationSettingsDialog"};
-const test::UIPath kLearnMoreLink = {"oobe-eula-md", "learn-more"};
+const test::UIPath kSecuritySettingsLink = {"oobe-eula-md", "securitySettings"};
+const test::UIPath kSecuritySettingsDialog = {"oobe-eula-md",
+                                              "securitySettingsDialog"};
+const test::UIPath kLearnMoreLink = {"oobe-eula-md", "learnMore"};
 
 // Helper class to wait until the WebCotnents finishes loading.
 class WebContentsLoadFinishedWaiter : public content::WebContentsObserver {
@@ -320,8 +319,8 @@
   base::HistogramTester histogram_tester;
   ShowEulaScreen();
 
-  test::OobeJS().TapLinkOnPath(kInstallationSettingsLink);
-  test::OobeJS().ExpectVisiblePath(kInstallationSettingsDialog);
+  test::OobeJS().TapLinkOnPath(kSecuritySettingsLink);
+  test::OobeJS().ExpectVisiblePath(kSecuritySettingsDialog);
 
   test::OobeJS()
       .CreateWaiter(
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
index 00308e7..04d2c9a 100644
--- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
+++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -113,8 +113,7 @@
   if (user && user->GetType() == user_manager::UserType::USER_TYPE_SUPERVISED)
     return false;
 
-  // Enable quick unlock only if the switch is present.
-  return base::FeatureList::IsEnabled(features::kQuickUnlockPin);
+  return true;
 }
 
 // Returns fingerprint location depending on the commandline switch.
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.cc b/chrome/browser/chromeos/login/screens/eula_screen.cc
index 3cac9f1..912b08d 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen.cc
+++ b/chrome/browser/chromeos/login/screens/eula_screen.cc
@@ -149,7 +149,17 @@
     return;
   }
   RecordUserAction(action_id);
-  if (action_id == kUserActionAcceptButtonClicked) {
+  if (action_id == kUserActionShowStatsUsageLearnMore) {
+    ShowStatsUsageLearnMore();
+  } else if (action_id == kUserActionShowAdditionalTos) {
+    ShowAdditionalTosDialog();
+  } else if (action_id == kUserActionShowSecuritySettings) {
+    InitiatePasswordFetch();
+  } else if (action_id == kUserActionSelectStatsUsage) {
+    SetUsageStatsEnabled(true);
+  } else if (action_id == kUserActionUnselectStatsUsage) {
+    SetUsageStatsEnabled(false);
+  } else if (action_id == kUserActionAcceptButtonClicked) {
     exit_callback_.Run(g_usage_statistics_reporting_enabled
                            ? Result::ACCEPTED_WITH_USAGE_STATS_REPORTING
                            : Result::ACCEPTED_WITHOUT_USAGE_STATS_REPORTING);
@@ -172,4 +182,14 @@
     view_->OnPasswordFetched(tpm_password_);
 }
 
+void EulaScreen::ShowStatsUsageLearnMore() {
+  if (view_)
+    view_->ShowStatsUsageLearnMore();
+}
+
+void EulaScreen::ShowAdditionalTosDialog() {
+  if (view_)
+    view_->ShowAdditionalTosDialog();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.h b/chrome/browser/chromeos/login/screens/eula_screen.h
index 449afda..d169d1f 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen.h
+++ b/chrome/browser/chromeos/login/screens/eula_screen.h
@@ -81,6 +81,8 @@
 
   // TpmPasswordFetcherDelegate implementation:
   void OnPasswordFetched(const std::string& tpm_password) override;
+  void ShowStatsUsageLearnMore();
+  void ShowAdditionalTosDialog();
 
   // URL of the OEM EULA page (on disk).
   GURL oem_eula_page_;
diff --git a/chrome/browser/chromeos/login/screens/mock_eula_screen.h b/chrome/browser/chromeos/login/screens/mock_eula_screen.h
index cfc854f..30e9378 100644
--- a/chrome/browser/chromeos/login/screens/mock_eula_screen.h
+++ b/chrome/browser/chromeos/login/screens/mock_eula_screen.h
@@ -36,6 +36,8 @@
   MOCK_METHOD(void, MockBind, (EulaScreen * screen));
   MOCK_METHOD(void, MockUnbind, ());
   MOCK_METHOD(void, OnPasswordFetched, (const std::string& tpm_password));
+  MOCK_METHOD(void, ShowStatsUsageLearnMore, ());
+  MOCK_METHOD(void, ShowAdditionalTosDialog, ());
 
  private:
   EulaScreen* screen_ = nullptr;
diff --git a/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc b/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
index 8693a69..5a0dadf 100644
--- a/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
@@ -37,12 +37,6 @@
   ~LockToSingleUserManagerTest() override = default;
 
   void SetUp() override {
-    // This setter will initialize DBusThreadManager.
-    // This is required before ArcSessionManager's constructor calls
-    // DBusThreadManager::Get().
-    auto dbus_thread_manager_setter =
-        chromeos::DBusThreadManager::GetSetterForTesting();
-
     arc::SetArcAvailableCommandLineForTesting(
         base::CommandLine::ForCurrentProcess());
     chromeos::LoginState::Initialize();
@@ -60,19 +54,20 @@
 
     arc_service_manager_->set_browser_context(profile());
 
+    auto setter = chromeos::DBusThreadManager::GetSetterForTesting();
     fake_concierge_client_ = new chromeos::FakeConciergeClient();
-    dbus_thread_manager_setter->SetConciergeClient(
-        base::WrapUnique(fake_concierge_client_));
+    setter->SetConciergeClient(base::WrapUnique(fake_concierge_client_));
   }
 
   void TearDown() override {
+    lock_to_single_user_manager_.reset();
+
     arc_session_manager_->Shutdown();
-    arc_session_manager_.reset();
     arc_service_manager_->set_browser_context(nullptr);
-    arc_service_manager_.reset();
 
     BrowserWithTestWindowTest::TearDown();
-    lock_to_single_user_manager_.reset();
+    arc_session_manager_.reset();
+    arc_service_manager_.reset();
 
     chromeos::CryptohomeClient::Shutdown();
     chromeos::LoginState::Shutdown();
diff --git a/chrome/browser/chromeos/policy/system_proxy_manager.cc b/chrome/browser/chromeos/policy/system_proxy_manager.cc
index 1fc7c4b..0c9bcf8 100644
--- a/chrome/browser/chromeos/policy/system_proxy_manager.cc
+++ b/chrome/browser/chromeos/policy/system_proxy_manager.cc
@@ -125,8 +125,11 @@
     // daemon and tell it to exit.
     // TODO(crbug.com/1055245,acostinas): Do not send shut-down command if
     // System-proxy is inactive.
-    chromeos::SystemProxyClient::Get()->ShutDownDaemon(base::BindOnce(
-        &SystemProxyManager::OnDaemonShutDown, weak_factory_.GetWeakPtr()));
+    system_proxy::ShutDownRequest request;
+    request.set_traffic_type(system_proxy::TrafficOrigin::ALL);
+    chromeos::SystemProxyClient::Get()->ShutDownProcess(
+        request, base::BindOnce(&SystemProxyManager::OnShutDownProcess,
+                                weak_factory_.GetWeakPtr()));
     system_services_address_.clear();
     return;
   }
@@ -205,10 +208,11 @@
   }
 }
 
-void SystemProxyManager::OnDaemonShutDown(
+void SystemProxyManager::OnShutDownProcess(
     const system_proxy::ShutDownResponse& response) {
   if (response.has_error_message() && !response.error_message().empty()) {
-    NET_LOG(ERROR) << "Failed to shutdown system proxy: " << kSystemProxyService
+    NET_LOG(ERROR) << "Failed to shutdown system proxy process: "
+                   << kSystemProxyService
                    << ", error: " << response.error_message();
   }
 }
diff --git a/chrome/browser/chromeos/policy/system_proxy_manager.h b/chrome/browser/chromeos/policy/system_proxy_manager.h
index efc53ff..8ad54ec 100644
--- a/chrome/browser/chromeos/policy/system_proxy_manager.h
+++ b/chrome/browser/chromeos/policy/system_proxy_manager.h
@@ -62,7 +62,7 @@
  private:
   void OnSetAuthenticationDetails(
       const system_proxy::SetAuthenticationDetailsResponse& response);
-  void OnDaemonShutDown(const system_proxy::ShutDownResponse& response);
+  void OnShutDownProcess(const system_proxy::ShutDownResponse& response);
   void OnClearUserCredentials(
       const system_proxy::ClearUserCredentialsResponse& response);
 
diff --git a/chrome/browser/conversions/OWNERS b/chrome/browser/conversions/OWNERS
new file mode 100644
index 0000000..8b8a4832
--- /dev/null
+++ b/chrome/browser/conversions/OWNERS
@@ -0,0 +1 @@
+file://content/browser/conversions/OWNERS
diff --git a/chrome/browser/conversions/conversions_usecounter_browsertest.cc b/chrome/browser/conversions/conversions_usecounter_browsertest.cc
new file mode 100644
index 0000000..ea82270
--- /dev/null
+++ b/chrome/browser/conversions/conversions_usecounter_browsertest.cc
@@ -0,0 +1,122 @@
+// Copyright 2020 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 "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/default_handlers.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Tests UseCounters recorded for the Conversion Measurement API. This is tested
+// in the Chrome layer, as UseCounter recording is not used with content shell.
+class ConversionsUseCounterBrowsertest : public InProcessBrowserTest {
+ public:
+  ConversionsUseCounterBrowsertest() = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Sets up the blink runtime feature for ConversionMeasurement.
+    command_line->AppendSwitch(
+        switches::kEnableExperimentalWebPlatformFeatures);
+  }
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+    net::test_server::RegisterDefaultHandlers(&server_);
+    server_.ServeFilesFromSourceDirectory("content/test/data");
+    content::SetupCrossSiteRedirector(&server_);
+    ASSERT_TRUE(server_.Start());
+  }
+
+ protected:
+  net::EmbeddedTestServer server_{net::EmbeddedTestServer::TYPE_HTTPS};
+};
+
+IN_PROC_BROWSER_TEST_F(ConversionsUseCounterBrowsertest,
+                       ImpressionClicked_FeatureRecorded) {
+  base::HistogramTester histogram_tester;
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  page_load_metrics::PageLoadMetricsTestWaiter waiter(web_contents);
+  waiter.AddWebFeatureExpectation(blink::mojom::WebFeature::kConversionAPIAll);
+
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(),
+      server_.GetURL("a.test",
+                     "/conversions/page_with_impression_creator.html")));
+
+  // Create an anchor tag with impression attributes which opens a link in a
+  // new.
+  GURL link_url = server_.GetURL(
+      "b.test", "/conversions/page_with_conversion_redirect.html");
+  EXPECT_TRUE(ExecJs(web_contents, content::JsReplace(R"(
+    createImpressionTagWithTarget("link" /* id */,
+                        $1 /* url */,
+                        "1" /* impression data */,
+                        "https://b.test" /* conversion_destination */, "_blank");)",
+                                                      link_url)));
+
+  // Click the impression, and wait for the new window to open. Then switch to
+  // the tab with the impression.
+  content::WebContentsAddedObserver window_observer;
+  EXPECT_TRUE(ExecJs(web_contents, "simulateClick('link');"));
+  content::WebContents* new_contents = window_observer.GetWebContents();
+  WaitForLoadStop(new_contents);
+  browser()->tab_strip_model()->ActivateTabAt(0);
+  waiter.Wait();
+
+  // Navigate to a new page to flush metrics.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank")));
+
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.Features",
+      blink::mojom::WebFeature::kImpressionRegistration, 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.Features", blink::mojom::WebFeature::kConversionAPIAll,
+      1);
+}
+
+IN_PROC_BROWSER_TEST_F(ConversionsUseCounterBrowsertest,
+                       ConversionPing_FeatureRecorded) {
+  base::HistogramTester histogram_tester;
+
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(),
+      server_.GetURL("a.test",
+                     "/conversions/page_with_conversion_redirect.html")));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Register a conversion with the original page as the reporting origin.
+  EXPECT_TRUE(ExecJs(web_contents, "registerConversion(7)"));
+
+  // Wait for the conversion redirect to be intercepted. This is indicated by
+  // window title changing when the img element for the conversion request fires
+  // an onerror event.
+  const base::string16 kConvertTitle = base::ASCIIToUTF16("converted");
+  content::TitleWatcher watcher(web_contents, kConvertTitle);
+  EXPECT_EQ(kConvertTitle, watcher.WaitAndGetTitle());
+
+  // Navigate to a new page to flush metrics.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank")));
+
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.Features",
+      blink::mojom::WebFeature::kConversionRegistration, 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.Features", blink::mojom::WebFeature::kConversionAPIAll,
+      1);
+}
diff --git a/chrome/browser/extensions/active_tab_apitest.cc b/chrome/browser/extensions/active_tab_apitest.cc
index 6990ac3..bbb906e 100644
--- a/chrome/browser/extensions/active_tab_apitest.cc
+++ b/chrome/browser/extensions/active_tab_apitest.cc
@@ -51,7 +51,6 @@
   }
 
  private:
-
   DISALLOW_COPY_AND_ASSIGN(ExtensionActiveTabTest);
 };
 
@@ -251,7 +250,7 @@
     // Sanity check the last committed url on the |file_iframe|.
     content::RenderFrameHost* file_iframe = content::FrameMatchingPredicate(
         browser()->tab_strip_model()->GetActiveWebContents(),
-        base::Bind(&content::FrameMatchesName, "file_iframe"));
+        base::BindRepeating(&content::FrameMatchesName, "file_iframe"));
     bool is_file_url = file_iframe->GetLastCommittedURL() == GURL("file:///");
     EXPECT_EQ(allowed, is_file_url)
         << "Unexpected committed url: "
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index 4d6c9b60..4cb8685 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -30,7 +30,7 @@
 
 namespace {
 
-using CreateMessageFunction = base::Callback<IPC::Message*(bool)>;
+using CreateMessageFunction = base::RepeatingCallback<IPC::Message*(bool)>;
 
 // Creates a new IPC message for updating tab-specific permissions.
 IPC::Message* CreateUpdateMessage(const GURL& visible_url,
@@ -177,8 +177,8 @@
       // We update all extension render views with the new tab permissions, and
       // also the tab itself.
       CreateMessageFunction update_message =
-          base::Bind(&CreateUpdateMessage, navigation_entry->GetURL(),
-                     extension->id(), new_hosts.Clone(), tab_id_);
+          base::BindRepeating(&CreateUpdateMessage, navigation_entry->GetURL(),
+                              extension->id(), new_hosts.Clone(), tab_id_);
       SendMessageToProcesses(
           process_manager->GetRenderFrameHostsForExtension(extension->id()),
           web_contents()->GetMainFrame()->GetProcess(), update_message);
@@ -253,7 +253,7 @@
   }
 
   CreateMessageFunction clear_message =
-      base::Bind(&CreateClearMessage, extension_ids, tab_id_);
+      base::BindRepeating(&CreateClearMessage, extension_ids, tab_id_);
   SendMessageToProcesses(
       frame_hosts, web_contents()->GetMainFrame()->GetProcess(), clear_message);
 
diff --git a/chrome/browser/extensions/activity_log/activity_database.cc b/chrome/browser/extensions/activity_log/activity_database.cc
index 0e87b02..01356b6 100644
--- a/chrome/browser/extensions/activity_log/activity_database.cc
+++ b/chrome/browser/extensions/activity_log/activity_database.cc
@@ -59,9 +59,8 @@
   did_init_ = true;
   DCHECK(GetActivityLogTaskRunner()->RunsTasksInCurrentSequence());
   db_.set_histogram_tag("Activity");
-  db_.set_error_callback(
-      base::Bind(&ActivityDatabase::DatabaseErrorCallback,
-                 base::Unretained(this)));
+  db_.set_error_callback(base::BindRepeating(
+      &ActivityDatabase::DatabaseErrorCallback, base::Unretained(this)));
   db_.set_page_size(4096);
   db_.set_cache_size(32);
 
diff --git a/chrome/browser/extensions/activity_log/counting_policy_unittest.cc b/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
index 62adbd8..72ed45d 100644
--- a/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
@@ -112,7 +112,7 @@
     // Set up a timeout for receiving results; if we haven't received anything
     // when the timeout triggers then assume that the test is broken.
     base::CancelableClosure timeout(
-        base::Bind(&CountingPolicyTest::TimeoutCallback));
+        base::BindRepeating(&CountingPolicyTest::TimeoutCallback));
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
 
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
index 669ffa4..36a60f8 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
@@ -70,8 +70,8 @@
 IN_PROC_BROWSER_TEST_F(ActivityLogApiTest, MAYBE_TriggerEvent) {
   ActivityLog::GetInstance(profile())->SetWatchdogAppActiveForTesting(true);
 
-  embedded_test_server()->RegisterRequestHandler(
-      base::Bind(&ActivityLogApiTest::HandleRequest, base::Unretained(this)));
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &ActivityLogApiTest::HandleRequest, base::Unretained(this)));
   ASSERT_TRUE(StartEmbeddedTestServer());
 
   const Extension* friend_extension = LoadExtensionIncognito(
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_util.cc b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
index 10fe596..085689e 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_util.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
@@ -200,7 +200,8 @@
 CountryEntryList GenerateCountryList(
     const autofill::PersonalDataManager& personal_data) {
   autofill::CountryComboboxModel model;
-  model.SetCountries(personal_data, base::Callback<bool(const std::string&)>(),
+  model.SetCountries(personal_data,
+                     base::RepeatingCallback<bool(const std::string&)>(),
                      g_browser_process->GetApplicationLocale());
   const std::vector<std::unique_ptr<autofill::AutofillCountry>>& countries =
       model.countries();
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
index 61aa3b7..0e44728 100644
--- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc
+++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -408,13 +408,13 @@
     const std::vector<char>& image_data,
     api::clipboard::ImageType type,
     AdditionalDataItemList additional_items,
-    const base::Closure& success_callback,
-    const base::Callback<void(const std::string&)>& error_callback) {
+    base::OnceClosure success_callback,
+    base::OnceCallback<void(const std::string&)> error_callback) {
   if (!clipboard_extension_helper_)
     clipboard_extension_helper_ = std::make_unique<ClipboardExtensionHelper>();
   clipboard_extension_helper_->DecodeAndSaveImageData(
-      image_data, type, std::move(additional_items), success_callback,
-      error_callback);
+      image_data, type, std::move(additional_items),
+      std::move(success_callback), std::move(error_callback));
 }
 #endif
 
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h
index 98d45c9..15fa53b 100644
--- a/chrome/browser/extensions/api/chrome_extensions_api_client.h
+++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -86,8 +86,8 @@
       const std::vector<char>& image_data,
       api::clipboard::ImageType type,
       AdditionalDataItemList additional_items,
-      const base::Closure& success_callback,
-      const base::Callback<void(const std::string&)>& error_callback) override;
+      base::OnceClosure success_callback,
+      base::OnceCallback<void(const std::string&)> error_callback) override;
 #endif
 
   AutomationInternalApiDelegate* GetAutomationInternalApiDelegate() override;
diff --git a/chrome/browser/extensions/clipboard_extension_helper_chromeos.cc b/chrome/browser/extensions/clipboard_extension_helper_chromeos.cc
index 21f05c0..f22f9723 100644
--- a/chrome/browser/extensions/clipboard_extension_helper_chromeos.cc
+++ b/chrome/browser/extensions/clipboard_extension_helper_chromeos.cc
@@ -85,8 +85,8 @@
     const std::vector<char>& data,
     clipboard::ImageType type,
     AdditionalDataItemList additional_items,
-    const base::Closure& success_callback,
-    const base::Callback<void(const std::string&)>& error_callback) {
+    base::OnceClosure success_callback,
+    base::OnceCallback<void(const std::string&)> error_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // If there is a previous image decoding request still running, cancel it
@@ -99,8 +99,8 @@
   // Cache additonal items.
   additonal_items_ = std::move(additional_items);
 
-  image_save_success_callback_ = success_callback;
-  image_save_error_callback_ = error_callback;
+  image_save_success_callback_ = std::move(success_callback);
+  image_save_error_callback_ = std::move(error_callback);
   clipboard_image_data_decoder_->Start(data, type);
 }
 
diff --git a/chrome/browser/extensions/clipboard_extension_helper_chromeos.h b/chrome/browser/extensions/clipboard_extension_helper_chromeos.h
index a8745b8..6c6bf9b 100644
--- a/chrome/browser/extensions/clipboard_extension_helper_chromeos.h
+++ b/chrome/browser/extensions/clipboard_extension_helper_chromeos.h
@@ -28,8 +28,8 @@
       const std::vector<char>& data,
       api::clipboard::ImageType type,
       AdditionalDataItemList additional_items,
-      const base::Closure& success_callback,
-      const base::Callback<void(const std::string&)>& error_callback);
+      base::OnceClosure success_callback,
+      base::OnceCallback<void(const std::string&)> error_callback);
 
  private:
   // A class to decode PNG and JPEG file.
@@ -43,8 +43,8 @@
   void OnImageDecodeCancel();
 
   std::unique_ptr<ClipboardImageDataDecoder> clipboard_image_data_decoder_;
-  base::Closure image_save_success_callback_;
-  base::Callback<void(const std::string&)> image_save_error_callback_;
+  base::OnceClosure image_save_success_callback_;
+  base::OnceCallback<void(const std::string&)> image_save_error_callback_;
   AdditionalDataItemList additonal_items_;
 
   DISALLOW_COPY_AND_ASSIGN(ClipboardExtensionHelper);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 010c5c3..6461c6e 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -384,6 +384,7 @@
     public static final String REPORT_FEED_USER_ACTIONS = "ReportFeedUserActions";
     public static final String REVAMPED_CONTEXT_MENU = "RevampedContextMenu";
     public static final String SAFETY_CHECK_ANDROID = "SafetyCheckAndroid";
+    public static final String SAFE_BROWSING_DELAYED_WARNINGS = "SafeBrowsingDelayedWarnings";
     public static final String SAFE_BROWSING_ENHANCED_PROTECTION_ENABLED =
             "SafeBrowsingEnhancedProtection";
     public static final String SAFE_BROWSING_SECURITY_SECTION_UI =
diff --git a/chrome/browser/installable/installable_task_queue.cc b/chrome/browser/installable/installable_task_queue.cc
index 41c423a..318c01e 100644
--- a/chrome/browser/installable/installable_task_queue.cc
+++ b/chrome/browser/installable/installable_task_queue.cc
@@ -67,18 +67,20 @@
   std::deque<InstallableTask> paused_tasks = std::move(paused_tasks_);
   // Some callbacks might be already invalidated on certain resets, so we must
   // check for that.
+  // Manifest is assumed to be non-null, so we create an empty one here.
+  blink::Manifest manifest;
   for (InstallableTask& task : tasks) {
     if (task.callback) {
       std::move(task.callback)
-          .Run(InstallableData({code}, GURL(), nullptr, GURL(), nullptr, false,
-                               GURL(), nullptr, false, false));
+          .Run(InstallableData({code}, GURL(), &manifest, GURL(), nullptr,
+                               false, GURL(), nullptr, false, false));
     }
   }
   for (InstallableTask& task : paused_tasks) {
     if (task.callback) {
       std::move(task.callback)
-          .Run(InstallableData({code}, GURL(), nullptr, GURL(), nullptr, false,
-                               GURL(), nullptr, false, false));
+          .Run(InstallableData({code}, GURL(), &manifest, GURL(), nullptr,
+                               false, GURL(), nullptr, false, false));
     }
   }
 }
diff --git a/chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl_unittest.cc b/chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl_unittest.cc
index 77a3580..da62a2d 100644
--- a/chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl_unittest.cc
+++ b/chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl_unittest.cc
@@ -176,14 +176,14 @@
       case UpdateDeviceRequestResult::kSuccess:
         std::move(client->update_device_requests()[0].callback)
             .Run(TestResponse());
-        return;
+        break;
       case UpdateDeviceRequestResult::kHttpFailure:
         std::move(client->update_device_requests()[0].error_callback)
             .Run(NearbyShareRequestError::kBadRequest);
-        return;
+        break;
       case UpdateDeviceRequestResult::kTimeout:
         FastForward(kTestTimeout);
-        return;
+        break;
     }
     EXPECT_EQ(num_responses + 1, responses_.size());
 
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc
new file mode 100644
index 0000000..79d0ebd
--- /dev/null
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc
@@ -0,0 +1,42 @@
+// Copyright 2020 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/password_manager/android/all_passwords_bottom_sheet_controller.h"
+
+#include "chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.h"
+#include "components/password_manager/core/browser/password_manager_driver.h"
+#include "components/password_manager/core/browser/password_store.h"
+
+AllPasswordsBottomSheetController::AllPasswordsBottomSheetController(
+    password_manager::PasswordManagerDriver* driver,
+    password_manager::PasswordStore* store)
+    : driver_(driver), store_(store) {
+  DCHECK(driver_);
+  DCHECK(store_);
+}
+
+AllPasswordsBottomSheetController::~AllPasswordsBottomSheetController() =
+    default;
+
+void AllPasswordsBottomSheetController::Show() {
+  store_->GetAllLoginsWithAffiliationAndBrandingInformation(this);
+  view_->Show();
+  delete view_;
+}
+
+AllPasswordsBottomSheetController* AllPasswordsBottomSheetController::Create(
+    password_manager::PasswordManagerDriver* driver,
+    password_manager::PasswordStore* store) {
+  std::unique_ptr<AllPasswordsBottomSheetController> controller =
+      std::make_unique<AllPasswordsBottomSheetController>(driver, store);
+  AllPasswordsBottomSheetController* raw_controller = controller.get();
+  raw_controller->view_ =
+      AllPasswordsBottomSheetView::Create(std::move(controller));
+  return raw_controller;
+}
+
+void AllPasswordsBottomSheetController::OnGetPasswordStoreResults(
+    std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
+  // TODO(crbug.com/1104132): Implement.
+}
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h
new file mode 100644
index 0000000..dc69f76
--- /dev/null
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h
@@ -0,0 +1,55 @@
+// Copyright 2020 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_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_CONTROLLER_H_
+#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_CONTROLLER_H_
+
+#include "components/password_manager/core/browser/password_store_consumer.h"
+
+namespace password_manager {
+class PasswordManagerDriver;
+class PasswordStore;
+}  // namespace password_manager
+
+class AllPasswordsBottomSheetView;
+
+// This class gets credentials and creates AllPasswordsBottomSheetView.
+class AllPasswordsBottomSheetController
+    : public password_manager::PasswordStoreConsumer {
+ public:
+  AllPasswordsBottomSheetController(
+      password_manager::PasswordManagerDriver* driver,
+      password_manager::PasswordStore* store);
+  ~AllPasswordsBottomSheetController() override;
+  AllPasswordsBottomSheetController(const AllPasswordsBottomSheetController&) =
+      delete;
+  AllPasswordsBottomSheetController& operator=(
+      const AllPasswordsBottomSheetController&) = delete;
+
+  // PasswordStoreConsumer:
+  void OnGetPasswordStoreResults(
+      std::vector<std::unique_ptr<autofill::PasswordForm>> results) override;
+
+  // Initializes the view and the controller.
+  // Doesn't take ownership of |driver|.
+  // Doesn't take ownership of |store|.
+  static AllPasswordsBottomSheetController* Create(
+      password_manager::PasswordManagerDriver* driver,
+      password_manager::PasswordStore* store);
+
+  // Instructs AllPasswordsBottomSheetView to show the credentials to the user.
+  void Show();
+
+ private:
+  // The controller doesn't take |driver_| ownership.
+  password_manager::PasswordManagerDriver* driver_ = nullptr;
+
+  // The controller doesn't take |store_| ownership.
+  password_manager::PasswordStore* store_ = nullptr;
+
+  // The controller takes |view_| ownership.
+  AllPasswordsBottomSheetView* view_ = nullptr;
+};
+
+#endif  // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_CONTROLLER_H_
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.cc
new file mode 100644
index 0000000..fbdcff7
--- /dev/null
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.cc
@@ -0,0 +1,28 @@
+// Copyright 2020 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/password_manager/android/all_passwords_bottom_sheet_view.h"
+
+#include "chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h"
+#include "components/password_manager/core/browser/password_manager_driver.h"
+
+AllPasswordsBottomSheetView::AllPasswordsBottomSheetView(
+    std::unique_ptr<AllPasswordsBottomSheetController> controller)
+    : controller_(std::move(controller)) {}
+
+AllPasswordsBottomSheetView::AllPasswordsBottomSheetView(
+    AllPasswordsBottomSheetView&&) = default;
+AllPasswordsBottomSheetView& AllPasswordsBottomSheetView::operator=(
+    AllPasswordsBottomSheetView&&) = default;
+
+AllPasswordsBottomSheetView::~AllPasswordsBottomSheetView() = default;
+
+AllPasswordsBottomSheetView* AllPasswordsBottomSheetView::Create(
+    std::unique_ptr<AllPasswordsBottomSheetController> controller) {
+  return new AllPasswordsBottomSheetView(std::move(controller));
+}
+
+void AllPasswordsBottomSheetView::AllPasswordsBottomSheetView::Show() {
+  // TODO(crbug.com/1104132): Implement.
+}
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.h b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.h
new file mode 100644
index 0000000..35de460
--- /dev/null
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_view.h
@@ -0,0 +1,37 @@
+// Copyright 2020 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_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_VIEW_H_
+#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_VIEW_H_
+
+#include <memory>
+
+class AllPasswordsBottomSheetController;
+
+// Bridge AllPasswordsBottomSheet native and java view code by converting user
+// credentials data into java-readable formats.
+class AllPasswordsBottomSheetView {
+ public:
+  AllPasswordsBottomSheetView(
+      std::unique_ptr<AllPasswordsBottomSheetController> controller);
+  AllPasswordsBottomSheetView(const AllPasswordsBottomSheetView&) = delete;
+  AllPasswordsBottomSheetView& operator=(const AllPasswordsBottomSheetView&) =
+      delete;
+  AllPasswordsBottomSheetView(AllPasswordsBottomSheetView&&);
+  AllPasswordsBottomSheetView& operator=(AllPasswordsBottomSheetView&&);
+  ~AllPasswordsBottomSheetView();
+
+  // Create an instance of the view with passed controller.
+  // return a raw pointer for the view.
+  static AllPasswordsBottomSheetView* Create(
+      std::unique_ptr<AllPasswordsBottomSheetController> controller);
+
+  // Makes call to java bridge to show AllPasswordsBottomSheet view.
+  void Show();
+
+ private:
+  std::unique_ptr<AllPasswordsBottomSheetController> controller_ = nullptr;
+};
+
+#endif  // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ALL_PASSWORDS_BOTTOM_SHEET_VIEW_H_
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc
index d224e9b..1724874 100644
--- a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc
+++ b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc
@@ -17,6 +17,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autofill/manual_filling_controller.h"
 #include "chrome/browser/autofill/manual_filling_utils.h"
+#include "chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h"
 #include "chrome/browser/password_manager/android/password_accessory_controller.h"
 #include "chrome/browser/password_manager/android/password_accessory_metrics_util.h"
 #include "chrome/browser/password_manager/android/password_generation_controller.h"
@@ -197,6 +198,18 @@
 
 void PasswordAccessoryControllerImpl::OnOptionSelected(
     autofill::AccessoryAction selected_action) {
+  if (selected_action == autofill::AccessoryAction::USE_OTHER_PASSWORD) {
+    password_manager::ContentPasswordManagerDriverFactory* factory =
+        password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
+            web_contents_);
+    password_manager::ContentPasswordManagerDriver* driver =
+        factory->GetDriverForFrame(web_contents_->GetFocusedFrame());
+    AllPasswordsBottomSheetController* controller =
+        AllPasswordsBottomSheetController::Create(
+            driver, password_client_->GetProfilePasswordStore());
+    controller->Show();
+    return;
+  }
   if (selected_action == autofill::AccessoryAction::MANAGE_PASSWORDS) {
     password_manager_launcher::ShowPasswordSettings(
         web_contents_,
@@ -263,6 +276,15 @@
     }
   }
 
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::kFillingPasswordsFromAnyOrigin)) {
+    base::string16 use_other_password_title = l10n_util::GetStringUTF16(
+        IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD);
+    footer_commands_to_add.push_back(
+        FooterCommand(use_other_password_title,
+                      autofill::AccessoryAction::USE_OTHER_PASSWORD));
+  }
+
   if (is_password_field && is_manual_generation_available) {
     base::string16 generate_password_title = l10n_util::GetStringUTF16(
         IDS_PASSWORD_MANAGER_ACCESSORY_GENERATE_PASSWORD_BUTTON_TITLE);
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
index 9511557..e94de53 100644
--- a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
+++ b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
@@ -142,6 +142,11 @@
   return l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN);
 }
 
+base::string16 show_other_passwords_str() {
+  return l10n_util::GetStringUTF16(
+      IDS_PASSWORD_MANAGER_ACCESSORY_USE_OTHER_PASSWORD);
+}
+
 base::string16 manage_passwords_str() {
   return l10n_util::GetStringUTF16(
       IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK);
@@ -627,6 +632,41 @@
       /*is_manual_generation_available=*/false);
 }
 
+TEST_F(PasswordAccessoryControllerTest, AddsShowOtherPasswordsIfEnabled) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      password_manager::features::kFillingPasswordsFromAnyOrigin);
+  AccessorySheetData::Builder data_builder(AccessoryTabType::PASSWORDS,
+                                           passwords_empty_str(kExampleDomain));
+  data_builder
+      .AppendFooterCommand(show_other_passwords_str(),
+                           autofill::AccessoryAction::USE_OTHER_PASSWORD)
+      .AppendFooterCommand(manage_passwords_str(),
+                           autofill::AccessoryAction::MANAGE_PASSWORDS);
+  EXPECT_CALL(mock_manual_filling_controller_,
+              RefreshSuggestions(std::move(data_builder).Build()));
+
+  controller()->RefreshSuggestionsForField(
+      FocusedFieldType::kFillablePasswordField,
+      /*is_manual_generation_available=*/false);
+}
+
+TEST_F(PasswordAccessoryControllerTest, HidesShowOtherPasswordsIfDisabled) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(
+      password_manager::features::kFillingPasswordsFromAnyOrigin);
+  AccessorySheetData::Builder data_builder(AccessoryTabType::PASSWORDS,
+                                           passwords_empty_str(kExampleDomain));
+  data_builder.AppendFooterCommand(manage_passwords_str(),
+                                   autofill::AccessoryAction::MANAGE_PASSWORDS);
+  EXPECT_CALL(mock_manual_filling_controller_,
+              RefreshSuggestions(std::move(data_builder).Build()));
+
+  controller()->RefreshSuggestionsForField(
+      FocusedFieldType::kFillablePasswordField,
+      /*is_manual_generation_available=*/false);
+}
+
 TEST_F(PasswordAccessoryControllerTest,
        NoSaveToggleIfIsBlacklistedAndSavingDisabled) {
   base::test::ScopedFeatureList scoped_feature_list;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 6bc07b6..db1db22 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <memory>
 #include <set>
 #include <utility>
 
@@ -154,6 +155,7 @@
 #include "third_party/blink/public/public_buildflags.h"
 #include "third_party/metrics_proto/omnibox_input_type.pb.h"
 #include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_data_endpoint.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
 #include "ui/base/emoji/emoji_panel_helper.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -771,7 +773,8 @@
   if (url.is_empty() || !url.is_valid())
     return;
 
-  ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
+  ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste,
+                                CreateDataEndpoint());
   scw.WriteText(FormatURLForClipboard(url));
 }
 
@@ -2665,6 +2668,16 @@
   }
 }
 
+std::unique_ptr<ui::ClipboardDataEndpoint>
+RenderViewContextMenu::CreateDataEndpoint() {
+  RenderFrameHost* render_frame_host = GetRenderFrameHost();
+  if (render_frame_host) {
+    return std::make_unique<ui::ClipboardDataEndpoint>(
+        render_frame_host->GetLastCommittedURL());
+  }
+  return nullptr;
+}
+
 bool RenderViewContextMenu::IsRouteMediaEnabled() const {
   if (!media_router::MediaRouterEnabled(browser_context_))
     return false;
@@ -2838,7 +2851,8 @@
 }
 
 void RenderViewContextMenu::ExecCopyLinkText() {
-  ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
+  ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste,
+                                CreateDataEndpoint());
   scw.WriteText(params_.link_text);
 }
 
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h
index 93b1df8..9da13ac 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -62,6 +62,10 @@
 }
 }
 
+namespace ui {
+class ClipboardDataEndpoint;
+}
+
 class RenderViewContextMenu : public RenderViewContextMenuBase {
  public:
   RenderViewContextMenu(content::RenderFrameHost* render_frame_host,
@@ -138,7 +142,7 @@
   static base::string16 FormatURLForClipboard(const GURL& url);
 
   // Writes the specified text/url to the system clipboard.
-  static void WriteURLToClipboard(const GURL& url);
+  void WriteURLToClipboard(const GURL& url);
 
   // RenderViewContextMenuBase:
   void InitMenu() override;
@@ -195,6 +199,8 @@
   void AppendSharedClipboardItem();
   void AppendQRCodeGeneratorItem(bool for_image, bool draw_icon);
 
+  std::unique_ptr<ui::ClipboardDataEndpoint> CreateDataEndpoint();
+
   // Command enabled query functions.
   bool IsReloadEnabled() const;
   bool IsViewSourceEnabled() const;
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index 50730d12..8cfe9eb 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -216,6 +216,8 @@
 
 js_library("oobe_eula") {
   deps = [
+    ":web_view_helper",
+    "components:login_screen_behavior",
     "components:oobe_dialog",
     "components:oobe_dialog_host_behavior",
     "components:oobe_i18n_behavior",
@@ -284,3 +286,6 @@
 
 js_library("update_required_card") {
 }
+
+js_library("web_view_helper") {
+}
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js
index d3d75f0..ba40e64 100644
--- a/chrome/browser/resources/chromeos/login/oobe.js
+++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -38,7 +38,6 @@
 // <include src="oobe_screen_demo_setup.js">
 // <include src="oobe_screen_demo_preferences.js">
 // <include src="oobe_screen_enable_debugging.js">
-// <include src="oobe_screen_eula.js">
 // <include src="multi_tap_detector.js">
 // <include src="web_view_helper.js">
 
@@ -50,7 +49,6 @@
      */
     initialize() {
       cr.ui.login.DisplayManager.initialize();
-      login.EulaScreen.register();
       login.AutoEnrollmentCheckScreen.register();
       login.EnableDebuggingScreen.register();
       login.AutolaunchScreen.register();
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.css b/chrome/browser/resources/chromeos/login/oobe_eula.css
index 0bc36a6..3642ae4 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.css
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.css
@@ -17,7 +17,7 @@
   height: 300px;
 }
 
-#installationSettings,
+#securitySettings,
 #logging {
   font-size: 13px;
   min-height: unset;
@@ -28,7 +28,7 @@
 }
 
 #additionalTerms,
-#installationSettings,
+#securitySettings,
 #logging {
   margin-top: 16px;
 }
@@ -65,6 +65,6 @@
   user-select: text;
 }
 
-.installation-settings-spinner {
+.security-settings-spinner {
   margin-inline-end: 5px;
 }
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html
index 788ee54..89633e7 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.html
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -40,10 +40,10 @@
               class="oobe-local-link">
             [[i18nDynamic(locale, 'oobeEulaAditionalTerms')]]
           </a>
-          <a id="installationSettings" href="#"
+          <a id="securitySettings" href="#"
               class="oobe-local-link"
-              on-tap="onInstallationSettingsClicked_">
-            [[i18nDynamic(locale, 'eulaSystemInstallationSettings')]]
+              on-tap="onSecuritySettingsClicked_">
+            [[i18nDynamic(locale, 'eulaSystemSecuritySettings')]]
           </a>
           <div id="logging" class="layout horizontal">
             <cr-checkbox id="usageStats" class="layout start self-center"
@@ -53,7 +53,7 @@
                 <span id="usageStatsLabel">
                   [[i18nDynamic(locale, 'checkboxLogging')]]
                 </span>
-                <a id="learn-more" href="#"
+                <a id="learnMore" href="#"
                     on-tap="onUsageStatsHelpLinkClicked_"
                     class="oobe-local-link">
                   [[i18nDynamic(locale, 'learnMore')]]
@@ -75,9 +75,9 @@
         </oobe-text-button>
       </div>
     </oobe-dialog>
-    <oobe-dialog id="installationSettingsDialog" role="dialog" has-buttons
-      title-key="eulaSystemInstallationSettings" hidden
-      aria-label$="[[i18nDynamic(locale, 'eulaSystemInstallationSettings')]]">
+    <oobe-dialog id="securitySettingsDialog" role="dialog" has-buttons
+      title-key="eulaSystemSecuritySettings" hidden
+      aria-label$="[[i18nDynamic(locale, 'eulaSystemSecuritySettings')]]">
       <hd-iron-icon slot="oobe-icon"
           icon1x="oobe-32:googleg" icon2x="oobe-64:googleg">
       </hd-iron-icon>
@@ -95,7 +95,7 @@
           </div>
           <div class="layout horizontal"
               hidden="[[!isWaitingForPassword_(password)]]">
-            <div class="installation-settings-spinner throbber"></div>
+            <div class="security-settings-spinner throbber"></div>
             <div>
               [[i18nDynamic(locale, 'eulaTpmBusy')]]
             </div>
@@ -111,11 +111,11 @@
         <div class="flex"></div>
         <oobe-text-button id="settings-close-button" inverse
             class="focus-on-show"
-            text-key="eulaSystemInstallationSettingsOkButton"
-            on-tap="onInstallationSettingsCloseClicked_"></oobe-text-button>
+            text-key="eulaSystemSecuritySettingsOkButton"
+            on-tap="onSecuritySettingsCloseClicked_"></oobe-text-button>
       </div>
     </oobe-dialog>
-    <cr-dialog id="additional-tos" ignore-popstate
+    <cr-dialog id="additionalToS" ignore-popstate
         on-close="focusAdditionalTermsLink_"
         on-cancel="focusAdditionalTermsLink_">
       <div slot="title">
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.js b/chrome/browser/resources/chromeos/login/oobe_eula.js
index 04990de..646bc47 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.js
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.js
@@ -2,6 +2,231 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+(function() {
+const CLEAR_ANCHORS_CONTENT_SCRIPT = {
+  code: 'A=Array.from(document.getElementsByTagName("a"));' +
+      'for(var i = 0; i < A.length; ++i) {' +
+      '  const el = A[i];' +
+      '  let e = document.createElement("span");' +
+      '  if (el.textContent.trim().length > 0) {' +
+      '    e.textContent=el.textContent + "(" + el.href + ")";' +
+      '  }' +
+      '  el.parentNode.replaceChild(e,el);' +
+      '}'
+};
+
+const EULA_FONTS_CSS = {
+  code: `body * {
+        font-family: Roboto, sans-serif !important;
+        font-size: 13px !important;
+        background-color: transparent !important;
+        line-height: 20px !important;}
+       body {
+        background-color: transparent !important;
+       }
+       body h2 {
+         font-size: 15px !important;
+         line-height: 22px !important;}`
+};
+
+/**
+ * Timeout to load online Eula.
+ * @type {number}
+ */
+const ONLINE_EULA_LOAD_TIMEOUT_IN_MS = 7000;
+
+/**
+ * Timeout between consequent loads of online Eula.
+ * @type {number}
+ */
+const ONLINE_EULA_RETRY_BACKOFF_TIMEOUT_IN_MS = 1000;
+
+/**
+ * URL to use when online page is not available.
+ * @type {string}
+ */
+const TERMS_URL = 'chrome://terms';
+
+// EulaLoader assists on the process of loading an URL into a webview.
+// It listens for events from the webRequest API for the given URL and
+// loads an offline version of the EULA in case of failure. Calling
+// setURL() multiple times with the same URL while requests are being made
+// won't affect current requests. Instead, it will mark the flag
+// 'reloadRequested' for the given URL. The reload will be performed only
+// if the current requests fail. This prevents webview-loadAbort events
+// from being fired and unnecessary reloads.
+class EulaLoader {
+  /**
+   * @suppress {missingProperties} as WebView type has no addContentScripts
+   */
+  constructor(webview, timeout, load_offline_callback, clear_anchors) {
+    assert(webview.tagName === 'WEBVIEW');
+
+    // Do not create multiple loaders.
+    if (EulaLoader.instances[webview.id]) {
+      return EulaLoader.instances[webview.id];
+    }
+
+    this.webview_ = webview;
+    this.timeout_ = timeout;
+    this.isPerformingRequests_ = false;
+    this.reloadRequested_ = false;
+    this.loadOfflineCallback_ = load_offline_callback;
+    this.loadTimer_ = 0;
+    this.backOffTimer_ = 0;
+    this.url_ = '';
+
+    if (clear_anchors) {
+      // Add the CLEAR_ANCHORS_CONTENT_SCRIPT that will clear <a><\a>
+      // (anchors) in order to prevent any navigation in the webview itself.
+      webview.addContentScripts([{
+        name: 'clearAnchors',
+        matches: ['<all_urls>'],
+        js: CLEAR_ANCHORS_CONTENT_SCRIPT,
+      }]);
+      webview.addEventListener('contentload', () => {
+        webview.executeScript(CLEAR_ANCHORS_CONTENT_SCRIPT);
+      });
+    }
+    webview.addEventListener('contentload', () => {
+      webview.insertCSS(EULA_FONTS_CSS);
+    });
+
+    // Monitor webRequests API events
+    this.webview_.request.onCompleted.addListener(
+        this.onCompleted_.bind(this),
+        {urls: ['<all_urls>'], types: ['main_frame']});
+    this.webview_.request.onErrorOccurred.addListener(
+        this.onErrorOccurred_.bind(this),
+        {urls: ['<all_urls>'], types: ['main_frame']});
+
+    // The only instance of the EulaLoader.
+    EulaLoader.instances[webview.id] = this;
+  }
+
+  // Clears the internal state of the EULA loader. Stops the timeout timer
+  // and prevents events from being handled.
+  clearInternalState() {
+    window.clearTimeout(this.loadTimer_);
+    window.clearTimeout(this.backOffTimer_);
+    this.isPerformingRequests_ = false;
+    this.reloadRequested_ = false;
+  }
+
+  // Sets an URL to be loaded in the webview. If the URL is different from the
+  // previous one, it will be immediately loaded. If the URL is the same as
+  // the previous one, it will be reloaded. If requests are under way, the
+  // reload will be performed once the current requests are finished.
+  setUrl(url) {
+    assert(/^https?:\/\//.test(url));
+
+    if (url != this.url_) {
+      // Clear the internal state and start with a new URL.
+      this.clearInternalState();
+      this.url_ = url;
+      this.loadWithFallbackTimer();
+    } else {
+      // Same URL was requested again. Reload later if a request is under way.
+      if (this.isPerformingRequests_)
+        this.reloadRequested_ = true;
+      else
+        this.loadWithFallbackTimer();
+    }
+  }
+
+  // This method only gets invoked if the webview webRequest API does not
+  // fire either 'onErrorOccurred' or 'onCompleted' before the timer runs out.
+  // See: https://developer.chrome.com/extensions/webRequest
+  onTimeoutError_() {
+    // Return if we are no longer monitoring requests. Sanity check.
+    if (!this.isPerformingRequests_)
+      return;
+
+    if (this.reloadRequested_)
+      this.loadWithFallbackTimer();
+    else
+      this.tryLoadOffline();
+  }
+
+  // Loads the offline version of the EULA.
+  tryLoadOffline() {
+    this.clearInternalState();
+    if (this.loadOfflineCallback_)
+      this.loadOfflineCallback_();
+  }
+
+  /**
+   * Only process events for the current URL and when performing requests.
+   * @param {!Object} details
+   */
+  shouldProcessEvent(details) {
+    return this.isPerformingRequests_ && (details.url === this.url_);
+  }
+
+  /**
+   * webRequest API Event Handler for 'onErrorOccurred'
+   * @param {!Object} details
+   */
+  onErrorOccurred_(details) {
+    if (!this.shouldProcessEvent(details))
+      return;
+
+    if (this.reloadRequested_)
+      this.loadWithFallbackTimer();
+    else
+      this.loadAfterBackoff();
+  }
+
+  /**
+   * webRequest API Event Handler for 'onCompleted'
+   * @suppress {missingProperties} no statusCode for details
+   * @param {!Object} details
+   */
+  onCompleted_(details) {
+    if (!this.shouldProcessEvent(details))
+      return;
+
+    // Http errors such as 4xx, 5xx hit here instead of 'onErrorOccurred'.
+    if (details.statusCode != 200) {
+      // Not a successful request. Perform a reload if requested.
+      if (this.reloadRequested_)
+        this.loadWithFallbackTimer();
+      else
+        this.loadAfterBackoff();
+    } else {
+      // Success!
+      this.clearInternalState();
+    }
+  }
+
+  // Loads the URL into the webview and starts a timer.
+  loadWithFallbackTimer() {
+    // Clear previous timer and perform a load.
+    window.clearTimeout(this.loadTimer_);
+    this.loadTimer_ =
+        window.setTimeout(this.onTimeoutError_.bind(this), this.timeout_);
+    this.tryLoadOnline();
+  }
+
+  loadAfterBackoff() {
+    window.clearTimeout(this.backOffTimer_);
+    this.backOffTimer_ = window.setTimeout(
+        this.tryLoadOnline.bind(this), ONLINE_EULA_RETRY_BACKOFF_TIMEOUT_IN_MS);
+  }
+
+  tryLoadOnline() {
+    this.reloadRequested_ = false;
+    // A request is being made
+    this.isPerformingRequests_ = true;
+    if (this.webview_.src === this.url_)
+      this.webview_.reload();
+    else
+      this.webview_.src = this.url_;
+  }
+}
+
+EulaLoader.instances = {};
+
 /**
  * @fileoverview Polymer element for displaying material design Terms Of Service
  * screen.
@@ -10,7 +235,14 @@
 Polymer({
   is: 'oobe-eula-md',
 
-  behaviors: [OobeI18nBehavior, OobeDialogHostBehavior],
+  behaviors: [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
+
+  EXTERNAL_API: [
+    'setTpmPassword',
+    'setUsageStats',
+    'showAdditionalTosDialog',
+    'showSecuritySettingsDialog',
+  ],
 
   properties: {
     /**
@@ -38,23 +270,12 @@
     },
 
     /**
-     * The TPM password shown on the installation settings page.
+     * The TPM password shown on the security settings page.
      */
     password: {
       type: String,
       value: null,
     },
-
-    /**
-     * Reference to OOBE screen object.
-     * @type {!{
-     *     loadEulaToWebview_: function(Element, string, boolean),
-     *     onUsageStatsClicked_: function(boolean),
-     * }}
-     */
-    screen: {
-      type: Object,
-    },
   },
 
   /**
@@ -65,15 +286,22 @@
 
   focus() {
     if (this.eulaLoadingScreenShown) {
-      this.$.eulaLoadingDialog.show();
+      this.$.eulaLoadingDialog.focus();
     } else {
-      this.$.eulaDialog.show();
+      this.$.crosEulaFrame.focus();
     }
   },
 
-  /** Called when dialog is shown */
+  /** Called just before the dialog is shown */
   onBeforeShow() {
     window.setTimeout(this.initializeScreen_.bind(this), 0);
+    this.updateLocalizedContent();
+  },
+
+  ready() {
+    this.initializeLoginScreen('EulaScreen', {
+      resetAllowed: true,
+    });
   },
 
   /**
@@ -115,19 +343,48 @@
   },
 
   /**
+   * Load Eula into the given webview. Online version is attempted first with
+   * a timeout. If it fails to load, fallback to chrome://terms. The loaded
+   * terms contents is then set to the webview via data url. Webview is
+   * used as a sandbox for both online and local contents. Data url is
+   * used for chrome://terms so that webview never needs to have the
+   * privileged webui bindings.
+   *
+   * @param {!Object} webview Webview element to host the terms.
+   * @param {!string} onlineEulaUrl
+   * @param {boolean} clear_anchors if true the script will clear anchors
+   *                                from the loaded page.
+   */
+  loadEulaToWebview_(webview, onlineEulaUrl, clear_anchors) {
+    assert(webview.tagName === 'WEBVIEW');
+
+    var loadBundledEula = function() {
+      WebViewHelper.loadUrlContentToWebView(
+          webview, TERMS_URL, WebViewHelper.ContentType.HTML);
+    };
+
+    // Load online Eula with a timeout to fallback to the offline version.
+    // This won't construct multiple EulaLoaders. Single instance.
+    var eulaLoader = new EulaLoader(
+        webview, ONLINE_EULA_LOAD_TIMEOUT_IN_MS, loadBundledEula,
+        clear_anchors);
+    eulaLoader.setUrl(onlineEulaUrl);
+  },
+
+  /**
    * This is called when strings are updated.
    */
-  updateLocalizedContent(event) {
+  updateLocalizedContent() {
     // This forces frame to reload.
     const onlineEulaUrl = loadTimeData.getString('eulaOnlineUrl');
 
     this.eulaLoadingScreenShown = true;
-    this.screen.loadEulaToWebview_(
+    this.loadEulaToWebview_(
         this.$.crosEulaFrame, onlineEulaUrl, false /* clear_anchors */);
 
     const additionalToSUrl =
         loadTimeData.getString('eulaAdditionalToSOnlineUrl');
-    this.screen.loadEulaToWebview_(
+    this.loadEulaToWebview_(
         this.$.additionalChromeToSFrame, additionalToSUrl,
         true /* clear_anchors */);
     this.i18nUpdateLocale();
@@ -139,7 +396,7 @@
    * @private
    */
   eulaAccepted_() {
-    chrome.send('login.EulaScreen.userActed', ['accept-button']);
+    this.userActed('accept-button');
   },
 
   /**
@@ -148,21 +405,26 @@
    * @private
    */
   onUsageChanged_() {
-    if (this.$.usageStats.checked) {
-      chrome.send('login.EulaScreen.userActed', ['select-stats-usage']);
+    if (this.usageStatsChecked) {
+      this.userActed('select-stats-usage');
     } else {
-      chrome.send('login.EulaScreen.userActed', ['unselect-stats-usage']);
+      this.userActed('unselect-stats-usage');
     }
-    this.screen.onUsageStatsClicked_(this.$.usageStats.checked);
   },
 
   /**
    * @private
    */
   onAdditionalTermsClicked_() {
-    chrome.send('login.EulaScreen.userActed', ['show-additional-tos']);
-    this.$['additional-tos'].showModal();
-    this.$['close-additional-tos'].focus();
+    this.userActed('show-additional-tos');
+  },
+
+  /**
+   * Shows additional terms of service dialog.
+   */
+  showAdditionalTosDialog() {
+    this.$.additionalToS.showModal();
+    this.$.additionalToS.focus();
   },
 
   /**
@@ -171,7 +433,7 @@
    * @private
    */
   hideToSDialog_() {
-    this.$['additional-tos'].close();
+    this.$.additionalToS.close();
   },
 
   /**
@@ -182,28 +444,33 @@
   },
 
   /**
-   * On-tap event handler for installationSettings.
+   * On-tap event handler for securitySettings.
    *
    * @private
    */
-  onInstallationSettingsClicked_() {
-    chrome.send('login.EulaScreen.userActed', ['show-security-settings']);
-    chrome.send('eulaOnInstallationSettingsPopupOpened');
-    this.$.eulaDialog.hidden = true;
-    this.$.installationSettingsDialog.hidden = false;
-    this.$.installationSettingsDialog.show();
+  onSecuritySettingsClicked_() {
+    this.userActed('show-security-settings');
   },
 
   /**
-   * On-tap event handler for the close button on installation settings page.
+   * Shows system security settings dialog.
+   */
+  showSecuritySettingsDialog() {
+    this.$.eulaDialog.hidden = true;
+    this.$.securitySettingsDialog.hidden = false;
+    this.$.securitySettingsDialog.show();
+  },
+
+  /**
+   * On-tap event handler for the close button on security settings page.
    *
    * @private
    */
-  onInstallationSettingsCloseClicked_() {
-    this.$.installationSettingsDialog.hidden = true;
+  onSecuritySettingsCloseClicked_() {
+    this.$.securitySettingsDialog.hidden = true;
     this.$.eulaDialog.hidden = false;
     this.$.eulaDialog.show();
-    this.$.installationSettings.focus();
+    this.$.securitySettings.focus();
   },
 
   /**
@@ -212,9 +479,8 @@
    * @private
    */
   onUsageStatsHelpLinkClicked_(e) {
-    chrome.send('login.EulaScreen.userActed', ['show-stats-usage-learn-more']);
-    this.$['learn-more'].focus();
-    chrome.send('eulaOnLearnMore');
+    this.userActed('show-stats-usage-learn-more');
+    this.$.learnMore.focus();
     e.stopPropagation();
   },
 
@@ -224,7 +490,7 @@
    * @private
    */
   onEulaBackButtonPressed_() {
-    chrome.send('login.EulaScreen.userActed', ['back-button']);
+    this.userActed('back-button');
   },
 
   /**
@@ -244,4 +510,28 @@
   isPasswordEmpty_(password) {
     return password != null && password.length == 0;
   },
+
+  /**
+   * Sets TPM password.
+   * @param {string} password TPM password to be shown.
+   */
+  setTpmPassword(password) {
+    this.password = password;
+  },
+
+  /**
+   * Sets usage statistics checkbox.
+   * @param {boolean} checked Is the checkbox checked?
+   */
+  setUsageStats(checked) {
+    this.usageStatsChecked = checked;
+  },
+
+  /**
+   * Called when focus is returned.
+   */
+  onFocusReturned() {
+    this.focus();
+  },
 });
+})();
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_eula.html b/chrome/browser/resources/chromeos/login/oobe_screen_eula.html
deleted file mode 100644
index d4794f3..0000000
--- a/chrome/browser/resources/chromeos/login/oobe_screen_eula.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="step hidden" id="eula" role="group"
-     i18n-values="aria-label:eulaScreenAccessibleTitle" hidden>
-  <oobe-eula-md id="oobe-eula-md"></oobe-eula-md>
-</div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js b/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
deleted file mode 100644
index 1fbbad8..0000000
--- a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
+++ /dev/null
@@ -1,316 +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.
-
-/**
- * @fileoverview Oobe eula screen implementation.
- */
-
-login.createScreen('EulaScreen', 'eula', function() {
-  const CLEAR_ANCHORS_CONTENT_SCRIPT = {
-    code: 'A=Array.from(document.getElementsByTagName("a"));' +
-        'for(var i = 0; i < A.length; ++i) {' +
-        '  const el = A[i];' +
-        '  let e = document.createElement("span");' +
-        '  if (el.textContent.trim().length > 0) {' +
-        '    e.textContent=el.textContent + "(" + el.href + ")";' +
-        '  }' +
-        '  el.parentNode.replaceChild(e,el);' +
-        '}'
-  };
-
-  const EULA_FONTS_CSS = {
-    code: `body * {
-          font-family: Roboto, sans-serif !important;
-          font-size: 13px !important;
-          background-color: transparent !important;
-          line-height: 20px !important;}
-         body {
-          background-color: transparent !important;
-         }
-         body h2 {
-           font-size: 15px !important;
-           line-height: 22px !important;}`
-  };
-
-  /**
-   * Timeout to load online Eula.
-   * @type {number}
-   */
-  const ONLINE_EULA_LOAD_TIMEOUT_IN_MS = 7000;
-
-  /**
-   * Timeout between consequent loads of online Eula.
-   * @type {number}
-   */
-  const ONLINE_EULA_RETRY_BACKOFF_TIMEOUT_IN_MS = 1000;
-
-  /**
-   * URL to use when online page is not available.
-   * @type {string}
-   */
-  const TERMS_URL = 'chrome://terms';
-
-  // EulaLoader assists on the process of loading an URL into a webview.
-  // It listens for events from the webRequest API for the given URL and
-  // loads an offline version of the EULA in case of failure. Calling
-  // setURL() multiple times with the same URL while requests are being made
-  // won't affect current requests. Instead, it will mark the flag
-  // 'reloadRequested' for the given URL. The reload will be performed only
-  // if the current requests fail. This prevents webview-loadAbort events
-  // from being fired and unnecessary reloads.
-  class EulaLoader {
-    constructor(webview, timeout, load_offline_callback, clear_anchors) {
-      assert(webview.tagName === 'WEBVIEW');
-
-      // Do not create multiple loaders.
-      if (EulaLoader.instances[webview.id]) {
-        return EulaLoader.instances[webview.id];
-      }
-
-      this.webview_ = webview;
-      this.timeout_ = timeout;
-      this.isPerformingRequests_ = false;
-      this.reloadRequested_ = false;
-      this.loadOfflineCallback_ = load_offline_callback;
-      this.loadTimer_ = 0;
-      this.backOffTimer_ = 0;
-
-      if (clear_anchors) {
-        // Add the CLEAR_ANCHORS_CONTENT_SCRIPT that will clear <a><\a>
-        // (anchors) in order to prevent any navigation in the webview itself.
-        webview.addContentScripts([{
-          name: 'clearAnchors',
-          matches: ['<all_urls>'],
-          js: CLEAR_ANCHORS_CONTENT_SCRIPT,
-        }]);
-        webview.addEventListener('contentload', () => {
-          webview.executeScript(CLEAR_ANCHORS_CONTENT_SCRIPT);
-        });
-      }
-      webview.addEventListener('contentload', () => {
-        webview.insertCSS(EULA_FONTS_CSS);
-      });
-
-      // Monitor webRequests API events
-      this.webview_.request.onCompleted.addListener(
-          this.onCompleted_.bind(this),
-          {urls: ['<all_urls>'], types: ['main_frame']});
-      this.webview_.request.onErrorOccurred.addListener(
-          this.onErrorOccurred_.bind(this),
-          {urls: ['<all_urls>'], types: ['main_frame']});
-
-      // The only instance of the EulaLoader.
-      EulaLoader.instances[webview.id] = this;
-    }
-
-    // Clears the internal state of the EULA loader. Stops the timeout timer
-    // and prevents events from being handled.
-    clearInternalState() {
-      window.clearTimeout(this.loadTimer_);
-      window.clearTimeout(this.backOffTimer_);
-      this.isPerformingRequests_ = false;
-      this.reloadRequested_ = false;
-    }
-
-    // Sets an URL to be loaded in the webview. If the URL is different from the
-    // previous one, it will be immediately loaded. If the URL is the same as
-    // the previous one, it will be reloaded. If requests are under way, the
-    // reload will be performed once the current requests are finished.
-    setUrl(url) {
-      assert(/^https?:\/\//.test(url));
-
-      if (url != this.url_) {
-        // Clear the internal state and start with a new URL.
-        this.clearInternalState();
-        this.url_ = url;
-        this.loadWithFallbackTimer();
-      } else {
-        // Same URL was requested again. Reload later if a request is under way.
-        if (this.isPerformingRequests_)
-          this.reloadRequested_ = true;
-        else
-          this.loadWithFallbackTimer();
-      }
-    }
-
-    // This method only gets invoked if the webview webRequest API does not
-    // fire either 'onErrorOccurred' or 'onCompleted' before the timer runs out.
-    // See: https://developer.chrome.com/extensions/webRequest
-    onTimeoutError_() {
-      // Return if we are no longer monitoring requests. Sanity check.
-      if (!this.isPerformingRequests_)
-        return;
-
-      if (this.reloadRequested_)
-        this.loadWithFallbackTimer();
-      else
-        this.tryLoadOffline();
-    }
-
-    // Loads the offline version of the EULA.
-    tryLoadOffline() {
-      this.clearInternalState();
-      if (this.loadOfflineCallback_)
-        this.loadOfflineCallback_();
-    }
-
-    // Only process events for the current URL and when performing requests.
-    shouldProcessEvent(details) {
-      return this.isPerformingRequests_ && (details.url === this.url_);
-    }
-
-    // webRequest API Event Handler for 'onErrorOccurred'
-    onErrorOccurred_(details) {
-      if (!this.shouldProcessEvent(details))
-        return;
-
-      if (this.reloadRequested_)
-        this.loadWithFallbackTimer();
-      else
-        this.loadAfterBackoff();
-    }
-
-    // webRequest API Event Handler for 'onCompleted'
-    onCompleted_(details) {
-      if (!this.shouldProcessEvent(details))
-        return;
-
-      // Http errors such as 4xx, 5xx hit here instead of 'onErrorOccurred'.
-      if (details.statusCode != 200) {
-        // Not a successful request. Perform a reload if requested.
-        if (this.reloadRequested_)
-          this.loadWithFallbackTimer();
-        else
-          this.loadAfterBackoff();
-      } else {
-        // Success!
-        this.clearInternalState();
-      }
-    }
-
-    // Loads the URL into the webview and starts a timer.
-    loadWithFallbackTimer() {
-      // Clear previous timer and perform a load.
-      window.clearTimeout(this.loadTimer_);
-      this.loadTimer_ =
-          window.setTimeout(this.onTimeoutError_.bind(this), this.timeout_);
-      this.tryLoadOnline();
-    }
-
-    loadAfterBackoff() {
-      window.clearTimeout(this.backOffTimer_);
-      this.backOffTimer_ = window.setTimeout(
-          this.tryLoadOnline.bind(this),
-          ONLINE_EULA_RETRY_BACKOFF_TIMEOUT_IN_MS);
-    }
-
-    tryLoadOnline() {
-      this.reloadRequested_ = false;
-      // A request is being made
-      this.isPerformingRequests_ = true;
-      if (this.webview_.src === this.url_)
-        this.webview_.reload();
-      else
-        this.webview_.src = this.url_;
-    }
-  }
-  EulaLoader.instances = {};
-
-  return {
-    EXTERNAL_API: [
-      'setTpmPassword',
-      'setUsageStats',
-    ],
-
-    /** @override */
-    decorate() {
-      $('oobe-eula-md').screen = this;
-    },
-
-    /**
-     * Called from $('oobe-eula-md') onUsageChanged handler.
-     * @param {boolean} value $('usage-stats').checked value.
-     */
-    onUsageStatsClicked_(value) {
-      chrome.send('EulaScreen.usageStatsEnabled', [value]);
-    },
-
-    /**
-     * Event handler that is invoked just before the screen is shown.
-     * @param {object} data Screen init payload.
-     */
-    onBeforeShow() {
-      this.updateLocalizedContent();
-    },
-
-    /**
-     * Returns a control which should receive an initial focus.
-     */
-    get defaultControl() {
-      return $('oobe-eula-md');
-    },
-
-    enableKeyboardFlow() {},
-
-    /**
-     * Updates localized content of the screen that is not updated via template.
-     */
-    updateLocalizedContent() {
-      // Reload the terms contents.
-      $('oobe-eula-md').updateLocalizedContent();
-    },
-
-    /**
-     * Sets TPM password.
-     * @param {text} password TPM password to be shown.
-     */
-    setTpmPassword(password) {
-      $('oobe-eula-md').password = password;
-    },
-
-    /**
-     * Sets usage statistics checkbox.
-     * @param {boolean} checked Is the checkbox checked?
-     */
-    setUsageStats(checked) {
-      $('oobe-eula-md').usageStatsChecked = checked;
-    },
-
-    /**
-     * Load Eula into the given webview. Online version is attempted first with
-     * a timeout. If it fails to load, fallback to chrome://terms. The loaded
-     * terms contents is then set to the webview via data url. Webview is
-     * used as a sandbox for both online and local contents. Data url is
-     * used for chrome://terms so that webview never needs to have the
-     * privileged webui bindings.
-     *
-     * @param {!WebView} webview Webview element to host the terms.
-     * @param {!string} onlineEulaUrl
-     * @param {boolean} clear_anchors if true the script will clear anchors
-     *                                from the loaded page.
-     */
-    loadEulaToWebview_(webview, onlineEulaUrl, clear_anchors) {
-      assert(webview.tagName === 'WEBVIEW');
-
-      var loadBundledEula = function() {
-        WebViewHelper.loadUrlContentToWebView(
-            webview, TERMS_URL, WebViewHelper.ContentType.HTML);
-      };
-
-      // Load online Eula with a timeout to fallback to the offline version.
-      // This won't construct multiple EulaLoaders. Single instance.
-      var eulaLoader = new EulaLoader(
-          webview, ONLINE_EULA_LOAD_TIMEOUT_IN_MS, loadBundledEula,
-          clear_anchors);
-      eulaLoader.setUrl(onlineEulaUrl);
-    },
-
-    /**
-     * Called when focus is returned.
-     */
-    onFocusReturned() {
-      $('oobe-eula-md').focus();
-    },
-  };
-});
diff --git a/chrome/browser/resources/chromeos/login/structure/screens_oobe.html b/chrome/browser/resources/chromeos/login/structure/screens_oobe.html
index 8a3be0f9..d7899dc 100644
--- a/chrome/browser/resources/chromeos/login/structure/screens_oobe.html
+++ b/chrome/browser/resources/chromeos/login/structure/screens_oobe.html
@@ -13,7 +13,7 @@
 <include src="../oobe_screen_demo_setup.html">
 <oobe-network id="network-selection" class="step hidden" hidden>
 </oobe-network>
-<include src="../oobe_screen_eula.html">
+<oobe-eula-md id="oobe-eula-md" class="step hidden" hidden></oobe-eula-md>
 <oobe-update id="oobe-update" class="step hidden" hidden>
 </oobe-update>
 <include src="../oobe_screen_auto_enrollment_check.html">
diff --git a/chrome/browser/resources/chromeos/login/web_view_helper.js b/chrome/browser/resources/chromeos/login/web_view_helper.js
index 47336de..edda633 100644
--- a/chrome/browser/resources/chromeos/login/web_view_helper.js
+++ b/chrome/browser/resources/chromeos/login/web_view_helper.js
@@ -13,9 +13,10 @@
    * The content is loaded via XHR and is sent to web view via data url so that
    * it is properly sandboxed.
    *
-   * @param {!WebView} webView web view element to host the content.
+   * @param {!Object} webView is a WebView element to host the content.
    * @param {string} url URL to load the content from.
-   * @param {!ContentType} contentType type of the content to load.
+   * @param {!WebViewHelper.ContentType} contentType type of the content to
+   *     load.
    */
   static loadUrlContentToWebView(webView, url, contentType) {
     assert(webView.tagName === 'WEBVIEW');
@@ -59,7 +60,8 @@
         onError();
         return;
       }
-      setContents(xhr.response);
+      let contents = /** @type {string} */ (xhr.response);
+      setContents(contents);
     };
 
     try {
@@ -79,4 +81,4 @@
   HTML: 'text/html',
   /** Base64 encoded application/pdf content type. */
   PDF: 'application/pdf',
-};
\ No newline at end of file
+};
diff --git a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html
index 6dd8bcf..37d9534 100644
--- a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html
+++ b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html
@@ -195,14 +195,18 @@
 
 <cr-action-menu force-dark-mode>
   <button id="single-page-view-button"
-      class="dropdown-item" on-click="onSinglePageViewClick_">
+      class="dropdown-item" on-click="onSinglePageViewClick_"
+      role="radio"
+      aria-checked="[[getSinglePageAriaChecked_(twoUpViewEnabled_)]]">
     <span class="check-container">
       <iron-icon icon="pdf:check" hidden="[[twoUpViewEnabled_]]"></iron-icon>
     </span>
     $i18n{twoUpViewDisable}
   </button>
   <button id="two-page-view-button"
-      class="dropdown-item" on-click="onTwoPageViewClick_">
+      class="dropdown-item" on-click="onTwoPageViewClick_"
+      role="radio"
+      aria-checked="[[getTwoPageViewAriaChecked_(twoUpViewEnabled_)]]">
     <span class="check-container">
       <iron-icon icon="pdf:check" hidden="[[!twoUpViewEnabled_]]"></iron-icon>
     </span>
@@ -210,7 +214,9 @@
   </button>
 
   <button id="show-annotations-button"
-      class="dropdown-item" on-click="toggleDisplayAnnotations_">
+      class="dropdown-item" on-click="toggleDisplayAnnotations_"
+      role="checkbox"
+      aria-checked="[[getShowAnnotationsAriaChecked_(displayAnnotations_)]]">
     <span class="check-container">
       <iron-icon icon="pdf:check" hidden="[[!displayAnnotations_]]"></iron-icon>
     </span>
diff --git a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js
index e33c4e4..dc958c8 100644
--- a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js
+++ b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js
@@ -181,6 +181,30 @@
     // </if>
   }
 
+  /**
+   * @param {boolean} checked
+   * @return {string}
+   */
+  getSinglePageAriaChecked_(checked) {
+    return checked ? 'false' : 'true';
+  }
+
+  /**
+   * @param {boolean} checked
+   * @return {string}
+   */
+  getTwoPageViewAriaChecked_(checked) {
+    return checked ? 'true' : 'false';
+  }
+
+  /**
+   * @param {boolean} checked
+   * @return {string}
+   */
+  getShowAnnotationsAriaChecked_(checked) {
+    return checked ? 'true' : 'false';
+  }
+
   /** @private */
   onSinglePageViewClick_() {
     this.twoUpViewEnabled_ = false;
diff --git a/chrome/browser/resources/signin/profile_picker/icons.js b/chrome/browser/resources/signin/profile_picker/icons.js
index 81d509c..3231955 100644
--- a/chrome/browser/resources/signin/profile_picker/icons.js
+++ b/chrome/browser/resources/signin/profile_picker/icons.js
@@ -1,8 +1,11 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
 
 const element = document.createElement('iron-iconset-svg');
 element.name = 'profiles';
-element.size = 74;
 element.innerHTML = `
 <svg>
   <defs>
@@ -10,6 +13,10 @@
       <circle cx="37" cy="37" r="37" stroke="none"/>
       <path d="M36.9999 46.4349C36.1315 46.4349 35.4274 45.7309 35.4274 44.8624V38.5724H29.1374C28.269 38.5724 27.5649 37.8684 27.5649 36.9999C27.5649 36.1315 28.269 35.4274 29.1374 35.4274H35.4274V29.1374C35.4274 28.269 36.1315 27.5649 36.9999 27.5649C37.8684 27.5649 38.5724 28.269 38.5724 29.1374V35.4274H44.8624C45.7309 35.4274 46.4349 36.1315 46.4349 36.9999C46.4349 37.8684 45.7309 38.5724 44.8624 38.5724H38.5724V44.8624C38.5724 45.7309 37.8684 46.4349 36.9999 46.4349Z" fill="var(--iron-icon-stroke-color)"/>
     </g>
+
+    <g id="account-circle" viewBox="0 0 24 24" fill="var(--footer-text-color)" width="18px" height="18px">
+      <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/>
+    </g>
   </defs>
 </svg>`;
 document.head.appendChild(element);
diff --git a/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js b/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js
index ad46615..9ae932f 100644
--- a/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js
+++ b/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js
@@ -37,6 +37,9 @@
    */
   launchSelectedProfile(profilePath) {}
 
+  /** Launches Guest profile. */
+  launchGuestProfile() {}
+
   /**
    * Inform native the user's choice on whether to show the profile picker
    * on startup or not.
@@ -68,6 +71,11 @@
   }
 
   /** @override */
+  launchGuestProfile() {
+    chrome.send('launchGuestProfile');
+  }
+
+  /** @override */
   askOnStartupChanged(shouldShow) {
     chrome.send('askOnStartupChanged', [shouldShow]);
   }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
index 9ba2ea1..4b6134d 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
@@ -89,14 +89,6 @@
     --cr-icon-button-stroke-color: var(--google-grey-refresh-700);
   }
 
-  @media (prefers-color-scheme: dark) {
-    /* TODO(msalama): Dark mode mocks not ready yet.*/
-    cr-checkbox {
-      --cr-checkbox-label-color: var(--google-grey-refresh-500);
-      background-color: rgba(var(--md-background-color), .8);
-    }
-  }
-
   .footer {
     bottom: 0;
     display: flex;
@@ -105,14 +97,36 @@
     width: 100%;
   }
 
+  .footer > * {
+    background-color: rgba(255, 255, 255, .8);
+  }
+
+  #browseAsGuestButton {
+    margin-inline-start: 40px;
+  }
+
+  #browseAsGuestButton > iron-icon {
+    margin-inline-end: 8px;
+  }
+
   cr-checkbox {
     --cr-checkbox-label-color:  var(--google-grey-refresh-700);
     --cr-checkbox-label-padding-start: 8px;
-    background-color: rgba(255, 255, 255, .8);
     justify-content: flex-end;
     margin-inline-end: 40px;
     margin-inline-start: auto;
   }
+
+  @media (prefers-color-scheme: dark) {
+    /* TODO(msalama): Dark mode mocks not ready yet.*/
+    .footer > * {
+      background-color: rgba(0, 0, 0, .5);
+    }
+
+    cr-checkbox {
+      --cr-checkbox-label-color: var(--google-grey-refresh-500);
+    }
+  }
 </style>
 
 <div id="leftBanner" class="banner"></div>
@@ -139,6 +153,10 @@
 <div id="rightBanner" class="banner"></div>
 
 <div class="footer">
+  <cr-button id="browseAsGuestButton" on-click="onLaunchGuestProfileClick_">
+    <iron-icon icon="profiles:account-circle"></iron-icon>
+    <div>$i18n{browseAsGuestButton}</div>
+  </cr-button>
   <cr-checkbox checked="{{askOnStartup_}}"
       on-change="onAskOnStartupChangedByUser_">
     $i18n{askOnStartupCheckboxText}
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js
index a4e819f..4b2facb 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js
@@ -92,4 +92,9 @@
   onAddProfileClick_() {
     navigateTo(Routes.NEW_PROFILE);
   },
+
+  /** @private */
+  onLaunchGuestProfileClick_() {
+    this.manageProfilesBrowserProxy_.launchGuestProfile();
+  },
 });
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 0fafb9b3..153db81 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -6278,8 +6278,7 @@
   policy::PolicyMap policies;
   policies.Set(policy::key::kInsecureFormsWarningsEnabled,
                policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               policy::POLICY_SOURCE_CLOUD,
-               std::make_unique<base::Value>(false), nullptr);
+               policy::POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
   UpdateProviderPolicy(policies);
   // Pref should now be set to false.
   EXPECT_FALSE(browser()->profile()->GetPrefs()->GetBoolean(
diff --git a/chrome/browser/ui/README.md b/chrome/browser/ui/README.md
index 2137f44..3cdb130 100644
--- a/chrome/browser/ui/README.md
+++ b/chrome/browser/ui/README.md
@@ -2,10 +2,13 @@
 of this directory is toolkit- and platform-independent. There are subdirectories
 with implementations for specific toolkits and OSes. Code in the root of this
 directory should *not* be aware of platform-specific implementation details or
-reach into the platform implementation subdirectories.
+reach into the platform implementation subdirectories. This directory also
+should not contain browser-process-scoped items that are not UI-specific, such
+as parts of the startup logic; these sorts of things belong elsewhere in
+chrome/browser/.
 
-This directory is often referred to in conversation as "cbui", pronounced "sea
-bee you eye".
+This directory is often referred to in conversation as "cbui" or "c/b/ui",
+pronounced "sea bee you eye".
 
 Important subdirectories:
 * views - the Views implementation of the UI, used on Windows, Mac, Linux, and
@@ -35,3 +38,8 @@
 
 //chrome/browser/ui/android/my_dialog_android.cc:  
     void ShowMyDialog(...) { ... }
+
+Because "Chromium UI" is such a large surface area, do not add new files
+directly to this directory; instead, add subdirectories with more specific
+OWNERS and place new features and files in them. Cleanup of existing scattered
+files is also welcome.
diff --git a/chrome/browser/ui/ash/assistant/assistant_state_client_unittest.cc b/chrome/browser/ui/ash/assistant/assistant_state_client_unittest.cc
index df81f80ae..9097a3e 100644
--- a/chrome/browser/ui/ash/assistant/assistant_state_client_unittest.cc
+++ b/chrome/browser/ui/ash/assistant/assistant_state_client_unittest.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_util.h"
 #include "components/arc/test/fake_arc_session.h"
 #include "components/language/core/browser/pref_names.h"
@@ -30,9 +29,6 @@
   ~AssistantStateClientTest() override = default;
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     ChromeAshTestBase::SetUp();
 
     // Setup test profile.
@@ -61,7 +57,6 @@
     arc_session_manager_->Shutdown();
     arc_session_manager_.reset();
     ChromeAshTestBase::TearDown();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
   AssistantStateClient* assistant_state_client() {
diff --git a/chrome/browser/ui/ash/login_screen_client.cc b/chrome/browser/ui/ash/login_screen_client.cc
index 06892501..4629b2f 100644
--- a/chrome/browser/ui/ash/login_screen_client.cc
+++ b/chrome/browser/ui/ash/login_screen_client.cc
@@ -157,9 +157,19 @@
 }
 
 void LoginScreenClient::ShowGaiaSignin(const AccountId& prefilled_account) {
-  if (chromeos::LoginDisplayHost::default_host()) {
-    chromeos::LoginDisplayHost::default_host()->ShowGaiaDialog(
-        prefilled_account);
+  if (chromeos::parent_access::ParentAccessService::Get().IsApprovalRequired(
+          chromeos::parent_access::ParentAccessService::SupervisedAction::
+              kOnlineLogin)) {
+    // Show the client native parent access widget and processed to GAIA signin
+    // flow in |OnParentAccessValidation| when validation success.
+    ash::LoginScreen::Get()->ShowParentAccessWidget(
+        prefilled_account,
+        base::BindOnce(&LoginScreenClient::OnParentAccessValidation,
+                       weak_ptr_factory_.GetWeakPtr(), prefilled_account),
+        ash::ParentAccessRequestReason::kOnlineLogin, false /* extra_dimmer */,
+        base::Time::Now());
+  } else {
+    ShowGaiaSigninInternal(prefilled_account);
   }
 }
 
@@ -288,3 +298,18 @@
         ->ResetAutoLoginTimer();
   }
 }
+
+void LoginScreenClient::OnParentAccessValidation(
+    const AccountId& prefilled_account,
+    bool success) {
+  if (success)
+    ShowGaiaSigninInternal(prefilled_account);
+}
+
+void LoginScreenClient::ShowGaiaSigninInternal(
+    const AccountId& prefilled_account) {
+  if (chromeos::LoginDisplayHost::default_host()) {
+    chromeos::LoginDisplayHost::default_host()->ShowGaiaDialog(
+        prefilled_account);
+  }
+}
diff --git a/chrome/browser/ui/ash/login_screen_client.h b/chrome/browser/ui/ash/login_screen_client.h
index 7cd853d..8ead2a3 100644
--- a/chrome/browser/ui/ash/login_screen_client.h
+++ b/chrome/browser/ui/ash/login_screen_client.h
@@ -121,6 +121,13 @@
       const std::string& locale,
       std::unique_ptr<base::ListValue> keyboard_layouts);
 
+  void ShowGaiaSigninInternal(const AccountId& prefilled_account);
+
+  // Called when the parent access code was validated with result equals
+  // |success|.
+  void OnParentAccessValidation(const AccountId& prefilled_account,
+                                bool success);
+
   Delegate* delegate_ = nullptr;
 
   // Captures authentication related user metrics for login screen.
diff --git a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
index 00df4ea..c0a65c9 100644
--- a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
@@ -65,8 +65,7 @@
     policy::PolicyMap policy;
     policy.Set(policy::key::kDefaultPopupsSetting,
                policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               policy::POLICY_SOURCE_CLOUD,
-               std::make_unique<base::Value>(popup_setting),
+               policy::POLICY_SOURCE_CLOUD, base::Value(popup_setting),
                nullptr /* external_data_fetcher */);
     provider_.UpdateChromePolicy(policy);
   }
diff --git a/chrome/browser/ui/managed_ui_browsertest.cc b/chrome/browser/ui/managed_ui_browsertest.cc
index 0982201..5b2a80b5 100644
--- a/chrome/browser/ui/managed_ui_browsertest.cc
+++ b/chrome/browser/ui/managed_ui_browsertest.cc
@@ -43,7 +43,7 @@
   policy::PolicyMap policy_map;
   policy_map.Set("test-policy", policy::POLICY_LEVEL_MANDATORY,
                  policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_PLATFORM,
-                 std::make_unique<base::Value>("hello world"), nullptr);
+                 base::Value("hello world"), nullptr);
   provider()->UpdateChromePolicy(policy_map);
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index e162344..73eb5cc 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -887,7 +887,7 @@
   policy::PolicyMap policies;
   policies.Set("DefaultSearchProviderEnabled", policy::POLICY_LEVEL_MANDATORY,
                policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_PLATFORM,
-               std::make_unique<base::Value>(false), nullptr);
+               base::Value(false), nullptr);
   policy_provider()->UpdateChromePolicy(policies);
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index d09a67a..4e95530 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -1528,9 +1528,8 @@
   policy_map_.Set(policy::key::kRestoreOnStartup,
                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
                   policy::POLICY_SOURCE_CLOUD, base::Value(4), nullptr);
-  auto url_list = std::make_unique<base::Value>(base::Value::Type::LIST);
-  url_list->Append(
-      base::Value(embedded_test_server()->GetURL("/title1.html").spec()));
+  base::Value url_list(base::Value::Type::LIST);
+  url_list.Append(embedded_test_server()->GetURL("/title1.html").spec());
   policy_map_.Set(policy::key::kRestoreOnStartupURLs,
                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
                   policy::POLICY_SOURCE_CLOUD, std::move(url_list), nullptr);
diff --git a/chrome/browser/ui/startup/startup_browser_policy_unittest.cc b/chrome/browser/ui/startup/startup_browser_policy_unittest.cc
index e5d3393..7540cfd9 100644
--- a/chrome/browser/ui/startup/startup_browser_policy_unittest.cc
+++ b/chrome/browser/ui/startup/startup_browser_policy_unittest.cc
@@ -99,7 +99,7 @@
                  Args... args) {
     policy_map.Set(policy, policy::POLICY_LEVEL_MANDATORY,
                    policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-                   std::make_unique<base::Value>(args...), nullptr);
+                   base::Value(args...), nullptr);
   }
 
   template <typename... Args>
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index e3b52d5..6623827 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -280,20 +280,6 @@
   return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE);
 }
 
-bool CollectedCookiesViews::Accept() {
-  // If the user closes our parent tab while we're still open, this method will
-  // (eventually) be called in response to a WebContentsDestroyed() call from
-  // the WebContentsImpl to its observers.  But since the InfoBarService is also
-  // torn down in response to WebContentsDestroyed(), it may already be null.
-  // Since the tab is going away anyway, we can just omit showing an infobar,
-  // which prevents any attempt to access a null InfoBarService.
-  if (status_changed_ && !web_contents_->IsBeingDestroyed()) {
-    CollectedCookiesInfoBarDelegate::Create(
-        InfoBarService::FromWebContents(web_contents_));
-  }
-  return true;
-}
-
 ui::ModalType CollectedCookiesViews::GetModalType() const {
   return ui::MODAL_TYPE_CHILD;
 }
@@ -367,6 +353,11 @@
       SetLayoutManager(std::make_unique<views::GridLayout>());
   ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
 
+  SetAcceptCallback(base::BindOnce(&CollectedCookiesViews::OnDialogClosed,
+                                   base::Unretained(this)));
+  SetCloseCallback(base::BindOnce(&CollectedCookiesViews::OnDialogClosed,
+                                  base::Unretained(this)));
+
   // Add margin above the content. The left, right, and bottom margins are added
   // by the content itself.
   SetBorder(views::CreateEmptyBorder(
@@ -414,6 +405,19 @@
   ShowCookieInfo();
 }
 
+void CollectedCookiesViews::OnDialogClosed() {
+  // If the user closes our parent tab while we're still open, this method will
+  // (eventually) be called in response to a WebContentsDestroyed() call from
+  // the WebContentsImpl to its observers.  But since the InfoBarService is also
+  // torn down in response to WebContentsDestroyed(), it may already be null.
+  // Since the tab is going away anyway, we can just omit showing an infobar,
+  // which prevents any attempt to access a null InfoBarService.
+  if (status_changed_ && !web_contents_->IsBeingDestroyed()) {
+    CollectedCookiesInfoBarDelegate::Create(
+        InfoBarService::FromWebContents(web_contents_));
+  }
+}
+
 std::unique_ptr<views::View> CollectedCookiesViews::CreateAllowedPane() {
   // This captures a snapshot of the allowed cookies of the current page so we
   // are fine using WebContents::GetMainFrame() here
diff --git a/chrome/browser/ui/views/collected_cookies_views.h b/chrome/browser/ui/views/collected_cookies_views.h
index 5ade35b..0c22ac1 100644
--- a/chrome/browser/ui/views/collected_cookies_views.h
+++ b/chrome/browser/ui/views/collected_cookies_views.h
@@ -51,7 +51,6 @@
 
   // views::DialogDelegate:
   base::string16 GetWindowTitle() const override;
-  bool Accept() override;
   ui::ModalType GetModalType() const override;
   bool ShouldShowCloseButton() const override;
   void DeleteDelegate() override;
@@ -74,8 +73,9 @@
 
   explicit CollectedCookiesViews(content::WebContents* web_contents);
 
-  std::unique_ptr<views::View> CreateAllowedPane();
+  void OnDialogClosed();
 
+  std::unique_ptr<views::View> CreateAllowedPane();
   std::unique_ptr<views::View> CreateBlockedPane();
 
   // Creates and returns the "buttons pane", which is the view in the
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index 8085a8ca..fbfda14 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -268,7 +268,10 @@
     return;
   }
 
-  if (old_selection.line != OmniboxPopupModel::kNoMatch) {
+  // Do not invalidate the same line twice, in order to avoid redundant
+  // accessibility events.
+  if (old_selection.line != OmniboxPopupModel::kNoMatch &&
+      old_selection.line != new_selection.line) {
     InvalidateLine(old_selection.line);
   }
 
@@ -465,10 +468,15 @@
 
 void OmniboxPopupContentsView::FireAXEventsForNewActiveDescendant(
     View* descendant_view) {
-  if (descendant_view)
+  if (descendant_view) {
     descendant_view->NotifyAccessibilityEvent(ax::mojom::Event::kSelection,
                                               true);
-  NotifyAccessibilityEvent(ax::mojom::Event::kActiveDescendantChanged, true);
+  }
+  // Selected children changed is fired on the popup.
+  NotifyAccessibilityEvent(ax::mojom::Event::kSelectedChildrenChanged, true);
+  // Active descendant changed is fired on the focused text field.
+  omnibox_view_->NotifyAccessibilityEvent(
+      ax::mojom::Event::kActiveDescendantChanged, true);
 }
 
 void OmniboxPopupContentsView::OnWidgetBoundsChanged(
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
index 6fc7098..4161111 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
@@ -40,6 +40,10 @@
 
 namespace {
 
+bool contains(std::string str, std::string substr) {
+  return str.find(substr) != std::string::npos;
+}
+
 // A View that positions itself over another View to intercept clicks.
 class ClickTrackingOverlayView : public views::View {
  public:
@@ -98,13 +102,27 @@
       return;
     ui::AXNodeData node_data;
     view->GetAccessibleNodeData(&node_data);
+    ax::mojom::Role role = node_data.role;
     if (event_type == ax::mojom::Event::kTextChanged &&
-        node_data.role == ax::mojom::Role::kListBoxOption)
+        role == ax::mojom::Role::kListBoxOption) {
       text_changed_on_listboxoption_count_++;
-    else if (event_type == ax::mojom::Event::kSelectedChildrenChanged)
+    } else if (event_type == ax::mojom::Event::kSelectedChildrenChanged &&
+               role == ax::mojom::Role::kListBox) {
       selected_children_changed_count_++;
-    else if (event_type == ax::mojom::Event::kActiveDescendantChanged)
+    } else if (event_type == ax::mojom::Event::kSelection &&
+               role == ax::mojom::Role::kListBoxOption) {
+      selection_changed_count_++;
+      selected_option_name_ =
+          node_data.GetStringAttribute(ax::mojom::StringAttribute::kName);
+    } else if (event_type == ax::mojom::Event::kValueChanged &&
+               role == ax::mojom::Role::kTextField) {
+      value_changed_count_++;
+      omnibox_value_ =
+          node_data.GetStringAttribute(ax::mojom::StringAttribute::kValue);
+    } else if (event_type == ax::mojom::Event::kActiveDescendantChanged &&
+               role == ax::mojom::Role::kTextField) {
       active_descendant_changed_count_++;
+    }
   }
 
   int text_changed_on_listboxoption_count() {
@@ -113,14 +131,23 @@
   int selected_children_changed_count() {
     return selected_children_changed_count_;
   }
+  int selection_changed_count() { return selection_changed_count_; }
+  int value_changed_count() { return value_changed_count_; }
   int active_descendant_changed_count() {
     return active_descendant_changed_count_;
   }
 
+  std::string omnibox_value() { return omnibox_value_; }
+  std::string selected_option_name() { return selected_option_name_; }
+
  private:
   int text_changed_on_listboxoption_count_ = 0;
   int selected_children_changed_count_ = 0;
+  int selection_changed_count_ = 0;
+  int value_changed_count_ = 0;
   int active_descendant_changed_count_ = 0;
+  std::string omnibox_value_;
+  std::string selected_option_name_;
 
   DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
 };
@@ -365,8 +392,7 @@
   EXPECT_EQ(color_before_focus, omnibox_view()->GetBackgroundColor());
 }
 
-IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest,
-                       EmitTextChangedAccessibilityEvent) {
+IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest, EmitAccessibilityEvents) {
   // Creation and population of the popup should not result in a text/name
   // change accessibility event.
   TestAXEventObserver observer;
@@ -376,8 +402,10 @@
                           AutocompleteMatchType::HISTORY_TITLE);
   AutocompleteController* controller = popup_model()->autocomplete_controller();
   match.contents = base::ASCIIToUTF16("https://foobar.com");
+  match.description = base::ASCIIToUTF16("FooBarCom");
   matches.push_back(match);
   match.contents = base::ASCIIToUTF16("https://foobarbaz.com");
+  match.description = base::ASCIIToUTF16("FooBarBazCom");
   matches.push_back(match);
   controller->result_.AppendMatches(controller->input_, matches);
   popup_view()->UpdatePopupAppearance();
@@ -389,15 +417,96 @@
   edit_model()->StartAutocomplete(false, false);
   popup_view()->UpdatePopupAppearance();
   EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 0);
+  EXPECT_EQ(observer.selected_children_changed_count(), 1);
+  EXPECT_EQ(observer.selection_changed_count(), 1);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 1);
+  EXPECT_EQ(observer.value_changed_count(), 2);
 
   // Each time the selection changes, we should have a text/name change event.
   // This makes it possible for screen readers to have the updated match content
   // when they are notified the selection changed.
   popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(1));
   EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 1);
+  EXPECT_EQ(observer.selected_children_changed_count(), 2);
+  EXPECT_EQ(observer.selection_changed_count(), 2);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 2);
+  EXPECT_EQ(observer.value_changed_count(), 3);
+  EXPECT_TRUE(contains(observer.omnibox_value(), "2 of 3"));
+  EXPECT_FALSE(contains(observer.selected_option_name(), "2 of 3"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "foobar.com"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "FooBarCom"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "FooBarCom"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "location from history"));
+  EXPECT_TRUE(
+      contains(observer.selected_option_name(), "location from history"));
 
   popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(2));
   EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 2);
+  EXPECT_EQ(observer.selected_children_changed_count(), 3);
+  EXPECT_EQ(observer.selection_changed_count(), 3);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 3);
+  EXPECT_EQ(observer.value_changed_count(), 4);
+  EXPECT_TRUE(contains(observer.omnibox_value(), "3 of 3"));
+  EXPECT_FALSE(contains(observer.selected_option_name(), "3 of 3"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "foobarbaz.com"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "FooBarBazCom"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "FooBarBazCom"));
+}
+
+IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest,
+                       EmitAccessibilityEventsOnButtonFocusHint) {
+  TestAXEventObserver observer;
+  CreatePopupForTestQuery();
+  ACMatches matches;
+  AutocompleteMatch match(nullptr, 500, false,
+                          AutocompleteMatchType::HISTORY_TITLE);
+  AutocompleteController* controller = popup_model()->autocomplete_controller();
+  match.contents = base::ASCIIToUTF16("https://foobar.com");
+  match.description = base::ASCIIToUTF16("The Foo Of All Bars");
+  match.has_tab_match = true;
+  matches.push_back(match);
+  controller->result_.AppendMatches(controller->input_, matches);
+  popup_view()->UpdatePopupAppearance();
+
+  popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(1));
+  EXPECT_EQ(observer.selected_children_changed_count(), 2);
+  EXPECT_EQ(observer.selection_changed_count(), 2);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 2);
+  EXPECT_EQ(observer.value_changed_count(), 2);
+  EXPECT_TRUE(contains(observer.omnibox_value(), "The Foo Of All Bars"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "foobar.com"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "press Tab then Enter"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "2 of 2"));
+  EXPECT_TRUE(
+      contains(observer.selected_option_name(), "press Tab then Enter"));
+  EXPECT_FALSE(contains(observer.selected_option_name(), "2 of 2"));
+
+  popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(
+      1, OmniboxPopupModel::FOCUSED_BUTTON_TAB_SWITCH));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "The Foo Of All Bars"));
+  EXPECT_EQ(observer.selected_children_changed_count(), 3);
+  EXPECT_EQ(observer.selection_changed_count(), 3);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 3);
+  EXPECT_EQ(observer.value_changed_count(), 3);
+  EXPECT_TRUE(contains(observer.omnibox_value(), "press Enter to switch"));
+  EXPECT_FALSE(contains(observer.omnibox_value(), "2 of 2"));
+  EXPECT_TRUE(
+      contains(observer.selected_option_name(), "press Enter to switch"));
+  EXPECT_FALSE(contains(observer.selected_option_name(), "2 of 2"));
+
+  popup_view()->model()->SetSelection(
+      OmniboxPopupModel::Selection(1, OmniboxPopupModel::NORMAL));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "The Foo Of All Bars"));
+  EXPECT_TRUE(contains(observer.selected_option_name(), "foobar.com"));
+  EXPECT_EQ(observer.selected_children_changed_count(), 4);
+  EXPECT_EQ(observer.selection_changed_count(), 4);
+  EXPECT_EQ(observer.active_descendant_changed_count(), 4);
+  EXPECT_EQ(observer.value_changed_count(), 4);
+  EXPECT_TRUE(contains(observer.omnibox_value(), "press Tab then Enter"));
+  EXPECT_TRUE(contains(observer.omnibox_value(), "2 of 2"));
+  EXPECT_TRUE(
+      contains(observer.selected_option_name(), "press Tab then Enter"));
+  EXPECT_FALSE(contains(observer.selected_option_name(), "2 of 2"));
 }
 
 IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest,
@@ -434,16 +543,22 @@
   // Lets check that arrowing up and down emits the event.
   TestAXEventObserver observer;
   EXPECT_EQ(observer.selected_children_changed_count(), 0);
+  EXPECT_EQ(observer.selection_changed_count(), 0);
+  EXPECT_EQ(observer.value_changed_count(), 0);
   EXPECT_EQ(observer.active_descendant_changed_count(), 0);
 
   // This is equiverlent of the user arrowing down in the omnibox.
   popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(1));
   EXPECT_EQ(observer.selected_children_changed_count(), 1);
+  EXPECT_EQ(observer.selection_changed_count(), 1);
+  EXPECT_EQ(observer.value_changed_count(), 1);
   EXPECT_EQ(observer.active_descendant_changed_count(), 1);
 
   // This is equivalent of the user arrowing up in the omnibox.
   popup_view()->model()->SetSelection(OmniboxPopupModel::Selection(0));
   EXPECT_EQ(observer.selected_children_changed_count(), 2);
+  EXPECT_EQ(observer.selection_changed_count(), 2);
+  EXPECT_EQ(observer.value_changed_count(), 2);
   EXPECT_EQ(observer.active_descendant_changed_count(), 2);
 
   // TODO(accessibility) Test that closing the popup fires an activedescendant
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index ccf243a..546ff0d 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -230,18 +230,23 @@
     // any cached values get updated prior to the selection change.
     EmitTextChangedAccessiblityEvent();
 
-    // Send accessibility event on the popup box that its selection has changed.
-    EmitSelectedChildrenChangedAccessibilityEvent();
+    auto selection_state = popup_contents_view_->model()->selection().state;
 
     // The text is also accessible via text/value change events in the omnibox
     // but this selection event allows the screen reader to get more details
     // about the list and the user's position within it.
-    popup_contents_view_->FireAXEventsForNewActiveDescendant(this);
+    // Limit which selection states fire the events, in order to avoid duplicate
+    // events. Specifically, OmniboxPopupContentsView::ProvideButtonFocusHint()
+    // already fires the correct events when the user tabs to an attached button
+    // in the current row.
+    if (selection_state == OmniboxPopupModel::FOCUSED_BUTTON_HEADER ||
+        selection_state == OmniboxPopupModel::NORMAL) {
+      popup_contents_view_->FireAXEventsForNewActiveDescendant(this);
+    }
 
     // TODO(orinj): Eventually the deep digging in this class should get
     //  replaced with a single local point of access to all selection state.
-    ShowKeyword(popup_contents_view_->model()->selection().state ==
-                OmniboxPopupModel::KEYWORD_MODE);
+    ShowKeyword(selection_state == OmniboxPopupModel::KEYWORD_MODE);
   } else {
     ShowKeyword(false);
   }
@@ -442,21 +447,27 @@
   // TODO(tommycli): We re-fetch the original match from the popup model,
   // because |match_| already has its contents and description swapped by this
   // class, and we don't want that for the bubble. We should improve this.
-  if (model_index_ < popup_contents_view_->model()->result().size()) {
-    AutocompleteMatch raw_match =
-        popup_contents_view_->model()->result().match_at(model_index_);
-    node_data->SetName(AutocompleteMatchType::ToAccessibilityLabel(
-        raw_match, raw_match.contents));
+  bool is_selected = IsMatchSelected();
+  OmniboxPopupModel* model = popup_contents_view_->model();
+  if (model_index_ < model->result().size()) {
+    AutocompleteMatch raw_match = model->result().match_at(model_index_);
+    // The selected match can have a special name, e.g. when is one or more
+    // buttons that can be tabbed to.
+    base::string16 label =
+        is_selected ? model->GetAccessibilityLabelForCurrentSelection(
+                          raw_match.contents, false)
+                    : AutocompleteMatchType::ToAccessibilityLabel(
+                          raw_match, raw_match.contents);
+    node_data->SetName(label);
   }
 
   node_data->role = ax::mojom::Role::kListBoxOption;
   node_data->AddIntAttribute(ax::mojom::IntAttribute::kPosInSet,
                              model_index_ + 1);
   node_data->AddIntAttribute(ax::mojom::IntAttribute::kSetSize,
-                             popup_contents_view_->model()->result().size());
+                             model->result().size());
 
-  node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected,
-                              IsMatchSelected());
+  node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, is_selected);
   if (IsMouseHovered())
     node_data->AddState(ax::mojom::State::kHovered);
 }
@@ -489,19 +500,16 @@
   // The omnibox results list reuses the same items, but the text displayed for
   // these items is updated as the value of omnibox changes. The displayed text
   // for a given item is exposed to screen readers as the item's name/label.
+  ui::AXNodeData node_data;
+  GetAccessibleNodeData(&node_data);
   base::string16 current_name =
-      AutocompleteMatchType::ToAccessibilityLabel(match_, match_.contents);
+      node_data.GetString16Attribute(ax::mojom::StringAttribute::kName);
   if (accessible_name_ != current_name) {
     NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
     accessible_name_ = current_name;
   }
 }
 
-void OmniboxResultView::EmitSelectedChildrenChangedAccessibilityEvent() {
-  popup_contents_view_->NotifyAccessibilityEvent(
-      ax::mojom::Event::kSelectedChildrenChanged, true);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // OmniboxResultView, private:
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
index 5458d56..7f3dad4 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -92,7 +92,6 @@
 
   // Helper to emit accessibility events (may only emit if conditions are met).
   void EmitTextChangedAccessiblityEvent();
-  void EmitSelectedChildrenChangedAccessibilityEvent();
 
   // views::View:
   void Layout() override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
index 99ed55ab..e628a3c 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
@@ -29,10 +29,21 @@
 class OmniboxSuggestionRowButton : public views::MdTextButton {
  public:
   OmniboxSuggestionRowButton(views::ButtonListener* listener,
-                             const base::string16& text)
-      : MdTextButton(listener, CONTEXT_OMNIBOX_PRIMARY) {
+                             const base::string16& text,
+                             const gfx::VectorIcon& icon,
+                             const views::FocusRing::ViewPredicate& predicate)
+      : MdTextButton(listener, CONTEXT_OMNIBOX_PRIMARY), icon_(icon) {
     SetText(text);
+    views::InstallPillHighlightPathGenerator(this);
+    SetImageLabelSpacing(ChromeLayoutProvider::Get()->GetDistanceMetric(
+        DISTANCE_RELATED_LABEL_HORIZONTAL_LIST));
+    SetCustomPadding(ChromeLayoutProvider::Get()->GetInsetsMetric(
+        INSETS_OMNIBOX_PILL_BUTTON));
+    SetCornerRadius(GetInsets().height() +
+                    GetLayoutConstant(LOCATION_BAR_ICON_SIZE));
+
     set_ink_drop_highlight_opacity(CalculateInkDropHighlightOpacity());
+    focus_ring()->SetHasFocusPredicate(predicate);
   }
 
   OmniboxSuggestionRowButton(const OmniboxSuggestionRowButton&) = delete;
@@ -45,6 +56,8 @@
     return color_utils::GetColorWithMaxContrast(background()->get_color());
   }
 
+  void OnStyleRefresh() { focus_ring()->SchedulePaint(); }
+
   std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
       const override {
     // MdTextButton uses custom colors when creating ink drop highlight.
@@ -53,7 +66,19 @@
     return views::InkDropHostView::CreateInkDropHighlight();
   }
 
+  void OnThemeChanged() override {
+    MdTextButton::OnThemeChanged();
+    SkColor color =
+        GetOmniboxColor(GetThemeProvider(), OmniboxPart::RESULTS_ICON,
+                        OmniboxPartState::NORMAL);
+    SetImage(views::Button::STATE_NORMAL,
+             gfx::CreateVectorIcon(
+                 icon_, GetLayoutConstant(LOCATION_BAR_ICON_SIZE), color));
+  }
+
  private:
+  const gfx::VectorIcon& icon_;
+
   float CalculateInkDropHighlightOpacity() {
     // Ink drop highlight opacity is result of mixing a layer with hovered
     // opacity and a layer with selected opacity. OmniboxPartState::SELECTED
@@ -70,19 +95,13 @@
 
 OmniboxSuggestionRowButton* CreatePillButton(
     OmniboxSuggestionButtonRowView* button_row,
-    const char* message) {
+    const char* message,
+    const gfx::VectorIcon& icon,
+    const views::FocusRing::ViewPredicate& predicate) {
   OmniboxSuggestionRowButton* button =
       button_row->AddChildView(std::make_unique<OmniboxSuggestionRowButton>(
-          button_row, base::ASCIIToUTF16(message)));
+          button_row, base::ASCIIToUTF16(message), icon, predicate));
   button->SetVisible(false);
-  button->SetImageLabelSpacing(ChromeLayoutProvider::Get()->GetDistanceMetric(
-      DISTANCE_RELATED_LABEL_HORIZONTAL_LIST));
-  button->SetCustomPadding(
-      ChromeLayoutProvider::Get()->GetInsetsMetric(INSETS_OMNIBOX_PILL_BUTTON));
-  button->SetCornerRadius(button->GetInsets().height() +
-                          GetLayoutConstant(LOCATION_BAR_ICON_SIZE));
-  views::HighlightPathGenerator::Install(
-      button, std::make_unique<views::PillHighlightPathGenerator>());
   return button;
 }
 
@@ -105,11 +124,6 @@
           gfx::Insets(0, ChromeLayoutProvider::Get()->GetDistanceMetric(
                              views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
 
-  // TODO(orinj): Use the real translated string table values here instead.
-  keyword_button_ = CreatePillButton(this, "Keyword search");
-  pedal_button_ = CreatePillButton(this, "Pedal");
-  tab_switch_button_ = CreatePillButton(this, "Switch to this tab");
-
   const auto make_predicate = [=](auto state) {
     return [=](View* view) {
       return view->GetVisible() &&
@@ -117,14 +131,16 @@
                  OmniboxPopupModel::Selection(model_index_, state);
     };
   };
-  keyword_button_focus_ring_ = views::FocusRing::Install(keyword_button_);
-  keyword_button_focus_ring_->SetHasFocusPredicate(
+
+  // TODO(orinj): Use the real translated string table values here instead.
+  keyword_button_ = CreatePillButton(
+      this, "Keyword search", vector_icons::kSearchIcon,
       make_predicate(OmniboxPopupModel::FOCUSED_BUTTON_KEYWORD));
-  pedal_button_focus_ring_ = views::FocusRing::Install(pedal_button_);
-  pedal_button_focus_ring_->SetHasFocusPredicate(
-      make_predicate(OmniboxPopupModel::FOCUSED_BUTTON_PEDAL));
-  tab_switch_button_focus_ring_ = views::FocusRing::Install(tab_switch_button_);
-  tab_switch_button_focus_ring_->SetHasFocusPredicate(
+  pedal_button_ =
+      CreatePillButton(this, "Pedal", omnibox::kProductIcon,
+                       make_predicate(OmniboxPopupModel::FOCUSED_BUTTON_PEDAL));
+  tab_switch_button_ = CreatePillButton(
+      this, "Switch to this tab", omnibox::kSwitchIcon,
       make_predicate(OmniboxPopupModel::FOCUSED_BUTTON_TAB_SWITCH));
 }
 
@@ -163,26 +179,9 @@
 }
 
 void OmniboxSuggestionButtonRowView::OnStyleRefresh() {
-  keyword_button_focus_ring_->SchedulePaint();
-  pedal_button_focus_ring_->SchedulePaint();
-  tab_switch_button_focus_ring_->SchedulePaint();
-}
-
-void OmniboxSuggestionButtonRowView::OnThemeChanged() {
-  View::OnThemeChanged();
-  SkColor color = GetOmniboxColor(GetThemeProvider(), OmniboxPart::RESULTS_ICON,
-                                  OmniboxPartState::NORMAL);
-  const int icon_size = GetLayoutConstant(LOCATION_BAR_ICON_SIZE);
-
-  keyword_button_->SetImage(
-      views::Button::STATE_NORMAL,
-      gfx::CreateVectorIcon(vector_icons::kSearchIcon, icon_size, color));
-  pedal_button_->SetImage(
-      views::Button::STATE_NORMAL,
-      gfx::CreateVectorIcon(omnibox::kProductIcon, icon_size, color));
-  tab_switch_button_->SetImage(
-      views::Button::STATE_NORMAL,
-      gfx::CreateVectorIcon(omnibox::kSwitchIcon, icon_size, color));
+  keyword_button_->OnStyleRefresh();
+  pedal_button_->OnStyleRefresh();
+  tab_switch_button_->OnStyleRefresh();
 }
 
 void OmniboxSuggestionButtonRowView::ButtonPressed(views::Button* button,
@@ -229,7 +228,7 @@
 }
 
 void OmniboxSuggestionButtonRowView::SetPillButtonVisibility(
-    views::MdTextButton* button,
+    OmniboxSuggestionRowButton* button,
     OmniboxPopupModel::LineState state) {
   button->SetVisible(model()->IsControlPresentOnMatch(
       OmniboxPopupModel::Selection(model_index_, state)));
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.h b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.h
index 7cf4c5d..0604377 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.h
@@ -32,9 +32,6 @@
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
-  // views::View:
-  void OnThemeChanged() override;
-
  private:
   // Get the popup model from the view.
   const OmniboxPopupModel* model() const;
@@ -42,7 +39,7 @@
   // Digs into the model with index to get the match for owning result view.
   const AutocompleteMatch& match() const;
 
-  void SetPillButtonVisibility(views::MdTextButton* button,
+  void SetPillButtonVisibility(OmniboxSuggestionRowButton* button,
                                OmniboxPopupModel::LineState state);
 
   OmniboxPopupContentsView* const popup_contents_view_;
@@ -51,9 +48,6 @@
   OmniboxSuggestionRowButton* keyword_button_ = nullptr;
   OmniboxSuggestionRowButton* pedal_button_ = nullptr;
   OmniboxSuggestionRowButton* tab_switch_button_ = nullptr;
-  views::FocusRing* keyword_button_focus_ring_ = nullptr;
-  views::FocusRing* pedal_button_focus_ring_ = nullptr;
-  views::FocusRing* tab_switch_button_focus_ring_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(OmniboxSuggestionButtonRowView);
 };
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 0deb0d7..b675d14 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -10,6 +10,7 @@
 #include "base/check_op.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
+#include "base/i18n/rtl.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
@@ -225,11 +226,20 @@
   elide_to_rect_.set_y(elide_from_rect_.y());
   elide_to_rect_.set_height(elide_from_rect_.height());
 
+  // There is nothing to animate in this case, so return without starting.
+  if (elide_from_rect_ == elide_to_rect_ && starting_color_ == ending_color_)
+    return;
+
   starting_display_offset_ = render_text_->GetUpdatedDisplayOffset().x();
   // Shift the text to where |elide_to_bounds| starts, relative to the current
   // display rect.
-  ending_display_offset_ =
-      starting_display_offset_ - (elide_to_rect_.x() - elide_from_rect_.x());
+  if (base::i18n::IsRTL()) {
+    ending_display_offset_ = starting_display_offset_ +
+                             elide_from_rect_.right() - elide_to_rect_.right();
+  } else {
+    ending_display_offset_ =
+        starting_display_offset_ - (elide_to_rect_.x() - elide_from_rect_.x());
+  }
 
   animation_->Start();
 }
@@ -278,8 +288,10 @@
       animation->GetCurrentValue(), elide_from_rect_, elide_to_rect_);
   DCHECK_EQ(bounds.y(), old_bounds.y());
   DCHECK_EQ(bounds.height(), old_bounds.height());
-  gfx::Rect shifted_bounds(old_bounds.x(), old_bounds.y(), bounds.width(),
-                           old_bounds.height());
+  gfx::Rect shifted_bounds(base::i18n::IsRTL()
+                               ? old_bounds.right() - bounds.width()
+                               : old_bounds.x(),
+                           old_bounds.y(), bounds.width(), old_bounds.height());
   render_text_->SetDisplayRect(shifted_bounds);
   current_offset_ = gfx::Tween::IntValueBetween(animation->GetCurrentValue(),
                                                 starting_display_offset_,
@@ -290,6 +302,13 @@
     view_->ApplyColor(GetCurrentColor(), range);
   }
 
+  // TODO(crbug.com/1101472): The smoothing gradient mask is not yet implemented
+  // correctly for RTL UI.
+  if (base::i18n::IsRTL()) {
+    view_->SchedulePaint();
+    return;
+  }
+
   // The gradient mask should be a fixed width, except if that width would
   // cause it to mask the unelided section. In that case we set it to the
   // maximum width possible that won't cover the unelided section.
@@ -916,7 +935,11 @@
     bool notify_text_changed) {
   if (save_original_selection)
     saved_temporary_selection_ = GetRenderText()->GetAllSelections();
-  SetAccessibilityLabel(display_text, match);
+
+  // SetWindowTextAndCaretPos will fire the acesssibility notification,
+  // so do not also generate redundant notification here.
+  SetAccessibilityLabel(display_text, match, false);
+
   SetWindowTextAndCaretPos(display_text, display_text.length(), false,
                            notify_text_changed);
   SetAdditionalText(match.fill_into_edit_additional_text);
@@ -951,16 +974,14 @@
 
 void OmniboxViewViews::OnRevertTemporaryText(const base::string16& display_text,
                                              const AutocompleteMatch& match) {
-  SetAccessibilityLabel(display_text, match);
-  SetSelectedRanges(saved_temporary_selection_);
-
   // We got here because the user hit the Escape key. We explicitly don't call
   // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
   // been called by now, and it would've called TextChanged() if it was
   // warranted.
   // However, it's important to notify accessibility that the value has changed,
   // otherwise the screen reader will use the old accessibility label text.
-  NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
+  SetAccessibilityLabel(display_text, match, true);
+  SetSelectedRanges(saved_temporary_selection_);
 }
 
 void OmniboxViewViews::ClearAccessibilityLabel() {
@@ -972,7 +993,8 @@
 }
 
 void OmniboxViewViews::SetAccessibilityLabel(const base::string16& display_text,
-                                             const AutocompleteMatch& match) {
+                                             const AutocompleteMatch& match,
+                                             bool notify_text_changed) {
   if (model()->popup_model()->selected_line() == OmniboxPopupModel::kNoMatch) {
     // If nothing is selected in the popup, we are in the no-default-match edge
     // case, and |match| is a synthetically generated match. In that case,
@@ -983,9 +1005,12 @@
   } else {
     friendly_suggestion_text_ =
         model()->popup_model()->GetAccessibilityLabelForCurrentSelection(
-            display_text, &friendly_suggestion_text_prefix_length_);
+            display_text, true, &friendly_suggestion_text_prefix_length_);
   }
 
+  if (notify_text_changed)
+    NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
+
 #if defined(OS_MAC)
   // On macOS, the only way to get VoiceOver to speak the friendly suggestion
   // text (for example, "how to open a pdf, search suggestion, 4 of 8") is
@@ -2477,22 +2502,37 @@
   }
 
   // |simplified_domain_rect| gives us the current bounds of the simplified
-  // domain substring. We shift it to the leftmost edge of the omnibox (as
-  // determined by the x position of the current display rect), and then scroll
-  // to where the simplified domain begins, so that the simplified domain
-  // appears at the leftmost edge.
+  // domain substring. We shift it to the leftmost (rightmost if UI is RTL) edge
+  // of the omnibox (as determined by the x position of the current display
+  // rect), and then scroll to where the simplified domain begins, so that the
+  // simplified domain appears at the leftmost/rightmost edge.
   gfx::Rect old_bounds = GetRenderText()->display_rect();
+  int shifted_simplified_domain_x_pos;
+  // The x position of the elided domain will depend on whether the UI is LTR or
+  // RTL.
+  if (base::i18n::IsRTL()) {
+    shifted_simplified_domain_x_pos =
+        old_bounds.right() - simplified_domain_rect.width();
+  } else {
+    shifted_simplified_domain_x_pos = old_bounds.x();
+  }
   // Use |old_bounds| for y and height values because the URL should never shift
   // vertically while eliding to/from simplified domain.
-  gfx::Rect shifted_simplified_domain_rect(old_bounds.x(), old_bounds.y(),
-                                           simplified_domain_rect.width(),
-                                           old_bounds.height());
+  gfx::Rect shifted_simplified_domain_rect(
+      shifted_simplified_domain_x_pos, old_bounds.y(),
+      simplified_domain_rect.width(), old_bounds.height());
   GetRenderText()->SetDisplayRect(shifted_simplified_domain_rect);
   // Scroll the text to where the simplified domain begins, relative to the
-  // leftmost edge of the current display rect.
-  GetRenderText()->SetDisplayOffset(
-      GetRenderText()->GetUpdatedDisplayOffset().x() -
-      (simplified_domain_rect.x() - old_bounds.x()));
+  // leftmost (rightmost if UI is RTL) edge of the current display rect.
+  if (base::i18n::IsRTL()) {
+    GetRenderText()->SetDisplayOffset(
+        GetRenderText()->GetUpdatedDisplayOffset().x() + old_bounds.right() -
+        simplified_domain_rect.right());
+  } else {
+    GetRenderText()->SetDisplayOffset(
+        GetRenderText()->GetUpdatedDisplayOffset().x() -
+        (simplified_domain_rect.x() - old_bounds.x()));
+  }
 
   // GetSubstringBounds() rounds outward internally, so there may be small
   // portions of text still showing. Set the ranges surrounding the simplified
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
index 1fa2082..729d9c8 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -219,6 +219,8 @@
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag);
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel);
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, DoNotNavigateOnDrop);
+  FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest,
+                           ElideAnimationDoesntStartIfNoVisibleChange);
 
   // Animates the URL to a given range of text, which could be a substring or
   // superstring of what's currently displayed. An elision animation hides the
@@ -348,7 +350,8 @@
   void ClearAccessibilityLabel();
 
   void SetAccessibilityLabel(const base::string16& display_text,
-                             const AutocompleteMatch& match) override;
+                             const AutocompleteMatch& match,
+                             bool notify_text_changed) override;
 
   // Returns true if the user text was updated with the full URL (without
   // steady-state elisions).  |gesture| is the user gesture causing unelision.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
index c5c771f..46799fe 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/i18n/rtl.h"
 #include "base/macros.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_tick_clock.h"
@@ -229,6 +230,13 @@
   DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController);
 };
 
+// TODO(crbug.com/1112536): With RTL UI, the URL is sometimes off by one pixel
+// of the right edge. Investigate if this is expected, otherwise replace this
+// with equality checks in tests that use it. Checks |a| is within 1 of |b|.
+void CheckEqualsWithMarginOne(int a, int b) {
+  EXPECT_LE(std::abs(a - b), 1);
+}
+
 }  // namespace
 
 // OmniboxViewViewsTest -------------------------------------------------------
@@ -236,10 +244,11 @@
 // Base class that ensures ScopedFeatureList is initialized first.
 class OmniboxViewViewsTestBase : public ChromeViewsTestBase {
  public:
-  OmniboxViewViewsTestBase(
-      const std::vector<base::Feature>& enabled_features,
-      const std::vector<base::Feature>& disabled_features) {
+  OmniboxViewViewsTestBase(const std::vector<base::Feature>& enabled_features,
+                           const std::vector<base::Feature>& disabled_features,
+                           bool is_rtl_ui_test = false) {
     scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
+    base::i18n::SetRTLForTesting(is_rtl_ui_test);
   }
 
  protected:
@@ -263,7 +272,8 @@
 class OmniboxViewViewsTest : public OmniboxViewViewsTestBase {
  public:
   OmniboxViewViewsTest(const std::vector<base::Feature>& enabled_features,
-                       const std::vector<base::Feature>& disabled_features);
+                       const std::vector<base::Feature>& disabled_features,
+                       bool is_rtl_ui_test = false);
 
   OmniboxViewViewsTest()
       : OmniboxViewViewsTest(std::vector<base::Feature>(),
@@ -342,8 +352,11 @@
 
 OmniboxViewViewsTest::OmniboxViewViewsTest(
     const std::vector<base::Feature>& enabled_features,
-    const std::vector<base::Feature>& disabled_features)
-    : OmniboxViewViewsTestBase(enabled_features, disabled_features),
+    const std::vector<base::Feature>& disabled_features,
+    bool is_rtl_ui_test)
+    : OmniboxViewViewsTestBase(enabled_features,
+                               disabled_features,
+                               is_rtl_ui_test),
       command_updater_(nullptr),
       omnibox_edit_controller_(&command_updater_, &location_bar_model_) {}
 
@@ -831,6 +844,30 @@
   EXPECT_FALSE(omnibox_view()->IsSelectAll());
 }
 
+TEST_F(OmniboxViewViewsTest, ElideAnimationDoesntStartIfNoVisibleChange) {
+  SetUpSimplifiedDomainTest();
+  gfx::RenderText* render_text = omnibox_view()->GetRenderText();
+  OmniboxViewViews::ElideAnimation elide_animation(omnibox_view(), render_text);
+  // Before any animation runs, the elide from rectangle is considered to be
+  // render_text's DisplayRect, so set it manually to be the current URL length.
+  gfx::Rect full_url_bounds;
+  for (auto rect : render_text->GetSubstringBounds(
+           gfx::Range(0, omnibox_view()->GetOmniboxTextLength()))) {
+    full_url_bounds.Union(rect);
+  }
+  render_text->SetDisplayRect(full_url_bounds);
+  // Start the animation, and have it animate to the current state.
+  elide_animation.Start(
+      gfx::Range(0,
+                 omnibox_view()->GetOmniboxTextLength()), /* elide_to_bounds */
+      0,                                                  /* delay_ms */
+      {gfx::Range(0, 0)}, /* ranges_surrounding_simplified_domain */
+      SK_ColorBLACK,      /* starting_color */
+      SK_ColorBLACK);     /* ending_color */
+  // Animation shouldn't have been started.
+  EXPECT_FALSE(elide_animation.IsAnimating());
+}
+
 class OmniboxViewViewsClipboardTest
     : public OmniboxViewViewsTest,
       public ::testing::WithParamInterface<ui::TextEditCommand> {
@@ -1451,8 +1488,15 @@
     // is because GetSubstringBounds() rounds outward, so the width of
     // |subdomain_and_scheme_rect| could slightly overlap
     // |registrable_domain_rect|.
-    EXPECT_EQ(registrable_domain_rect.x() - subdomain_and_scheme_rect.x(),
-              -1 * render_text->GetUpdatedDisplayOffset().x());
+    // In the RTL UI case, the offset instead has to push the path offscreen to
+    // the right, so we check offset equals the width of the path rectangle.
+    if (base::i18n::IsRTL()) {
+      CheckEqualsWithMarginOne(path_rect.width(),
+                               render_text->GetUpdatedDisplayOffset().x());
+    } else {
+      EXPECT_EQ(registrable_domain_rect.x() - subdomain_and_scheme_rect.x(),
+                -1 * render_text->GetUpdatedDisplayOffset().x());
+    }
     // The scheme and subdomain should be transparent.
     EXPECT_EQ(SK_ColorTRANSPARENT, view->GetLatestColorForRange(gfx::Range(
                                        0, scheme.size() + subdomain.size())));
@@ -1470,8 +1514,15 @@
     // text starts at the subdomain. As above, it's important to compute the
     // expected offset with x() values instead of width()s, since the width()s
     // of different adjacent substring bounds could overlap.
-    EXPECT_EQ(hostname_rect.x() - subdomain_and_scheme_rect.x(),
-              -1 * render_text->GetUpdatedDisplayOffset().x());
+    // In the RTL UI case, the offset instead has to push the path offscreen to
+    // the right, so we check offset equals the width of the path rectangle.
+    if (base::i18n::IsRTL()) {
+      CheckEqualsWithMarginOne(path_rect.width(),
+                               render_text->GetUpdatedDisplayOffset().x());
+    } else {
+      EXPECT_EQ(hostname_rect.x() - subdomain_and_scheme_rect.x(),
+                -1 * render_text->GetUpdatedDisplayOffset().x());
+    }
     // The scheme should be transparent.
     EXPECT_EQ(SK_ColorTRANSPARENT,
               view->GetLatestColorForRange(gfx::Range(0, scheme.size())));
@@ -1493,8 +1544,14 @@
   }
   EXPECT_TRUE(render_text->display_rect().Contains(unelided_rect));
   // |display_url| should be at the leading edge of |render_text|'s display
-  // rect.
-  EXPECT_EQ(unelided_rect.x(), render_text->display_rect().x());
+  // rect for LTR UI, or at the rightmost side of the omnibox for RTL UI.
+  if (base::i18n::IsRTL()) {
+    CheckEqualsWithMarginOne(
+        unelided_rect.x(),
+        render_text->display_rect().right() - unelided_rect.width());
+  } else {
+    EXPECT_EQ(unelided_rect.x(), render_text->display_rect().x());
+  }
 }
 
 // Returns true if |render_text|'s current display rect and offset display at
@@ -1548,17 +1605,18 @@
 
 class OmniboxViewViewsRevealOnHoverTest
     : public OmniboxViewViewsTest,
-      public ::testing::WithParamInterface<bool> {
+      public ::testing::WithParamInterface<std::pair<bool, bool>> {
  public:
   OmniboxViewViewsRevealOnHoverTest()
       : OmniboxViewViewsTest(
-            GetParam()
+            GetParam().first
                 ? std::vector<base::Feature>(
                       {omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover,
                        omnibox::kElideToRegistrableDomain})
                 : std::vector<base::Feature>(
                       {omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover}),
-            {}) {}
+            {},
+            GetParam().second) {}
 
   OmniboxViewViewsRevealOnHoverTest(const OmniboxViewViewsRevealOnHoverTest&) =
       delete;
@@ -1566,12 +1624,15 @@
       const OmniboxViewViewsRevealOnHoverTest&) = delete;
 
  protected:
-  bool ShouldElideToRegistrableDomain() { return GetParam(); }
+  bool ShouldElideToRegistrableDomain() { return GetParam().first; }
 };
 
 INSTANTIATE_TEST_SUITE_P(OmniboxViewViewsRevealOnHoverTest,
                          OmniboxViewViewsRevealOnHoverTest,
-                         ::testing::Values(true, false));
+                         ::testing::ValuesIn({std::make_pair(true, false),
+                                              std::make_pair(false, false),
+                                              std::make_pair(true, true),
+                                              std::make_pair(false, true)}));
 
 // Tests the field trial variation that shows a simplified domain by default and
 // reveals the unsimplified URL on hover.
@@ -1644,11 +1705,11 @@
 
 class OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest
     : public OmniboxViewViewsTest,
-      public ::testing::WithParamInterface<bool> {
+      public ::testing::WithParamInterface<std::pair<bool, bool>> {
  public:
   OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest()
       : OmniboxViewViewsTest(
-            GetParam()
+            GetParam().first
                 ? std::vector<base::Feature>(
                       {omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover,
                        omnibox::kHideSteadyStateUrlPathQueryAndRefOnInteraction,
@@ -1657,7 +1718,8 @@
                       {omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover,
                        omnibox::
                            kHideSteadyStateUrlPathQueryAndRefOnInteraction}),
-            {}) {}
+            {},
+            GetParam().second) {}
 
   OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest(
       const OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest&) = delete;
@@ -1665,12 +1727,15 @@
       const OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest&) = delete;
 
  protected:
-  bool ShouldElideToRegistrableDomain() { return GetParam(); }
+  bool ShouldElideToRegistrableDomain() { return GetParam().first; }
 };
 
 INSTANTIATE_TEST_SUITE_P(OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest,
                          OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest,
-                         ::testing::Values(true, false));
+                         ::testing::ValuesIn({std::make_pair(true, false),
+                                              std::make_pair(false, false),
+                                              std::make_pair(true, true),
+                                              std::make_pair(false, true)}));
 
 // Tests the field trial variation that shows the simplified domain when the
 // user interacts with the page and brings back the URL when the user hovers
@@ -1959,30 +2024,34 @@
 
 class OmniboxViewViewsHideOnInteractionTest
     : public OmniboxViewViewsTest,
-      public ::testing::WithParamInterface<bool> {
+      public ::testing::WithParamInterface<std::pair<bool, bool>> {
  public:
   OmniboxViewViewsHideOnInteractionTest()
       : OmniboxViewViewsTest(
-            GetParam()
+            GetParam().first
                 ? std::vector<base::Feature>(
                       {omnibox::kHideSteadyStateUrlPathQueryAndRefOnInteraction,
                        omnibox::kElideToRegistrableDomain})
                 : std::vector<base::Feature>(
                       {omnibox::
                            kHideSteadyStateUrlPathQueryAndRefOnInteraction}),
-            {}) {}
+            {},
+            GetParam().second) {}
   OmniboxViewViewsHideOnInteractionTest(
       const OmniboxViewViewsHideOnInteractionTest&) = delete;
   OmniboxViewViewsHideOnInteractionTest& operator=(
       const OmniboxViewViewsHideOnInteractionTest&) = delete;
 
  protected:
-  bool ShouldElideToRegistrableDomain() { return GetParam(); }
+  bool ShouldElideToRegistrableDomain() { return GetParam().first; }
 };
 
 INSTANTIATE_TEST_SUITE_P(OmniboxViewViewsHideOnInteractionTest,
                          OmniboxViewViewsHideOnInteractionTest,
-                         ::testing::Values(true, false));
+                         ::testing::ValuesIn({std::make_pair(true, false),
+                                              std::make_pair(false, false),
+                                              std::make_pair(true, true),
+                                              std::make_pair(false, true)}));
 
 // Tests the the "Always Show Full URLs" option works with the field trial
 // variation that shows a simplified domain when the user interacts with the
@@ -2042,11 +2111,11 @@
 // and the hide-on-interaction variation when the parameter is true.
 class OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest
     : public OmniboxViewViewsTest,
-      public ::testing::WithParamInterface<bool> {
+      public ::testing::WithParamInterface<std::pair<bool, bool>> {
  public:
   OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest()
       : OmniboxViewViewsTest(
-            GetParam()
+            GetParam().first
                 ? std::vector<base::Feature>(
                       {omnibox::kOmniboxContextMenuShowFullUrls,
                        omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover,
@@ -2055,7 +2124,8 @@
                 : std::vector<base::Feature>(
                       {omnibox::kOmniboxContextMenuShowFullUrls,
                        omnibox::kRevealSteadyStateUrlPathQueryAndRefOnHover}),
-            {omnibox::kElideToRegistrableDomain}) {}
+            {omnibox::kElideToRegistrableDomain},
+            GetParam().second) {}
 
   OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest(
       const OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest&) =
@@ -2065,13 +2135,16 @@
       delete;
 
  protected:
-  bool IsHideOnInteractionEnabled() { return GetParam(); }
+  bool IsHideOnInteractionEnabled() { return GetParam().first; }
 };
 
 INSTANTIATE_TEST_SUITE_P(
     OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest,
     OmniboxViewViewsRevealOnHoverAndMaybeHideOnInteractionTest,
-    ::testing::Values(true, false));
+    ::testing::ValuesIn({std::make_pair(true, false),
+                         std::make_pair(false, false),
+                         std::make_pair(true, true),
+                         std::make_pair(false, true)}));
 
 // Tests that unsetting the "Always show full URLs" option begins showing/hiding
 // the full URL appropriately when simplified domain field trials are enabled.
@@ -2141,6 +2214,11 @@
       omnibox_view()->GetHoverElideOrUnelideAnimationForTesting();
   ASSERT_TRUE(elide_animation);
   EXPECT_TRUE(elide_animation->IsAnimating());
+  // Advance the animation, so the visible URL changes.
+  gfx::AnimationContainerElement* elide_as_element =
+      elide_animation->GetAnimationForTesting();
+  elide_as_element->SetStartTime(base::TimeTicks());
+  elide_as_element->Step(base::TimeTicks() + base::TimeDelta::FromSeconds(1));
   omnibox_view()->OnMouseExited(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0}));
   elide_animation = omnibox_view()->GetHoverElideOrUnelideAnimationForTesting();
   ASSERT_TRUE(elide_animation);
@@ -2463,6 +2541,11 @@
 
 // Tests that gradient mask is set correctly.
 TEST_P(OmniboxViewViewsHideOnInteractionTest, GradientMask) {
+  if (base::i18n::IsRTL()) {
+    // TODO(crbug.com/1101472): Re-enable this test once gradient mask is
+    // implemented for RTL UI.
+    return;
+  }
   SetUpSimplifiedDomainTest();
   gfx::RenderText* render_text = omnibox_view()->GetRenderText();
 
@@ -2493,7 +2576,7 @@
   }
   // If we are eliding from the left, the other side gradient should also be
   // full size at this point, otherwise it should be 0.
-  if (GetParam()) {
+  if (ShouldElideToRegistrableDomain()) {
     EXPECT_EQ(omnibox_view()->elide_animation_smoothing_rect_left_.width(),
               max_gradient_width);
   } else {
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
index 0d20e4a..2b75bda 100644
--- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -429,7 +429,8 @@
     All,
     SafetyTipPageInfoBubbleViewBrowserTest,
     ::testing::Values(UIStatus::kDisabled,
-                      UIStatus::kEnabledWithDefaultFeatures,
+                      // Disabled for flakiness. https://crbug.com/1113105.
+                      // UIStatus::kEnabledWithDefaultFeatures,
                       UIStatus::kEnabledWithSuspiciousSites,
                       UIStatus::kEnabledWithAllFeatures));
 
diff --git a/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc b/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
index 8c98940..2f060a1 100644
--- a/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
+++ b/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
@@ -509,7 +509,7 @@
       policies.Set(policy::key::kClickToCallEnabled,
                    policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                    policy::POLICY_SOURCE_ENTERPRISE_DEFAULT,
-                   std::make_unique<base::Value>(policy_bool), nullptr);
+                   base::Value(policy_bool), nullptr);
     }
 
     provider_.UpdateChromePolicy(policies);
diff --git a/chrome/browser/ui/webauthn/transport_utils.cc b/chrome/browser/ui/webauthn/transport_utils.cc
index 4701295..46f979a 100644
--- a/chrome/browser/ui/webauthn/transport_utils.cc
+++ b/chrome/browser/ui/webauthn/transport_utils.cc
@@ -28,6 +28,8 @@
       return IDS_WEBAUTHN_TRANSPORT_INTERNAL;
     case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy:
       return IDS_WEBAUTHN_TRANSPORT_CABLE;
+    case AuthenticatorTransport::kAndroidAccessory:
+      return IDS_WEBAUTHN_TRANSPORT_USB;
   }
   NOTREACHED();
   return 0;
@@ -48,6 +50,8 @@
       return IDS_WEBAUTHN_TRANSPORT_POPUP_INTERNAL;
     case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy:
       return IDS_WEBAUTHN_TRANSPORT_POPUP_CABLE;
+    case AuthenticatorTransport::kAndroidAccessory:
+      return IDS_WEBAUTHN_TRANSPORT_POPUP_USB;
   }
   NOTREACHED();
   return 0;
@@ -81,6 +85,8 @@
       return &kFingerprintIcon;
     case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy:
       return &kSmartphoneIcon;
+    case AuthenticatorTransport::kAndroidAccessory:
+      return &kSmartphoneIcon;
   }
   NOTREACHED();
   return &kFingerprintIcon;
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
index 3040f27..3f17f0c 100644
--- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -89,8 +89,7 @@
   builder->Add("back", IDS_EULA_BACK_BUTTON);
   builder->Add("next", IDS_EULA_NEXT_BUTTON);
   builder->Add("acceptAgreement", IDS_EULA_ACCEPT_AND_CONTINUE_BUTTON);
-  builder->Add("eulaSystemInstallationSettings",
-               IDS_EULA_SYSTEM_SECURITY_SETTING);
+  builder->Add("eulaSystemSecuritySettings", IDS_EULA_SYSTEM_SECURITY_SETTING);
 
   builder->Add("eulaTpmDesc", IDS_EULA_SECURE_MODULE_DESCRIPTION);
   builder->Add("eulaTpmKeyDesc", IDS_EULA_SECURE_MODULE_KEY_DESCRIPTION);
@@ -100,7 +99,7 @@
   ::login::GetSecureModuleUsed(base::BindOnce(
       &EulaScreenHandler::UpdateLocalizedValues, weak_factory_.GetWeakPtr()));
 
-  builder->Add("eulaSystemInstallationSettingsOkButton", IDS_OK);
+  builder->Add("eulaSystemSecuritySettingsOkButton", IDS_OK);
   builder->Add("termsOfServiceLoading", IDS_TERMS_OF_SERVICE_SCREEN_LOADING);
 #if BUILDFLAG(ENABLE_RLZ)
   builder->AddF("eulaRlzDesc",
@@ -124,14 +123,6 @@
                IDS_OOBE_EULA_ACCEPT_AND_CONTINUE_BUTTON_TEXT);
 }
 
-void EulaScreenHandler::DeclareJSCallbacks() {
-  AddCallback("eulaOnLearnMore", &EulaScreenHandler::HandleOnLearnMore);
-  AddCallback("eulaOnInstallationSettingsPopupOpened",
-              &EulaScreenHandler::HandleOnInstallationSettingsPopupOpened);
-  AddCallback("EulaScreen.usageStatsEnabled",
-              &EulaScreenHandler::HandleUsageStatsEnabled);
-}
-
 void EulaScreenHandler::GetAdditionalParameters(base::DictionaryValue* dict) {
 #if BUILDFLAG(ENABLE_RLZ)
   dict->SetString("rlzEnabled", "enabled");
@@ -154,23 +145,18 @@
 
 void EulaScreenHandler::OnPasswordFetched(const std::string& tpm_password) {
   CallJS("login.EulaScreen.setTpmPassword", tpm_password);
+  CallJS("login.EulaScreen.showSecuritySettingsDialog");
 }
 
-void EulaScreenHandler::HandleOnLearnMore() {
+void EulaScreenHandler::ShowStatsUsageLearnMore() {
   if (!help_app_.get())
     help_app_ = new HelpAppLauncher(
         LoginDisplayHost::default_host()->GetNativeWindow());
   help_app_->ShowHelpTopic(HelpAppLauncher::HELP_STATS_USAGE);
 }
 
-void EulaScreenHandler::HandleOnInstallationSettingsPopupOpened() {
-  if (screen_)
-    screen_->InitiatePasswordFetch();
-}
-
-void EulaScreenHandler::HandleUsageStatsEnabled(bool enabled) {
-  if (screen_)
-    screen_->SetUsageStatsEnabled(enabled);
+void EulaScreenHandler::ShowAdditionalTosDialog() {
+  CallJS("login.EulaScreen.showAdditionalTosDialog");
 }
 
 void EulaScreenHandler::UpdateLocalizedValues(
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h
index e4dcb38..4d74615 100644
--- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h
@@ -26,7 +26,7 @@
 // dtor.
 class EulaView {
  public:
-  constexpr static StaticOobeScreenId kScreenId{"eula"};
+  constexpr static StaticOobeScreenId kScreenId{"oobe-eula-md"};
 
   virtual ~EulaView() {}
 
@@ -35,6 +35,8 @@
   virtual void Bind(EulaScreen* screen) = 0;
   virtual void Unbind() = 0;
   virtual void OnPasswordFetched(const std::string& tpm_password) = 0;
+  virtual void ShowStatsUsageLearnMore() = 0;
+  virtual void ShowAdditionalTosDialog() = 0;
 };
 
 // WebUI implementation of EulaScreenView. It is used to interact
@@ -53,20 +55,16 @@
   void Bind(EulaScreen* screen) override;
   void Unbind() override;
   void OnPasswordFetched(const std::string& tpm_password) override;
+  void ShowStatsUsageLearnMore() override;
+  void ShowAdditionalTosDialog() override;
 
   // BaseScreenHandler implementation:
   void DeclareLocalizedValues(
       ::login::LocalizedValuesBuilder* builder) override;
-  void DeclareJSCallbacks() override;
   void GetAdditionalParameters(base::DictionaryValue* dict) override;
   void Initialize() override;
 
  private:
-  // JS messages handlers.
-  void HandleOnLearnMore();
-  void HandleOnInstallationSettingsPopupOpened();
-  void HandleUsageStatsEnabled(bool enabled);
-
   // Determines the online URL to use.
   std::string GetEulaOnlineUrl();
   std::string GetAdditionalToSUrl();
@@ -76,12 +74,12 @@
   EulaScreen* screen_ = nullptr;
   CoreOobeView* core_oobe_view_ = nullptr;
 
-  // Help application used for help dialogs.
-  scoped_refptr<HelpAppLauncher> help_app_;
-
   // Keeps whether screen should be shown right after initialization.
   bool show_on_init_ = false;
 
+  // Help application used for help dialogs.
+  scoped_refptr<HelpAppLauncher> help_app_;
+
   base::WeakPtrFactory<EulaScreenHandler> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(EulaScreenHandler);
diff --git a/chrome/browser/ui/webui/managed_ui_handler_unittest.cc b/chrome/browser/ui/webui/managed_ui_handler_unittest.cc
index c165d33..cc1126a 100644
--- a/chrome/browser/ui/webui/managed_ui_handler_unittest.cc
+++ b/chrome/browser/ui/webui/managed_ui_handler_unittest.cc
@@ -104,7 +104,7 @@
   policy::PolicyMap non_empty_map;
   non_empty_map.Set("FakePolicyName", policy::POLICY_LEVEL_MANDATORY,
                     policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-                    std::make_unique<base::Value>("fake"), nullptr);
+                    base::Value("fake"), nullptr);
   policy_provider()->UpdateChromePolicy(non_empty_map);
 
   // Source should auto-update.
diff --git a/chrome/browser/ui/webui/management_ui_browsertest.cc b/chrome/browser/ui/webui/management_ui_browsertest.cc
index 961468b..806e9c1 100644
--- a/chrome/browser/ui/webui/management_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/management_ui_browsertest.cc
@@ -92,7 +92,7 @@
   policy::PolicyMap policy_map;
   policy_map.Set("test-policy", policy::POLICY_LEVEL_MANDATORY,
                  policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_PLATFORM,
-                 std::make_unique<base::Value>("hello world"), nullptr);
+                 base::Value("hello world"), nullptr);
   provider()->UpdateExtensionPolicy(policy_map,
                                     kOnPremReportingExtensionBetaId);
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc b/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
index d301f7a..36aee62 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
@@ -176,7 +176,7 @@
   // Sets a policy update which will cause power pref managed change.
   void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
                              const std::string& policy_key,
-                             std::unique_ptr<base::Value> value) {
+                             base::Value value) {
     policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
                     policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
                     std::move(value), nullptr);
@@ -224,21 +224,20 @@
   // Making an arbitrary AC delay pref managed should result in the AC idle
   // setting being reported as managed.
   SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayAC,
-                        std::make_unique<base::Value>(10000));
+                        base::Value(10000));
   DevicePowerSettings settings;
   settings.ac_idle_managed = true;
   EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
 
   // Ditto for battery delay pref managed.
   SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayBattery,
-                        std::make_unique<base::Value>(10000));
+                        base::Value(10000));
   settings.battery_idle_managed = true;
   EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
 
   // Ditto for making the lid action pref managed.
-  SetPolicyForPolicyKey(
-      &policy_map, policy::key::kLidCloseAction,
-      std::make_unique<base::Value>(PowerPolicyController::ACTION_SUSPEND));
+  SetPolicyForPolicyKey(&policy_map, policy::key::kLidCloseAction,
+                        base::Value(PowerPolicyController::ACTION_SUSPEND));
   settings.lid_closed_controlled = true;
   EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
 }
@@ -288,9 +287,9 @@
   // Set Enterpise policy that forces AC idle action to suspend. Only possible
   // AC idle option visible to the user should be DISPLAY_OFF_SLEEP and the
   // current should also be set to same.
-  SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionAC,
-                        std::make_unique<base::Value>(
-                            chromeos::PowerPolicyController::ACTION_SUSPEND));
+  SetPolicyForPolicyKey(
+      &policy_map, policy::key::kIdleActionAC,
+      base::Value(chromeos::PowerPolicyController::ACTION_SUSPEND));
   DevicePowerSettings settings;
   std::set<PowerHandler::IdleBehavior> behaviors;
   behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
@@ -301,9 +300,9 @@
   // Set Enterpise policy that forces battery idle action to Shutdown. Only
   // possible battery idle option visible to the user then should be OTHER and
   // the default should also be set to same.
-  SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionBattery,
-                        std::make_unique<base::Value>(
-                            chromeos::PowerPolicyController::ACTION_SHUT_DOWN));
+  SetPolicyForPolicyKey(
+      &policy_map, policy::key::kIdleActionBattery,
+      base::Value(chromeos::PowerPolicyController::ACTION_SHUT_DOWN));
   behaviors.clear();
   behaviors.insert(PowerHandler::IdleBehavior::OTHER);
   settings.possible_battery_behaviors = behaviors;
@@ -317,8 +316,7 @@
   // should not see DISPLAY_OFF_SLEEP in available options.
   SetPolicyForPolicyKey(
       &policy_map, policy::key::kIdleActionBattery,
-      std::make_unique<base::Value>(
-          chromeos::PowerPolicyController::ACTION_DO_NOTHING));
+      base::Value(chromeos::PowerPolicyController::ACTION_DO_NOTHING));
   behaviors.clear();
   behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
   behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
@@ -330,7 +328,7 @@
   // action. The user should see only see DISPLAY_OFF as the possible battery
   // idle action.
   SetPolicyForPolicyKey(&policy_map, policy::key::kScreenOffDelayBattery,
-                        std::make_unique<base::Value>(10000));
+                        base::Value(10000));
   behaviors.clear();
   behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
   settings.possible_battery_behaviors = behaviors;
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
index b05bf1b..92df43e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
@@ -23,7 +23,6 @@
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/test/fake_arc_session.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -59,9 +58,6 @@
   ~StorageHandlerTest() override = default;
 
   void SetUp() override {
-    // Need to initialize DBusThreadManager before ArcSessionManager's
-    // constructor calls DBusThreadManager::Get().
-    chromeos::DBusThreadManager::Initialize();
     // The storage handler requires an instance of DiskMountManager,
     // ArcServiceManager and ArcSessionManager.
     chromeos::disks::DiskMountManager::InitializeForTesting(
@@ -123,11 +119,8 @@
     apps_size_test_api_.reset();
     crostini_size_test_api_.reset();
     other_users_size_test_api_.reset();
-    arc_session_manager_.reset();
-    arc_service_manager_.reset();
     chromeos::disks::DiskMountManager::Shutdown();
     storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
-    chromeos::DBusThreadManager::Shutdown();
   }
 
  protected:
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
index 81aa102..378b66e 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
@@ -174,7 +174,7 @@
   // Sets a policy update which will cause power pref managed change.
   void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
                              const std::string& policy_key,
-                             std::unique_ptr<base::Value> value) {
+                             base::Value value) {
     policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
                     policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
                     std::move(value), nullptr);
@@ -225,9 +225,8 @@
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicy) {
   policy::PolicyMap policy_map;
-  SetPolicyForPolicyKey(
-      &policy_map, policy::key::kDnsOverHttpsMode,
-      std::make_unique<base::Value>(SecureDnsConfig::kModeAutomatic));
+  SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode,
+                        base::Value(SecureDnsConfig::kModeAutomatic));
 
   PrefService* local_state = g_browser_process->local_state();
   local_state->SetString(prefs::kDnsOverHttpsMode,
@@ -245,9 +244,8 @@
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) {
   policy::PolicyMap policy_map;
-  SetPolicyForPolicyKey(
-      &policy_map, policy::key::kDnsOverHttpsMode,
-      std::make_unique<base::Value>(SecureDnsConfig::kModeAutomatic));
+  SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode,
+                        base::Value(SecureDnsConfig::kModeAutomatic));
 
   std::string secure_dns_mode;
   std::vector<std::string> secure_dns_templates;
@@ -258,9 +256,8 @@
   EXPECT_EQ(static_cast<int>(SecureDnsConfig::ManagementMode::kNoOverride),
             management_mode);
 
-  SetPolicyForPolicyKey(
-      &policy_map, policy::key::kDnsOverHttpsMode,
-      std::make_unique<base::Value>(SecureDnsConfig::kModeOff));
+  SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode,
+                        base::Value(SecureDnsConfig::kModeOff));
   EXPECT_TRUE(GetLastSettingsChangedMessage(
       &secure_dns_mode, &secure_dns_templates, &management_mode));
   EXPECT_EQ(SecureDnsConfig::kModeOff, secure_dns_mode);
@@ -274,7 +271,7 @@
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, OtherPoliciesSet) {
   policy::PolicyMap policy_map;
   SetPolicyForPolicyKey(&policy_map, policy::key::kIncognitoModeAvailability,
-                        std::make_unique<base::Value>(1));
+                        base::Value(1));
 
   PrefService* local_state = g_browser_process->local_state();
   local_state->SetString(prefs::kDnsOverHttpsMode,
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
index b74f0bf..c5c9c68 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -43,6 +43,10 @@
       base::BindRepeating(&ProfilePickerHandler::HandleLaunchSelectedProfile,
                           base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
+      "launchGuestProfile",
+      base::BindRepeating(&ProfilePickerHandler::HandleLaunchGuestProfile,
+                          base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
       "askOnStartupChanged",
       base::BindRepeating(&ProfilePickerHandler::HandleAskOnStartupChanged,
                           base::Unretained(this)));
@@ -107,6 +111,15 @@
                  weak_factory_.GetWeakPtr()));
 }
 
+void ProfilePickerHandler::HandleLaunchGuestProfile(
+    const base::ListValue* args) {
+  // TODO(crbug.com/1063856): Add check |IsGuestModeEnabled| once policy
+  // checking has been added to the UI.
+  profiles::SwitchToGuestProfile(
+      base::Bind(&ProfilePickerHandler::OnSwitchToProfileComplete,
+                 weak_factory_.GetWeakPtr()));
+}
+
 void ProfilePickerHandler::HandleAskOnStartupChanged(
     const base::ListValue* args) {
   bool show_on_startup;
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.h b/chrome/browser/ui/webui/signin/profile_picker_handler.h
index 8d98c0f..6b2269d 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler.h
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler.h
@@ -26,6 +26,7 @@
  private:
   void HandleMainViewInitialize(const base::ListValue* args);
   void HandleLaunchSelectedProfile(const base::ListValue* args);
+  void HandleLaunchGuestProfile(const base::ListValue* args);
   void HandleAskOnStartupChanged(const base::ListValue* args);
   void HandleGetNewProfileSuggestedThemeInfo(const base::ListValue* args);
   void HandleLoadSignInProfileCreationFlow(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
index 176336c..2ff67fd 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -25,6 +25,7 @@
       {"mainViewTitle", IDS_PROFILE_PICKER_MAIN_VIEW_TITLE},
       {"mainViewSubtitle", IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE},
       {"askOnStartupCheckboxText", IDS_PROFILE_PICKER_ASK_ON_STARTUP},
+      {"browseAsGuestButton", IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON},
       {"backButtonLabel", IDS_PROFILE_PICKER_BACK_BUTTON_LABEL},
       {"profileTypeChoiceTitle",
        IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE},
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 6463013d..d6d293f 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -28,6 +28,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/device_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "device/fido/features.h"
@@ -323,6 +324,11 @@
     auto paired_phones = GetCablePairings();
     have_paired_phones = !paired_phones.empty();
     pairings.insert(pairings.end(), paired_phones.begin(), paired_phones.end());
+
+    mojo::Remote<device::mojom::UsbDeviceManager> usb_device_manager;
+    content::GetDeviceService().BindUsbDeviceManager(
+        usb_device_manager.BindNewPipeAndPassReceiver());
+    discovery_factory()->set_usb_device_manager(std::move(usb_device_manager));
   }
 
   if (pairings.empty() && !qr_generator_key) {
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 0d3a936..63f80ca 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1596610622-a993b1ede4201f1709aeb65ee161df429dedf1b5.profdata
+chrome-win32-master-1596628771-e32af535197a262fe54680b0a1a803a0983bdd0a.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index de8d250..3dd22efc 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1596606694-35c6f8535b14ce15b4839555c5550c892d549ecc.profdata
+chrome-win64-master-1596628771-86348d2a61736525bb253851ce1433e67dea13ba.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index a7fc300..f1869d3 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -536,6 +536,11 @@
 const base::Feature kParentAccessCode{"ParentAccessCode",
                                       base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Enables usage of Parent Access Code in the login flow for reauth and add
+// user. Requires |kParentAccessCode| to be enabled.
+const base::Feature kParentAccessCodeForOnlineLogin{
+    "ParentAccessCodeForOnlineLogin", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables usage of Parent Access Code to authorize change of time actions on
 // child user device. Requires |kParentAccessCode| to be enabled.
 const base::Feature kParentAccessCodeForTimeChange{
@@ -693,11 +698,6 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-// Enables or disables pin quick unlock.
-// TODO(https://crbug.com/935613): Remove this & the backing code.
-const base::Feature kQuickUnlockPin{"QuickUnlockPin",
-                                    base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Controls whether the PIN auto submit feature is enabled.
 const base::Feature kQuickUnlockPinAutosubmit{
     "QuickUnlockPinAutosubmit", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -806,4 +806,11 @@
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // defined(OS_CHROMEOS)
 
+#if defined(OS_CHROMEOS)
+bool IsParentAccessCodeForOnlineLoginEnabled() {
+  return base::FeatureList::IsEnabled(kParentAccessCode) &&
+         base::FeatureList::IsEnabled(kParentAccessCodeForOnlineLogin);
+}
+#endif  // defined(OS_CHROMEOS)
+
 }  // namespace features
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index a982924..c5bce98 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -342,6 +342,9 @@
 extern const base::Feature kParentAccessCode;
 
 COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kParentAccessCodeForOnlineLogin;
+
+COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kParentAccessCodeForTimeChange;
 
 COMPONENT_EXPORT(CHROME_FEATURES)
@@ -455,8 +458,6 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kQuickUnlockPin;
-
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kQuickUnlockPinAutosubmit;
 
@@ -521,6 +522,11 @@
 extern const base::Feature kWebTimeLimits;
 #endif  // defined(OS_CHROMEOS)
 
+#if defined(OS_CHROMEOS)
+COMPONENT_EXPORT(CHROME_FEATURES)
+bool IsParentAccessCodeForOnlineLoginEnabled();
+#endif  // defined(OS_CHROMEOS)
+
 bool PrefServiceEnabled();
 
 // DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index b880fa3..cfedcfe 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -884,6 +884,7 @@
       "../browser/component_updater/component_patcher_operation_browsertest.cc",
       "../browser/content_index/content_index_browsertest.cc",
       "../browser/content_settings/content_settings_browsertest.cc",
+      "../browser/conversions/conversions_usecounter_browsertest.cc",
       "../browser/crash_recovery_browsertest.cc",
       "../browser/custom_handlers/protocol_handler_registry_browsertest.cc",
       "../browser/data_reduction_proxy/data_reduction_proxy_browsertest.cc",
diff --git a/chrome/test/data/pdf/viewer_pdf_toolbar_new_test.js b/chrome/test/data/pdf/viewer_pdf_toolbar_new_test.js
index 0c026c0..b260cea 100644
--- a/chrome/test/data/pdf/viewer_pdf_toolbar_new_test.js
+++ b/chrome/test/data/pdf/viewer_pdf_toolbar_new_test.js
@@ -156,8 +156,12 @@
 
     toolbar.addEventListener('two-up-view-changed', function(e) {
       chrome.test.assertEq(false, e.detail);
+      chrome.test.assertEq(
+          'true', singlePageViewButton.getAttribute('aria-checked'));
       chrome.test.assertFalse(
           singlePageViewButton.querySelector('iron-icon').hidden);
+      chrome.test.assertEq(
+          'false', twoPageViewButton.getAttribute('aria-checked'));
       chrome.test.assertTrue(
           twoPageViewButton.querySelector('iron-icon').hidden);
       chrome.test.succeed();
@@ -174,8 +178,12 @@
 
     toolbar.addEventListener('two-up-view-changed', function(e) {
       chrome.test.assertEq(true, e.detail);
+      chrome.test.assertEq(
+          'true', twoPageViewButton.getAttribute('aria-checked'));
       chrome.test.assertFalse(
           twoPageViewButton.querySelector('iron-icon').hidden);
+      chrome.test.assertEq(
+          'false', singlePageViewButton.getAttribute('aria-checked'));
       chrome.test.assertTrue(
           singlePageViewButton.querySelector('iron-icon').hidden);
       chrome.test.succeed();
@@ -188,11 +196,15 @@
 
     const showAnnotationsButton =
         toolbar.shadowRoot.querySelector('#show-annotations-button');
+    chrome.test.assertEq(
+        'true', showAnnotationsButton.getAttribute('aria-checked'));
     chrome.test.assertFalse(
         showAnnotationsButton.querySelector('iron-icon').hidden);
 
     toolbar.addEventListener('display-annotations-changed', (e) => {
       chrome.test.assertEq(false, e.detail);
+      chrome.test.assertEq(
+          'false', showAnnotationsButton.getAttribute('aria-checked'));
       chrome.test.assertTrue(
           showAnnotationsButton.querySelector('iron-icon').hidden);
       chrome.test.succeed();
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc
index 3483370e..ed5d756 100644
--- a/chrome/test/media_router/media_router_integration_browsertest.cc
+++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -389,7 +389,7 @@
   policy::PolicyMap policy;
   policy.Set(policy::key::kEnableMediaRouter, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             std::make_unique<base::Value>(enable), nullptr);
+             base::Value(enable), nullptr);
   provider_.UpdateChromePolicy(policy);
   base::RunLoop().RunUntilIdle();
 }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 352cb6c..76fc03b 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-13387.0.0
\ No newline at end of file
+13389.0.0
\ No newline at end of file
diff --git a/chromeos/dbus/system_proxy/fake_system_proxy_client.cc b/chromeos/dbus/system_proxy/fake_system_proxy_client.cc
index baa7569..f45acf4 100644
--- a/chromeos/dbus/system_proxy/fake_system_proxy_client.cc
+++ b/chromeos/dbus/system_proxy/fake_system_proxy_client.cc
@@ -24,13 +24,6 @@
       FROM_HERE, base::BindOnce(std::move(callback), response));
 }
 
-void FakeSystemProxyClient::ShutDownDaemon(ShutDownDaemonCallback callback) {
-  ++shut_down_call_count_;
-  system_proxy::ShutDownResponse response;
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback), response));
-}
-
 void FakeSystemProxyClient::ClearUserCredentials(
     const system_proxy::ClearUserCredentialsRequest& request,
     ClearUserCredentialsCallback callback) {
@@ -40,6 +33,15 @@
       FROM_HERE, base::BindOnce(std::move(callback), response));
 }
 
+void FakeSystemProxyClient::ShutDownProcess(
+    const system_proxy::ShutDownRequest& request,
+    ShutDownProcessCallback callback) {
+  ++shut_down_call_count_;
+  system_proxy::ShutDownResponse response;
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback), response));
+}
+
 void FakeSystemProxyClient::SetWorkerActiveSignalCallback(
     WorkerActiveCallback callback) {
   worker_active_callback_ = callback;
diff --git a/chromeos/dbus/system_proxy/fake_system_proxy_client.h b/chromeos/dbus/system_proxy/fake_system_proxy_client.h
index 300b68b..10a6952 100644
--- a/chromeos/dbus/system_proxy/fake_system_proxy_client.h
+++ b/chromeos/dbus/system_proxy/fake_system_proxy_client.h
@@ -24,13 +24,14 @@
   void SetAuthenticationDetails(
       const system_proxy::SetAuthenticationDetailsRequest& request,
       SetAuthenticationDetailsCallback callback) override;
-  void ShutDownDaemon(ShutDownDaemonCallback callback) override;
   void SetWorkerActiveSignalCallback(WorkerActiveCallback callback) override;
   void SetAuthenticationRequiredSignalCallback(
       AuthenticationRequiredCallback callback) override;
   void ClearUserCredentials(
       const system_proxy::ClearUserCredentialsRequest& request,
       ClearUserCredentialsCallback callback) override;
+  void ShutDownProcess(const system_proxy::ShutDownRequest& request,
+                       ShutDownProcessCallback callback) override;
 
   void ConnectToWorkerSignals() override;
 
diff --git a/chromeos/dbus/system_proxy/system_proxy_client.cc b/chromeos/dbus/system_proxy/system_proxy_client.cc
index 8bd005b..d6bdba1 100644
--- a/chromeos/dbus/system_proxy/system_proxy_client.cc
+++ b/chromeos/dbus/system_proxy/system_proxy_client.cc
@@ -67,10 +67,6 @@
                                request, std::move(callback));
   }
 
-  void ShutDownDaemon(ShutDownDaemonCallback callback) override {
-    CallProtoMethod(system_proxy::kShutDownMethod, std::move(callback));
-  }
-
   void ClearUserCredentials(
       const system_proxy::ClearUserCredentialsRequest& request,
       ClearUserCredentialsCallback callback) override {
@@ -78,6 +74,12 @@
                                request, std::move(callback));
   }
 
+  void ShutDownProcess(const system_proxy::ShutDownRequest& request,
+                       ShutDownProcessCallback callback) override {
+    CallProtoMethodWithRequest(system_proxy::kShutDownProcessMethod, request,
+                               std::move(callback));
+  }
+
   void SetWorkerActiveSignalCallback(WorkerActiveCallback callback) override {
     DCHECK(callback);
     DCHECK(!worker_active_callback_);
diff --git a/chromeos/dbus/system_proxy/system_proxy_client.h b/chromeos/dbus/system_proxy/system_proxy_client.h
index 2955dd8..178d396 100644
--- a/chromeos/dbus/system_proxy/system_proxy_client.h
+++ b/chromeos/dbus/system_proxy/system_proxy_client.h
@@ -23,14 +23,14 @@
  public:
   using SetAuthenticationDetailsCallback = base::OnceCallback<void(
       const system_proxy::SetAuthenticationDetailsResponse& response)>;
-  using ShutDownDaemonCallback =
-      base::OnceCallback<void(const system_proxy::ShutDownResponse& response)>;
   using WorkerActiveCallback = base::RepeatingCallback<void(
       const system_proxy::WorkerActiveSignalDetails& details)>;
   using AuthenticationRequiredCallback = base::RepeatingCallback<void(
       const system_proxy::AuthenticationRequiredDetails& details)>;
   using ClearUserCredentialsCallback = base::OnceCallback<void(
       const system_proxy::ClearUserCredentialsResponse& response)>;
+  using ShutDownProcessCallback =
+      base::OnceCallback<void(const system_proxy::ShutDownResponse& response)>;
 
   // Interface with testing functionality. Accessed through GetTestInterface(),
   // only implemented in the fake implementation.
@@ -38,7 +38,7 @@
    public:
     // Returns how many times |SetAuthenticationDetails| was called.
     virtual int GetSetAuthenticationDetailsCallCount() const = 0;
-    // Returns how many times |ShutDownDaemon| was called.
+    // Returns how many times |ShutDownProcess| was called.
     virtual int GetShutDownCallCount() const = 0;
     // Returns how many times |ClearUserCredentials| was called.
     virtual int GetClearUserCredentialsCount() const = 0;
@@ -79,14 +79,16 @@
       const system_proxy::SetAuthenticationDetailsRequest& request,
       SetAuthenticationDetailsCallback callback) = 0;
 
-  // When receiving a shut-down call, System-proxy will schedule a shut-down
-  // task and reply. |callback| is called when the daemon starts to shut-down.
-  virtual void ShutDownDaemon(ShutDownDaemonCallback callback) = 0;
-
   virtual void ClearUserCredentials(
       const system_proxy::ClearUserCredentialsRequest& request,
       ClearUserCredentialsCallback callback) = 0;
 
+  // When receiving a shut down call, System-proxy will schedule a shut down
+  // task and reply. |callback| is called when the daemon or one of the
+  // processes starts to shut down.
+  virtual void ShutDownProcess(const system_proxy::ShutDownRequest& request,
+                               ShutDownProcessCallback callback) = 0;
+
   // Returns an interface for testing (fake only), or returns nullptr.
   virtual TestInterface* GetTestInterface() = 0;
 
diff --git a/components/arc/clipboard/arc_clipboard_bridge.cc b/components/arc/clipboard/arc_clipboard_bridge.cc
index ce9fc07..af34838 100644
--- a/components/arc/clipboard/arc_clipboard_bridge.cc
+++ b/components/arc/clipboard/arc_clipboard_bridge.cc
@@ -4,6 +4,7 @@
 
 #include "components/arc/clipboard/arc_clipboard_bridge.h"
 
+#include <memory>
 #include <utility>
 #include <vector>
 
@@ -15,6 +16,7 @@
 #include "components/arc/session/arc_bridge_service.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_data_endpoint.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
 
@@ -172,7 +174,9 @@
 
   // Order is important. AutoReset should outlive ScopedClipboardWriter.
   base::AutoReset<bool> auto_reset(&event_originated_at_instance_, true);
-  ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
+  ui::ScopedClipboardWriter writer(
+      ui::ClipboardBuffer::kCopyPaste,
+      std::make_unique<ui::ClipboardDataEndpoint>(ui::EndpointType::kVm));
 
   for (const auto& repr : clip_data->representations) {
     const std::string& mime_type(repr->mime_type);
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 7e3163b..4283808 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -38,6 +38,7 @@
 #include "components/autofill/core/browser/metrics/form_events.h"
 #include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
 #include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_strike_database.h"
 #include "components/autofill/core/browser/payments/test_payments_client.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
@@ -373,6 +374,11 @@
         /*call_parent_methods=*/false);
     autofill_manager_->SetExternalDelegate(external_delegate_.get());
 
+    std::unique_ptr<TestStrikeDatabase> test_strike_database =
+        std::make_unique<TestStrikeDatabase>();
+    strike_database_ = test_strike_database.get();
+    autofill_client_.set_test_strike_database(std::move(test_strike_database));
+
     // Initialize the TestPersonalDataManager with some default data.
     CreateTestAutofillProfiles();
     CreateTestCreditCards();
@@ -633,6 +639,7 @@
   TestPersonalDataManager personal_data_;
   std::unique_ptr<MockAutocompleteHistoryManager> autocomplete_history_manager_;
   base::test::ScopedFeatureList scoped_feature_list_;
+  TestStrikeDatabase* strike_database_;
 
  private:
   int ToHistogramSample(AutofillMetrics::CardUploadDecisionMetric metric) {
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
index 8798b03..fe9c470 100644
--- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -476,6 +476,9 @@
   histogram_tester.ExpectTotalCount("Autofill.CardUploadDecisionMetric", 0);
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_OnlyCountryInAddresses) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -535,6 +538,7 @@
       payments_client_->addresses_in_upload_card(),
       testing::UnorderedElementsAreArray({*personal_data_.GetProfiles()[0]}));
 }
+#endif
 
 // Tests metrics for SaveCardWithFirstAndLastNameComplete for local cards.
 TEST_F(CreditCardSaveManagerTest, LocalCreditCard_FirstAndLastName) {
@@ -675,6 +679,9 @@
 }
 
 // Tests metrics for supporting unfocused card form.
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_WithNonFocusableField) {
   credit_card_save_manager_->SetCreditCardUploadEnabled(true);
 
@@ -718,6 +725,7 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD);
 }
+#endif
 
 // Tests local card save will still work as usual when supporting unfocused card
 // form feature is already on.
@@ -1094,6 +1102,9 @@
 
 // Tests that a credit card inferred from a form with a credit card first and
 // last name can be uploaded.
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_FirstAndLastName) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1142,10 +1153,14 @@
   histogram_tester.ExpectTotalCount(
       "Autofill.SaveCardWithFirstAndLastNameComplete.Server", 1);
 }
+#endif
 
 // Tests that a credit card inferred from a form with a credit card first and
 // last name can be uploaded when the last name comes before first name on the
 // form.
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_LastAndFirstName) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1216,6 +1231,7 @@
   histogram_tester.ExpectTotalCount(
       "Autofill.SaveCardWithFirstAndLastNameComplete.Server", 1);
 }
+#endif
 
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NotSavedLocally) {
   personal_data_.ClearCreditCards();
@@ -1289,6 +1305,9 @@
   histogram_tester.ExpectTotalCount("Autofill.CardUploadDecisionMetric", 0);
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_CvcUnavailable) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1329,7 +1348,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::CVC_VALUE_NOT_FOUND);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_CvcInvalidLength) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1367,7 +1390,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::INVALID_CVC_VALUE);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_MultipleCvcFields) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1422,7 +1449,11 @@
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoCvcFieldOnForm) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1474,7 +1505,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::CVC_FIELD_NOT_FOUND);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_NoCvcFieldOnForm_InvalidCvcInNonCvcField) {
   // Create, fill and submit an address form in order to establish a recent
@@ -1530,7 +1565,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::CVC_FIELD_NOT_FOUND);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_NoCvcFieldOnForm_CvcInNonCvcField) {
   // Create, fill and submit an address form in order to establish a recent
@@ -1588,7 +1627,11 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::FOUND_POSSIBLE_CVC_VALUE_IN_NON_CVC_FIELD);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_NoCvcFieldOnForm_CvcInAddressField) {
   // Create, fill and submit an address form in order to establish a recent
@@ -1644,7 +1687,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::CVC_FIELD_NOT_FOUND);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoProfileAvailable) {
   // Don't fill or submit an address form.
 
@@ -1677,7 +1724,11 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoRecentlyUsedProfile) {
   // Create the test clock and set the time to a specific value.
   TestAutofillClock test_clock;
@@ -1724,7 +1775,11 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_CvcUnavailableAndNoProfileAvailable) {
   // Don't fill or submit an address form.
@@ -1760,7 +1815,11 @@
       AutofillMetrics::UPLOAD_OFFERED | AutofillMetrics::CVC_VALUE_NOT_FOUND |
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoNameAvailable) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -1803,7 +1862,11 @@
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME |
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_NoNameAvailableAndNoProfileAvailable) {
   // Don't fill or submit an address form.
@@ -1843,7 +1906,11 @@
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME |
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_ZipCodesConflict) {
   // Create, fill and submit two address forms with different zip codes.
   FormData address_form1, address_form2;
@@ -1892,7 +1959,11 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_ZipCodesDoNotDiscardWhitespace) {
   // Create two separate profiles with different zip codes. Must directly add
@@ -1940,7 +2011,11 @@
       AutofillMetrics::UPLOAD_OFFERED |
       AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_ZipCodesHavePrefixMatch) {
   // Create, fill and submit two address forms with different zip codes.
   FormData address_form1, address_form2;
@@ -1983,7 +2058,11 @@
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoZipCodeAvailable) {
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -2028,7 +2107,11 @@
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED |
                               AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_CCFormHasMiddleInitial) {
   // Create, fill and submit two address forms with different names.
   FormData address_form1, address_form2;
@@ -2070,7 +2153,11 @@
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoMiddleInitialInCCForm) {
   // Create, fill and submit two address forms with different names.
   FormData address_form1, address_form2;
@@ -2109,7 +2196,11 @@
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_CCFormHasCardholderMiddleName) {
   // Create, fill and submit address form without middle name.
@@ -2152,7 +2243,11 @@
       AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES |
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_CCFormHasAddressMiddleName) {
   // Create, fill and submit address form with middle name.
   FormData address_form;
@@ -2194,7 +2289,11 @@
       AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES |
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NamesCanMismatch) {
   // Create, fill and submit two address forms with different names.
   FormData address_form1, address_form2;
@@ -2245,7 +2344,11 @@
       AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES |
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_IgnoreOldProfiles) {
   // Create the test clock and set the time to a specific value.
   TestAutofillClock test_clock;
@@ -2290,6 +2393,7 @@
   ExpectUniqueCardUploadDecision(histogram_tester,
                                  AutofillMetrics::UPLOAD_OFFERED);
 }
+#endif
 
 TEST_F(
     CreditCardSaveManagerTest,
@@ -2440,6 +2544,9 @@
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_DoNotRequestCardholderNameIfNameExistsAndNoPaymentsCustomer) {
+// On iOS the cardholder name fix flow and expiration date fix flow no longer
+// apply since the user is forced to always set correct data before submitting.
+#if !defined(OS_IOS)
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
   FormData address_form;
@@ -2473,11 +2580,16 @@
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
   EXPECT_FALSE(payments_client_->detected_values_in_upload_details() &
                CreditCardSaveManager::DetectedValue::USER_PROVIDED_NAME);
+#endif
 }
 
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_DoNotRequestCardholderNameIfNameMissingAndPaymentsCustomer) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Set the billing_customer_number to designate existence of a Payments
   // account.
   personal_data_.SetPaymentsCustomerData(
@@ -2518,11 +2630,16 @@
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
   EXPECT_FALSE(payments_client_->detected_values_in_upload_details() &
                CreditCardSaveManager::DetectedValue::USER_PROVIDED_NAME);
+#endif
 }
 
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_DoNotRequestCardholderNameIfNameConflictingAndPaymentsCustomer) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Set the billing_customer_number to designate existence of a Payments
   // account.
   personal_data_.SetPaymentsCustomerData(
@@ -2563,6 +2680,7 @@
       AutofillMetrics::USER_REQUESTED_TO_PROVIDE_CARDHOLDER_NAME);
   EXPECT_FALSE(payments_client_->detected_values_in_upload_details() &
                CreditCardSaveManager::DetectedValue::USER_PROVIDED_NAME);
+#endif
 }
 
 // This test ensures |should_request_name_from_user_| is reset between offers to
@@ -2570,6 +2688,10 @@
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_ShouldRequestCardholderName_ResetBetweenConsecutiveSaves) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
   FormData address_form;
@@ -2612,6 +2734,7 @@
 
   // Verify the |credit_card_save_manager_| is NOT requesting cardholder name.
   EXPECT_FALSE(credit_card_save_manager_->should_request_name_from_user_);
+#endif
 }
 
 // This test ensures |should_request_expiration_date_from_user_|
@@ -2619,6 +2742,10 @@
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_ShouldRequestExpirationDate_ResetBetweenConsecutiveSaves) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
   FormData address_form;
@@ -2660,6 +2787,7 @@
   // Verify the |credit_card_save_manager_| is NOT requesting expiration date.
   EXPECT_FALSE(
       credit_card_save_manager_->should_request_expiration_date_from_user_);
+#endif
 }
 
 // This test ensures |should_request_expiration_date_from_user_|
@@ -2667,6 +2795,10 @@
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_WalletSyncTransportEnabled_ShouldNotRequestExpirationDate) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Wallet Sync Transport is enabled.
   personal_data_.SetSyncAndSignInState(
       AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
@@ -2691,11 +2823,13 @@
   credit_card_form.fields[3].value = ASCIIToUTF16("");
   credit_card_form.fields[4].value = ASCIIToUTF16("123");
 
+  FormSubmitted(credit_card_form);
+
   // Save should not be offered because implicit Sync + Expiration date fix flow
   // aborts offering save
-  FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
   EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+#endif
 }
 
 // This test ensures |should_request_expiration_date_from_user_|
@@ -2703,6 +2837,10 @@
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_WalletSyncTransportNotEnabled_ShouldRequestExpirationDate) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Wallet Sync Transport is not enabled.
   personal_data_.SetSyncAndSignInState(
       AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled);
@@ -2736,11 +2874,16 @@
   // Verify the |credit_card_save_manager_| is requesting expiration date.
   EXPECT_TRUE(
       credit_card_save_manager_->should_request_expiration_date_from_user_);
+#endif
 }
 
 TEST_F(
     CreditCardSaveManagerTest,
     UploadCreditCard_DoNotRequestExpirationDateIfMissingNameAndExpirationDate) {
+  // On iOS the cardholder name fix flow and expiration date fix flow no longer
+  // apply since the user is forced to always set correct data before
+  // submitting.
+#if !defined(OS_IOS)
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
   FormData address_form;
@@ -2767,6 +2910,46 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
   EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+#endif
+}
+
+// iOS should always provide a valid expiration date when attempting to
+// upload a Saved Card due to the Messages SaveCard modal.
+TEST_F(CreditCardSaveManagerTest,
+       UploadCreditCard_AlwaysRequestCardholderNameAndExpirationDateOnIOS) {
+#if defined(OS_IOS)
+  // Create, fill and submit an address form in order to establish a recent
+  // profile which can be selected for the upload request.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen(std::vector<FormData>(1, address_form));
+  ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.
+  FormData credit_card_form;
+  CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions());
+  FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+  // Edit the data, and submit.
+  credit_card_form.fields[0].value = ASCIIToUTF16("");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16(test::NextMonth());
+  credit_card_form.fields[3].value = ASCIIToUTF16(test::NextYear());
+  credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+  base::HistogramTester histogram_tester;
+
+  FormSubmitted(credit_card_form);
+  EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+  EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+  EXPECT_TRUE(
+      payments_client_->detected_values_in_upload_details() &
+      CreditCardSaveManager::DetectedValue::USER_PROVIDED_EXPIRATION_DATE);
+  EXPECT_TRUE(payments_client_->detected_values_in_upload_details() &
+              CreditCardSaveManager::DetectedValue::USER_PROVIDED_NAME);
+
+#endif
 }
 
 TEST_F(CreditCardSaveManagerTest,
@@ -3030,6 +3213,9 @@
       CreditCardSaveManager::DetectedValue::USER_PROVIDED_EXPIRATION_DATE);
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_UploadDetailsFails) {
   // Anything other than "en-US" will cause GetUploadDetails to return a failure
   // response.
@@ -3070,6 +3256,7 @@
   ExpectCardUploadDecisionUkm(
       AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
 }
+#endif
 
 TEST_F(CreditCardSaveManagerTest, DuplicateMaskedCreditCard_NoUpload) {
   // Create, fill and submit an address form in order to establish a recent
@@ -3595,6 +3782,9 @@
             expected_detected_values);
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_LogAdditionalErrorsWithUploadDetailsFailure) {
   // Anything other than "en-US" will cause GetUploadDetails to return a failure
@@ -3649,6 +3839,7 @@
                UkmCardUploadDecisionType::kEntryName, upload_decision,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
 TEST_F(
     CreditCardSaveManagerTest,
@@ -3777,6 +3968,9 @@
   EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfNoCvc) {
   // Create, fill and submit an address form in order to establish a recent
@@ -3818,7 +4012,11 @@
       AutofillMetrics::UPLOAD_OFFERED | AutofillMetrics::CVC_VALUE_NOT_FOUND,
       1 /* expected_num_matching_entries */);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfNoName) {
   // Create, fill and submit an address form in order to establish a recent
@@ -3866,7 +4064,11 @@
                UkmCardUploadDecisionType::kEntryName, upload_decision,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfConflictingNames) {
   // Create, fill and submit an address form in order to establish a recent
@@ -3913,7 +4115,11 @@
                UkmCardUploadDecisionType::kEntryName, upload_decision,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfNoZip) {
   // Set up a new address profile without a postal code.
@@ -3957,7 +4163,11 @@
                    AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfConflictingZips) {
   // Set up two new address profiles with conflicting postal codes.
@@ -4013,7 +4223,11 @@
                    AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 TEST_F(CreditCardSaveManagerTest,
        UploadCreditCard_PaymentsDecidesOfferToSaveIfNothingFound) {
   // Set up a new address profile without a name or postal code.
@@ -4066,6 +4280,7 @@
                UkmCardUploadDecisionType::kEntryName, upload_decision,
                1 /* expected_num_matching_entries */);
 }
+#endif
 
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_UploadOfLocalCard) {
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
@@ -4425,6 +4640,9 @@
       AutofillMetrics::SaveTypeMetric::LOCAL, 1);
 }
 
+// TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip
+// permanently if the test doesn't apply to iOS flow.
+#if !defined(OS_IOS)
 // Tests that a card with max strikes does not offer save on mobile at all.
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_MaxStrikesDisallowsSave) {
   TestCreditCardSaveStrikeDatabase credit_card_save_strike_database =
@@ -4477,6 +4695,7 @@
   ExpectCardUploadDecisionUkm(
       AutofillMetrics::UPLOAD_NOT_OFFERED_MAX_STRIKES_ON_MOBILE);
 }
+#endif
 
 #else  // !defined(OS_ANDROID) && !defined(OS_IOS)
 // Tests that a card with max strikes should still offer to save on Desktop via
diff --git a/components/autofill/core/browser/ui/accessory_sheet_enums.h b/components/autofill/core/browser/ui/accessory_sheet_enums.h
index 97a2cbf5..a6d5fa1 100644
--- a/components/autofill/core/browser/ui/accessory_sheet_enums.h
+++ b/components/autofill/core/browser/ui/accessory_sheet_enums.h
@@ -37,6 +37,7 @@
   MANAGE_ADDRESSES = 4,
   GENERATE_PASSWORD_MANUAL = 5,
   TOGGLE_SAVE_PASSWORDS = 6,
+  USE_OTHER_PASSWORD = 7,
   COUNT,
 };
 
diff --git a/components/browser_sync/PRESUBMIT.py b/components/browser_sync/PRESUBMIT.py
index e7128a2..6d8aa48 100644
--- a/components/browser_sync/PRESUBMIT.py
+++ b/components/browser_sync/PRESUBMIT.py
@@ -14,7 +14,7 @@
 
 def CheckChangeLintsClean(input_api, output_api):
   source_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=BROWSER_SYNC_SOURCE_FILES, black_list=None)
+    x, files_to_check=BROWSER_SYNC_SOURCE_FILES, files_to_skip=None)
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
 
diff --git a/components/country_codes/README.md b/components/country_codes/README.md
new file mode 100644
index 0000000..7ae597aa
--- /dev/null
+++ b/components/country_codes/README.md
@@ -0,0 +1,3 @@
+The country codes component deals with 2-letter country codes (aka ISO 3166-1).
+Its primary purpose is to interface with platform-specific functionality to
+provide a unified API to find out "what is the system's current country code".
diff --git a/components/cronet/PRESUBMIT.py b/components/cronet/PRESUBMIT.py
index 3c02298..1c940c4 100644
--- a/components/cronet/PRESUBMIT.py
+++ b/components/cronet/PRESUBMIT.py
@@ -49,7 +49,7 @@
   impl_package_pattern = input_api.re.compile(r'^package org.chromium.net;')
 
   source_filter = lambda path: input_api.FilterSourceFile(path,
-      white_list=[r'^components/cronet/android/.*\.(java|template)$'])
+      files_to_check=[r'^components/cronet/android/.*\.(java|template)$'])
 
   problems = []
   for f in input_api.AffectedSourceFiles(source_filter):
diff --git a/components/exo/seat.cc b/components/exo/seat.cc
index 5a19ee3..022dd31 100644
--- a/components/exo/seat.cc
+++ b/components/exo/seat.cc
@@ -4,6 +4,8 @@
 
 #include "components/exo/seat.h"
 
+#include <memory>
+
 #if defined(OS_CHROMEOS)
 #include "ash/shell.h"
 #endif  // defined(OS_CHROMEOS)
@@ -24,7 +26,9 @@
 #include "components/exo/wm_helper.h"
 #include "services/data_decoder/public/cpp/decode_image.h"
 #include "ui/aura/client/focus_client.h"
+#include "ui/base/clipboard/clipboard_data_endpoint.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/platform/platform_event_source.h"
 
@@ -108,8 +112,7 @@
   }
   selection_source_ = std::make_unique<ScopedDataSource>(source, this);
   scoped_refptr<RefCountedScopedClipboardWriter> writer =
-      base::MakeRefCounted<RefCountedScopedClipboardWriter>(
-          ui::ClipboardBuffer::kCopyPaste);
+      base::MakeRefCounted<RefCountedScopedClipboardWriter>();
 
   base::RepeatingClosure data_read_callback = base::BarrierClosure(
       kMaxClipboardDataTypes,
@@ -128,6 +131,20 @@
       data_read_callback);
 }
 
+class Seat::RefCountedScopedClipboardWriter
+    : public ui::ScopedClipboardWriter,
+      public base::RefCounted<RefCountedScopedClipboardWriter> {
+ public:
+  explicit RefCountedScopedClipboardWriter()
+      : ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste,
+                              std::make_unique<ui::ClipboardDataEndpoint>(
+                                  ui::EndpointType::kVm)) {}
+
+ private:
+  friend class base::RefCounted<RefCountedScopedClipboardWriter>;
+  virtual ~RefCountedScopedClipboardWriter() = default;
+};
+
 void Seat::OnTextRead(scoped_refptr<RefCountedScopedClipboardWriter> writer,
                       base::OnceClosure callback,
                       const std::string& mime_type,
diff --git a/components/exo/seat.h b/components/exo/seat.h
index e2b028a..b9d9f06b 100644
--- a/components/exo/seat.h
+++ b/components/exo/seat.h
@@ -107,17 +107,7 @@
   }
 
  private:
-  class RefCountedScopedClipboardWriter
-      : public ui::ScopedClipboardWriter,
-        public base::RefCounted<RefCountedScopedClipboardWriter> {
-   public:
-    RefCountedScopedClipboardWriter(ui::ClipboardBuffer buffer)
-        : ScopedClipboardWriter(buffer) {}
-
-   private:
-    friend class base::RefCounted<RefCountedScopedClipboardWriter>;
-    virtual ~RefCountedScopedClipboardWriter() = default;
-  };
+  class RefCountedScopedClipboardWriter;
 
   // Called when data is read from FD passed from a client.
   // |data| is read data. |source| is source of the data, or nullptr if
diff --git a/components/exo/wayland/clients/blur.cc b/components/exo/wayland/clients/blur.cc
index bde7118..3b3cfe5f 100644
--- a/components/exo/wayland/clients/blur.cc
+++ b/components/exo/wayland/clients/blur.cc
@@ -184,9 +184,9 @@
       SkIRect subset;
       SkIPoint offset;
       sk_sp<SkImage> blur_image = content_surfaces.back()->makeImageSnapshot();
-      sk_sp<SkImage> blurred_image =
-          blur_image->makeWithFilter(blur_filter.get(), blur_image->bounds(),
-                                     blur_image->bounds(), &subset, &offset);
+      sk_sp<SkImage> blurred_image = blur_image->makeWithFilter(
+          gr_context_.get(), blur_filter.get(), blur_image->bounds(),
+          blur_image->bounds(), &subset, &offset);
       SkCanvas* canvas = buffer->sk_surface->getCanvas();
       canvas->save();
       SkSize size = SkSize::Make(size_.width(), size_.height());
diff --git a/components/google/README.md b/components/google/README.md
new file mode 100644
index 0000000..3b7ebe7
--- /dev/null
+++ b/components/google/README.md
@@ -0,0 +1,10 @@
+The Google component deals with Google- (and Google-owned-property-)specific
+URLs and utilities.  This includes functions that determine if URLs are various
+types of Google URLs, getters for Google search URLs, and various URL
+manipulation functions.
+
+Since Chrome should serve users of all search engines, URLs, and products well,
+be hesitant before keying behavior to these functions.  Consider whether the
+proposed behavior would appear innocuous and appealing if you worked for a
+direct Google competitor, as well as whether you'd want a standardized mechanism
+for other sites to achieve the same results.
diff --git a/components/infobars/README b/components/infobars/README
deleted file mode 100644
index 8b736f1..0000000
--- a/components/infobars/README
+++ /dev/null
@@ -1,7 +0,0 @@
-- Infobars is a layered component
-(https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design)
-to enable it to be shared cleanly on iOS.
-
-Directory structure:
-core/: shared code that does not depend on src/content/
-content/: Driver for the shared code based on the content layer.
diff --git a/components/infobars/README.md b/components/infobars/README.md
new file mode 100644
index 0000000..6c005f8
--- /dev/null
+++ b/components/infobars/README.md
@@ -0,0 +1,21 @@
+The infobars component contains the core types for infobars, a UI surface that
+shows informative but generally nonblocking updates to users related to their
+current page content.  This is used on both desktop and mobile, though the
+presentation and available infobars both differ.  On desktop, for example,
+infobars are a thin bar atop the page, while on Android an "infobar" is a
+larger, popup-like surface at screen bottom.
+
+Infobars are a problematic UI design for various reasons (spoofability,
+dynamically modifying content area size, not being visually anchored and scoped
+well), and are occasionally used for purposes outside their original intent
+(e.g. the "default browser" infobar, which does not relate to the page content).
+Be cautious about adding new ones.
+
+Infobars is a layered component
+(https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design)
+to enable it to be shared cleanly on iOS.
+
+Directory structure:
+android/: Android-specific specializations
+core/: Shared code that does not depend on src/content/
+content/: Driver for the shared code based on the content layer
diff --git a/components/infobars/core/infobar_feature.cc b/components/infobars/core/infobar_feature.cc
index e64333d..0553d65 100644
--- a/components/infobars/core/infobar_feature.cc
+++ b/components/infobars/core/infobar_feature.cc
@@ -5,4 +5,4 @@
 #include "components/infobars/core/infobar_feature.h"
 
 const base::Feature kIOSInfobarUIReboot{"InfobarUIReboot",
-                                        base::FEATURE_DISABLED_BY_DEFAULT};
+                                        base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/location/android/java/src/org/chromium/components/location/LocationUtils.java b/components/location/android/java/src/org/chromium/components/location/LocationUtils.java
index 19978a2..ab5518a 100644
--- a/components/location/android/java/src/org/chromium/components/location/LocationUtils.java
+++ b/components/location/android/java/src/org/chromium/components/location/LocationUtils.java
@@ -13,8 +13,6 @@
 import android.os.Process;
 import android.provider.Settings;
 
-import androidx.annotation.VisibleForTesting;
-
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
@@ -153,7 +151,6 @@
      * Call this to use a different subclass of LocationUtils throughout the program.
      * This can be used by embedders in addition to tests.
      */
-    @VisibleForTesting
     public static void setFactory(Factory factory) {
         sFactory = factory;
         sInstance = null;
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h
index 7e9d19b..9ee8571 100644
--- a/components/omnibox/browser/autocomplete_controller.h
+++ b/components/omnibox/browser/autocomplete_controller.h
@@ -176,7 +176,9 @@
                            RedundantKeywordsIgnoredInResult);
   FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, UpdateAssistedQueryStats);
   FRIEND_TEST_ALL_PREFIXES(OmniboxPopupContentsViewTest,
-                           EmitTextChangedAccessibilityEvent);
+                           EmitAccessibilityEvents);
+  FRIEND_TEST_ALL_PREFIXES(OmniboxPopupContentsViewTest,
+                           EmitAccessibilityEventsOnButtonFocusHint);
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewTest, DoesNotUpdateAutocompleteOnBlur);
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag);
   FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel);
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index a90e884..7647187 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -1509,7 +1509,7 @@
     "Omnibox.CutOrCopyAllText";
 
 void OmniboxEditModel::SetAccessibilityLabel(const AutocompleteMatch& match) {
-  view_->SetAccessibilityLabel(view_->GetText(), match);
+  view_->SetAccessibilityLabel(view_->GetText(), match, true);
 }
 
 bool OmniboxEditModel::PopupIsOpen() const {
diff --git a/components/omnibox/browser/omnibox_popup_model.cc b/components/omnibox/browser/omnibox_popup_model.cc
index 6efe67e..4f5745f 100644
--- a/components/omnibox/browser/omnibox_popup_model.cc
+++ b/components/omnibox/browser/omnibox_popup_model.cc
@@ -588,6 +588,7 @@
 
 base::string16 OmniboxPopupModel::GetAccessibilityLabelForCurrentSelection(
     const base::string16& match_text,
+    bool include_positional_info,
     int* label_prefix_length) {
   size_t line = selection_.line;
   DCHECK_NE(line, kNoMatch)
@@ -636,10 +637,14 @@
       break;
   }
 
+  if (selection_.IsButtonFocused())
+    include_positional_info = false;
+
+  size_t total_matches = include_positional_info ? result().size() : 0;
+
   // If there's a button focused, we don't want the "n of m" message announced.
-  size_t total_matches = selection_.IsButtonFocused() ? 0 : result().size();
   return AutocompleteMatchType::ToAccessibilityLabel(
-      match, match_text, selection_.line, total_matches, additional_message_id,
+      match, match_text, line, total_matches, additional_message_id,
       label_prefix_length);
 }
 
diff --git a/components/omnibox/browser/omnibox_popup_model.h b/components/omnibox/browser/omnibox_popup_model.h
index 01eb962..9d1f4f7 100644
--- a/components/omnibox/browser/omnibox_popup_model.h
+++ b/components/omnibox/browser/omnibox_popup_model.h
@@ -249,6 +249,7 @@
   // Never call this when the current selection is kNoMatch.
   base::string16 GetAccessibilityLabelForCurrentSelection(
       const base::string16& match_text,
+      bool include_positional_info,
       int* label_prefix_length = nullptr);
 
  private:
diff --git a/components/omnibox/browser/omnibox_view.h b/components/omnibox/browser/omnibox_view.h
index e9b22e3..df7beb9 100644
--- a/components/omnibox/browser/omnibox_view.h
+++ b/components/omnibox/browser/omnibox_view.h
@@ -165,7 +165,8 @@
 
   // Updates the accessibility state by enunciating any on-focus text.
   virtual void SetAccessibilityLabel(const base::string16& display_text,
-                                     const AutocompleteMatch& match) {}
+                                     const AutocompleteMatch& match,
+                                     bool notify_text_changed) {}
 
   // Called when the temporary text in the model may have changed.
   // |display_text| is the new text to show; |match_type| is the type of the
diff --git a/components/password_manager/core/browser/credential_manager_impl.cc b/components/password_manager/core/browser/credential_manager_impl.cc
index 874b7f9..22da527 100644
--- a/components/password_manager/core/browser/credential_manager_impl.cc
+++ b/components/password_manager/core/browser/credential_manager_impl.cc
@@ -202,7 +202,10 @@
             ? CredentialType::CREDENTIAL_TYPE_PASSWORD
             : CredentialType::CREDENTIAL_TYPE_FEDERATED;
     info = CredentialInfo(*form, type_to_return);
-    if (PasswordStore* store = GetProfilePasswordStore()) {
+    PasswordStore* store = form->IsUsingAccountStore()
+                               ? GetAccountPasswordStore()
+                               : GetProfilePasswordStore();
+    if (store) {
       if (form->skip_zero_click && IsZeroClickAllowed()) {
         autofill::PasswordForm update_form = *form;
         update_form.skip_zero_click = false;
diff --git a/components/password_manager/core/browser/credential_manager_impl_unittest.cc b/components/password_manager/core/browser/credential_manager_impl_unittest.cc
index a1598ed..a20567a 100644
--- a/components/password_manager/core/browser/credential_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/credential_manager_impl_unittest.cc
@@ -1302,7 +1302,7 @@
   EXPECT_NE(CredentialType::CREDENTIAL_TYPE_EMPTY, credential_1->type);
 }
 
-TEST_P(CredentialManagerImplTest, ResetSkipZeroClickAfterPrompt) {
+TEST_P(CredentialManagerImplTest, ResetSkipZeroClickInProfileStoreAfterPrompt) {
   // Turn on the global zero-click flag, and add two credentials in separate
   // origins, both set to skip zero-click.
   client_->set_zero_click_enabled(true);
@@ -1351,6 +1351,92 @@
   EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
 }
 
+TEST_P(CredentialManagerImplTest, ResetSkipZeroClickInAccountStoreAfterPrompt) {
+  // This test is relevant only for account store users.
+  if (!GetParam())
+    return;
+  DCHECK(account_store_);
+  // This is simplified version of the test above that tests against the account
+  // store.
+  // Turn on the global zero-click flag, and add the credential for
+  // |kTestWebOrigin| and set to skip zero-click.
+  client_->set_zero_click_enabled(true);
+  form_.skip_zero_click = true;
+  account_store_->AddLogin(form_);
+
+  // Trigger a request which should return the credential found in |form_|, and
+  // wait for it to process.
+  // Check that the form in the database has been updated. `OnRequestCredential`
+  // generates a call to prompt the user to choose a credential.
+  // MockPasswordManagerClient mocks a user choice, and when users choose a
+  // credential (and have the global zero-click flag enabled), we make sure that
+  // they'll be logged in again next time.
+  EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr)
+      .Times(testing::Exactly(1));
+  EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
+
+  bool called = false;
+  CredentialManagerError error;
+  base::Optional<CredentialInfo> credential;
+  CallGet(CredentialMediationRequirement::kOptional, true, /*federations=*/{},
+          base::BindOnce(&GetCredentialCallback, &called, &error, &credential));
+
+  RunAllPendingTasks();
+
+  TestPasswordStore::PasswordMap passwords = account_store_->stored_passwords();
+  ASSERT_EQ(1U, passwords.size());
+  ASSERT_EQ(1U, passwords[form_.signon_realm].size());
+  EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
+}
+
+TEST_P(CredentialManagerImplTest,
+       ResetSkipZeroClickInAccountStoreAfterPromptIfExistsInBothStores) {
+  // This test is relevant only for account store users.
+  if (!GetParam())
+    return;
+  DCHECK(account_store_);
+  // This is simplified version of the test above that tests against both the
+  // profile the account stores. When the same credential is stored in both
+  // stores, we favor the one in the account.
+
+  // Turn on the global zero-click flag, and add the credential for
+  // |kTestWebOrigin| , both set to skip zero-click on both stores.
+  client_->set_zero_click_enabled(true);
+  form_.skip_zero_click = true;
+  account_store_->AddLogin(form_);
+  store_->AddLogin(form_);
+
+  // Trigger a request which should return the credential found in |form_|, and
+  // wait for it to process.
+  // Check that the form in the database has been updated. `OnRequestCredential`
+  // generates a call to prompt the user to choose a credential.
+  // MockPasswordManagerClient mocks a user choice, and when users choose a
+  // credential (and have the global zero-click flag enabled), we make sure that
+  // they'll be logged in again next time.
+  EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr)
+      .Times(testing::Exactly(1));
+  EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
+
+  bool called = false;
+  CredentialManagerError error;
+  base::Optional<CredentialInfo> credential;
+  CallGet(CredentialMediationRequirement::kOptional, true, /*federations=*/{},
+          base::BindOnce(&GetCredentialCallback, &called, &error, &credential));
+
+  RunAllPendingTasks();
+
+  // Only the one in the account store is affected.
+  TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
+  ASSERT_EQ(1U, passwords.size());
+  ASSERT_EQ(1U, passwords[form_.signon_realm].size());
+  EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
+
+  passwords = account_store_->stored_passwords();
+  ASSERT_EQ(1U, passwords.size());
+  ASSERT_EQ(1U, passwords[form_.signon_realm].size());
+  EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
+}
+
 TEST_P(CredentialManagerImplTest, IncognitoZeroClickRequestCredential) {
   EXPECT_CALL(*client_, IsIncognito()).WillRepeatedly(testing::Return(true));
   store_->AddLogin(form_);
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index c87a2f1..0acfce1 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -45,16 +45,6 @@
 constexpr char kAutocompleteCreditCardPrefix[] = "cc-";
 constexpr char kAutocompleteOneTimePassword[] = "one-time-code";
 
-// The susbset of autocomplete flags related to passwords.
-enum class AutocompleteFlag {
-  kNone,
-  kUsername,
-  kCurrentPassword,
-  kNewPassword,
-  // Represents the whole family of cc-* flags + OTP flag.
-  kNonPassword
-};
-
 // The autocomplete attribute has one of the following structures:
 //   [section-*] [shipping|billing] [type_hint] field_type
 //   on | off | false
@@ -89,42 +79,6 @@
   return AutocompleteFlag::kNone;
 }
 
-// How likely is user interaction for a given field?
-// Note: higher numeric values should match higher likeliness to allow using the
-// standard operator< for comparison of likeliness.
-enum class Interactability {
-  // When the field is invisible.
-  kUnlikely = 0,
-  // When the field is visible/focusable.
-  kPossible = 1,
-  // When the user actually typed into the field before.
-  kCertain = 2,
-};
-
-// A wrapper around FormFieldData, carrying some additional data used during
-// parsing.
-struct ProcessedField {
-  // This points to the wrapped FormFieldData.
-  const FormFieldData* field;
-
-  // The flag derived from field->autocomplete_attribute.
-  AutocompleteFlag autocomplete_flag = AutocompleteFlag::kNone;
-
-  // True if field->form_control_type == "password".
-  bool is_password = false;
-
-  // True if field is predicted to be a password.
-  bool is_predicted_as_password = false;
-
-  // True if the server predicts that this field is not a password field.
-  bool server_hints_not_password = false;
-
-  // True if the server predicts that this field is not a username field.
-  bool server_hints_not_username = false;
-
-  Interactability interactability = Interactability::kUnlikely;
-};
-
 // Returns true if the |str| contains words related to CVC fields.
 bool StringMatchesCVC(const base::string16& str) {
   static const base::NoDestructor<base::string16> kCardCvcReCached(
@@ -909,27 +863,6 @@
   return result;
 }
 
-// Find the first element in |username_predictions| (i.e. the most reliable
-// prediction) that occurs in |processed_fields| and has interactability level
-// at least |username_max|.
-const FormFieldData* FindUsernameInPredictions(
-    const std::vector<autofill::FieldRendererId>& username_predictions,
-    const std::vector<ProcessedField>& processed_fields,
-    Interactability username_max) {
-  for (autofill::FieldRendererId predicted_id : username_predictions) {
-    auto iter = std::find_if(
-        processed_fields.begin(), processed_fields.end(),
-        [predicted_id, username_max](const ProcessedField& processed_field) {
-          return processed_field.field->unique_renderer_id == predicted_id &&
-                 MatchesInteractability(processed_field, username_max);
-        });
-    if (iter != processed_fields.end()) {
-      return iter->field;
-    }
-  }
-  return nullptr;
-}
-
 // Return true if |significant_fields| has an username field and
 // |form_predictions| has |may_use_prefilled_placeholder| == true for the
 // username field.
@@ -1103,4 +1036,22 @@
   return url.ReplaceComponents(rep).spec();
 }
 
+const FormFieldData* FindUsernameInPredictions(
+    const std::vector<autofill::FieldRendererId>& username_predictions,
+    const std::vector<ProcessedField>& processed_fields,
+    Interactability username_max) {
+  for (autofill::FieldRendererId predicted_id : username_predictions) {
+    auto iter = std::find_if(
+        processed_fields.begin(), processed_fields.end(),
+        [predicted_id, username_max](const ProcessedField& processed_field) {
+          return processed_field.field->unique_renderer_id == predicted_id &&
+                 MatchesInteractability(processed_field, username_max);
+        });
+    if (iter != processed_fields.end()) {
+      return iter->field;
+    }
+  }
+  return nullptr;
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.h b/components/password_manager/core/browser/form_parsing/form_parser.h
index a69e144..7f248ad 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.h
+++ b/components/password_manager/core/browser/form_parsing/form_parser.h
@@ -21,6 +21,52 @@
 
 namespace password_manager {
 
+// The susbset of autocomplete flags related to passwords.
+enum class AutocompleteFlag {
+  kNone,
+  kUsername,
+  kCurrentPassword,
+  kNewPassword,
+  // Represents the whole family of cc-* flags + OTP flag.
+  kNonPassword
+};
+
+// How likely is user interaction for a given field?
+// Note: higher numeric values should match higher likeliness to allow using the
+// standard operator< for comparison of likeliness.
+enum class Interactability {
+  // When the field is invisible.
+  kUnlikely = 0,
+  // When the field is visible/focusable.
+  kPossible = 1,
+  // When the user actually typed into the field before.
+  kCertain = 2,
+};
+
+// A wrapper around FormFieldData, carrying some additional data used during
+// parsing.
+struct ProcessedField {
+  // This points to the wrapped FormFieldData.
+  const autofill::FormFieldData* field;
+
+  // The flag derived from field->autocomplete_attribute.
+  AutocompleteFlag autocomplete_flag = AutocompleteFlag::kNone;
+
+  // True if field->form_control_type == "password".
+  bool is_password = false;
+
+  // True if field is predicted to be a password.
+  bool is_predicted_as_password = false;
+
+  // True if the server predicts that this field is not a password field.
+  bool server_hints_not_password = false;
+
+  // True if the server predicts that this field is not a username field.
+  bool server_hints_not_username = false;
+
+  Interactability interactability = Interactability::kUnlikely;
+};
+
 // This class takes care of parsing FormData into PasswordForm and managing
 // related metadata.
 class FormDataParser {
@@ -104,6 +150,14 @@
 // origin |url|.
 std::string GetSignonRealm(const GURL& url);
 
+// Find the first element in |username_predictions| (i.e. the most reliable
+// prediction) that occurs in |processed_fields| and has interactability level
+// at least |username_max|.
+const autofill::FormFieldData* FindUsernameInPredictions(
+    const std::vector<autofill::FieldRendererId>& username_predictions,
+    const std::vector<ProcessedField>& processed_fields,
+    Interactability username_max);
+
 }  // namespace password_manager
 
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_IOS_FORM_PARSER_H_
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index e05dd61..65dca71 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -2522,6 +2522,53 @@
   EXPECT_FALSE(parser.Parse(form_data, FormDataParser::Mode::kSaving));
 }
 
+TEST(FormParserTest, FindUsernameInPredictions_SkipPrediction) {
+  // Searching username field should skip prediction that is less
+  // likely to be user interaction. For example, if a field has no
+  // user input while others have, the field cannot be an username
+  // field.
+
+  // Create a form containing username, email, id, password, submit.
+  const FormParsingTestCase form_desc = {
+      .fields = {
+          {.name = "username", .form_control_type = "text"},
+          {.name = "email", .form_control_type = "text"},
+          {.name = "id", .form_control_type = "text"},
+          {.name = "password", .form_control_type = "password"},
+          {.name = "submit", .form_control_type = "submit"},
+      }};
+
+  FormPredictions no_predictions;
+  ParseResultIds dummy;
+  const FormData form_data =
+      GetFormDataAndExpectation(form_desc, &no_predictions, &dummy, &dummy);
+
+  // Add all form fields in ProcessedField. A user typed only into
+  // "id" and "password" fields. So, the prediction for "email" field
+  // should be ignored despite it is more reliable than prediction for
+  // "id" field.
+  std::vector<ProcessedField> processed_fields;
+  for (const auto& form_field_data : form_data.fields)
+    processed_fields.push_back(ProcessedField{.field = &form_field_data});
+
+  processed_fields[2].interactability = Interactability::kCertain;  // id
+  processed_fields[3].interactability = Interactability::kCertain;  // password
+
+  // Add predictions for "email" and "id" fields. The "email" is in
+  // front of "id", indicating "email" is more reliable.
+  const std::vector<autofill::FieldRendererId> predictions = {
+      form_data.fields[1].unique_renderer_id,  // email
+      form_data.fields[2].unique_renderer_id,  // id
+  };
+
+  // Now search the username field. The username field is supposed to
+  // be "id", not "email".
+  const autofill::FormFieldData* field_data = FindUsernameInPredictions(
+      predictions, processed_fields, Interactability::kCertain);
+  ASSERT_TRUE(field_data);
+  EXPECT_EQ(base::UTF8ToUTF16("id"), field_data->name);
+}
+
 }  // namespace
 
 }  // namespace password_manager
diff --git a/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java b/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java
index ad4f7d9..a626dd7 100644
--- a/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java
+++ b/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java
@@ -6,8 +6,6 @@
 
 import android.os.Bundle;
 
-import androidx.annotation.VisibleForTesting;
-
 import org.chromium.base.ThreadUtils;
 
 /**
@@ -24,9 +22,6 @@
         mCombinedPolicyProvider.onSettingsAvailable(mSource, settings);
     }
 
-    // Within Chromium only used in tests, although used in downstream code. @VisibleForTesting
-    // required to prevent removal by Proguard when building upstream.
-    @VisibleForTesting
     protected void terminateIncognitoSession() {
         mCombinedPolicyProvider.terminateIncognitoSession();
     }
diff --git a/components/policy/core/browser/policy_pref_mapping_test.cc b/components/policy/core/browser/policy_pref_mapping_test.cc
index 7dcdf70..14a5aa5a 100644
--- a/components/policy/core/browser/policy_pref_mapping_test.cc
+++ b/components/policy/core/browser/policy_pref_mapping_test.cc
@@ -359,7 +359,7 @@
     ASSERT_TRUE(policy_details);
     policy_map.Set(
         it.first, level, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-        it.second.CreateDeepCopy(),
+        it.second.Clone(),
         policy_details->max_external_data_size
             ? std::make_unique<ExternalDataFetcher>(nullptr, it.first)
             : nullptr);
diff --git a/components/policy/core/common/async_policy_provider_unittest.cc b/components/policy/core/common/async_policy_provider_unittest.cc
index a9d618e2..7594fd225 100644
--- a/components/policy/core/common/async_policy_provider_unittest.cc
+++ b/components/policy/core/common/async_policy_provider_unittest.cc
@@ -34,8 +34,7 @@
                const std::string& value) {
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_PLATFORM, std::make_unique<base::Value>(value),
-           nullptr);
+           POLICY_SOURCE_PLATFORM, base::Value(value), nullptr);
 }
 
 class MockPolicyLoader : public AsyncPolicyLoader {
diff --git a/components/policy/core/common/cloud/component_cloud_policy_store.cc b/components/policy/core/common/cloud/component_cloud_policy_store.cc
index 1c39b22..4800bfbd 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_store.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_store.cc
@@ -435,8 +435,7 @@
       level = POLICY_LEVEL_RECOMMENDED;
 
     policy->Set(policy_name, level, domain_constants_->scope, policy_source_,
-                base::Value::ToUniquePtrValue(std::move(value.value())),
-                nullptr);
+                std::move(value.value()), nullptr);
   }
 
   return true;
diff --git a/components/policy/core/common/cloud/user_cloud_policy_manager.cc b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
index 9384f98..4201a72 100644
--- a/components/policy/core/common/cloud/user_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
@@ -114,8 +114,7 @@
       !policy_map->Get(key::kNTPContentSuggestionsEnabled)) {
     policy_map->Set(key::kNTPContentSuggestionsEnabled, POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_USER, POLICY_SOURCE_ENTERPRISE_DEFAULT,
-                    std::make_unique<base::Value>(false),
-                    nullptr /* external_data_fetcher */);
+                    base::Value(false), nullptr /* external_data_fetcher */);
   }
 #endif
 }
diff --git a/components/policy/core/common/generate_policy_source_unittest.cc b/components/policy/core/common/generate_policy_source_unittest.cc
index 59de129..d7c75da 100644
--- a/components/policy/core/common/generate_policy_source_unittest.cc
+++ b/components/policy/core/common/generate_policy_source_unittest.cc
@@ -221,7 +221,7 @@
   // If policy already configured, it's not changed to enterprise defaults.
   policy_map.Set(key::kChromeOsMultiProfileUserBehavior, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 std::make_unique<base::Value>("test_value"), nullptr);
+                 base::Value("test_value"), nullptr);
   SetEnterpriseUsersDefaults(&policy_map);
   multiprof_behavior =
       policy_map.GetValue(key::kChromeOsMultiProfileUserBehavior);
diff --git a/components/policy/core/common/legacy_chrome_policy_migrator_unittest.cc b/components/policy/core/common/legacy_chrome_policy_migrator_unittest.cc
index 2577ad0..f9cac88 100644
--- a/components/policy/core/common/legacy_chrome_policy_migrator_unittest.cc
+++ b/components/policy/core/common/legacy_chrome_policy_migrator_unittest.cc
@@ -28,9 +28,7 @@
   *val = base::Value(val->GetInt() * 3);
 }
 
-void SetPolicy(PolicyMap* policy,
-               const char* policy_name,
-               std::unique_ptr<base::Value> value) {
+void SetPolicy(PolicyMap* policy, const char* policy_name, base::Value value) {
   policy->Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
               POLICY_SOURCE_CLOUD, std::move(value), nullptr);
 }
@@ -42,9 +40,8 @@
 
   PolicyMap& chrome_map = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
 
-  SetPolicy(&chrome_map, kOldPolicy, std::make_unique<base::Value>(kOldValue));
-  SetPolicy(&chrome_map, kOtherPolicy,
-            std::make_unique<base::Value>(kOtherValue));
+  SetPolicy(&chrome_map, kOldPolicy, base::Value(kOldValue));
+  SetPolicy(&chrome_map, kOtherPolicy, base::Value(kOtherValue));
 
   LegacyChromePolicyMigrator migrator(kOldPolicy, kNewPolicy);
 
@@ -71,7 +68,7 @@
 
   PolicyMap& chrome_map = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
 
-  SetPolicy(&chrome_map, kOldPolicy, std::make_unique<base::Value>(kOldValue));
+  SetPolicy(&chrome_map, kOldPolicy, base::Value(kOldValue));
 
   LegacyChromePolicyMigrator migrator(kOldPolicy, kNewPolicy,
                                       base::BindRepeating(&MultiplyByThree));
@@ -88,8 +85,8 @@
 
   PolicyMap& chrome_map = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
 
-  SetPolicy(&chrome_map, kOldPolicy, std::make_unique<base::Value>(kOldValue));
-  SetPolicy(&chrome_map, kNewPolicy, std::make_unique<base::Value>(kNewValue));
+  SetPolicy(&chrome_map, kOldPolicy, base::Value(kOldValue));
+  SetPolicy(&chrome_map, kNewPolicy, base::Value(kNewValue));
 
   LegacyChromePolicyMigrator migrator(kOldPolicy, kNewPolicy);
 
diff --git a/components/policy/core/common/policy_bundle_unittest.cc b/components/policy/core/common/policy_bundle_unittest.cc
index 6625447e..09104ea 100644
--- a/components/policy/core/common/policy_bundle_unittest.cc
+++ b/components/policy/core/common/policy_bundle_unittest.cc
@@ -37,10 +37,10 @@
               POLICY_SOURCE_CLOUD, base::Value("omg"), nullptr);
   policy->Set("recommended-user", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
               POLICY_SOURCE_CLOUD, base::Value(true), nullptr);
-  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->SetBoolean("false", false);
-  dict->SetInteger("int", 456);
-  dict->SetString("str", "bbq");
+  base::Value dict(base::Value::Type::DICTIONARY);
+  dict.SetBoolKey("false", false);
+  dict.SetIntKey("int", 456);
+  dict.SetStringKey("str", "bbq");
   policy->Set("recommended-machine", POLICY_LEVEL_RECOMMENDED,
               POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::move(dict),
               nullptr);
diff --git a/components/policy/core/common/policy_loader_ios.h b/components/policy/core/common/policy_loader_ios.h
index c04a579..ca4682c 100644
--- a/components/policy/core/common/policy_loader_ios.h
+++ b/components/policy/core/common/policy_loader_ios.h
@@ -40,9 +40,8 @@
   // Validates the given policy data against the stored |schema_|, converting
   // data to the expected type if necessary.  The returned value is suitable for
   // adding to a PolicyMap.
-  std::unique_ptr<base::Value> ConvertPolicyDataIfNecessary(
-      const std::string& key,
-      const base::Value& value);
+  base::Value ConvertPolicyDataIfNecessary(const std::string& key,
+                                           const base::Value& value);
 
   // The schema used by |ValidatePolicyData()|.
   const Schema* policy_schema_;
diff --git a/components/policy/core/common/policy_loader_ios.mm b/components/policy/core/common/policy_loader_ios.mm
index 36b57d8..8e58ebf 100644
--- a/components/policy/core/common/policy_loader_ios.mm
+++ b/components/policy/core/common/policy_loader_ios.mm
@@ -149,13 +149,13 @@
   }
 }
 
-std::unique_ptr<base::Value> PolicyLoaderIOS::ConvertPolicyDataIfNecessary(
+base::Value PolicyLoaderIOS::ConvertPolicyDataIfNecessary(
     const std::string& key,
     const base::Value& value) {
   const Schema schema = policy_schema_->GetKnownProperty(key);
 
   if (!schema.valid()) {
-    return value.CreateDeepCopy();
+    return value.Clone();
   }
 
   // Handle the case of a JSON-encoded string for a dict policy.
@@ -163,12 +163,12 @@
     base::Optional<base::Value> decoded_value = base::JSONReader::Read(
         value.GetString(), base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS);
     if (decoded_value.has_value()) {
-      return base::Value::ToUniquePtrValue(std::move(decoded_value.value()));
+      return std::move(decoded_value.value());
     }
   }
 
   // Otherwise return an unchanged value.
-  return value.CreateDeepCopy();
+  return value.Clone();
 }
 
 }  // namespace policy
diff --git a/components/policy/core/common/policy_loader_mac.mm b/components/policy/core/common/policy_loader_mac.mm
index bb19a66..7bbe6c5 100644
--- a/components/policy/core/common/policy_loader_mac.mm
+++ b/components/policy/core/common/policy_loader_mac.mm
@@ -134,7 +134,7 @@
     std::unique_ptr<base::Value> policy = PropertyToValue(value);
     if (policy) {
       chrome_policy.Set(it.key(), level, POLICY_SCOPE_MACHINE,
-                        POLICY_SOURCE_PLATFORM, std::move(policy), nullptr);
+                        POLICY_SOURCE_PLATFORM, std::move(*policy), nullptr);
     } else {
       status.Add(POLICY_LOAD_STATUS_PARSE_ERROR);
     }
@@ -234,7 +234,7 @@
     std::unique_ptr<base::Value> policy_value = PropertyToValue(value);
     if (policy_value) {
       policy->Set(it.key(), level, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
-                  std::move(policy_value), nullptr);
+                  std::move(*policy_value), nullptr);
     }
   }
 }
diff --git a/components/policy/core/common/policy_loader_mac_unittest.cc b/components/policy/core/common/policy_loader_mac_unittest.cc
index 846af79..1e5ea05 100644
--- a/components/policy/core/common/policy_loader_mac_unittest.cc
+++ b/components/policy/core/common/policy_loader_mac_unittest.cc
@@ -197,7 +197,7 @@
   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(test_keys::kKeyString, POLICY_LEVEL_RECOMMENDED,
            POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
-           std::make_unique<base::Value>("string value"), nullptr);
+           base::Value("string value"), nullptr);
   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
 }
 
diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc
index 3fa33e9..8c8cb7d 100644
--- a/components/policy/core/common/policy_map.cc
+++ b/components/policy/core/common/policy_map.cc
@@ -217,19 +217,6 @@
     PolicyLevel level,
     PolicyScope scope,
     PolicySource source,
-    std::unique_ptr<base::Value> value,
-    std::unique_ptr<ExternalDataFetcher> external_data_fetcher) {
-  Entry entry(level, scope, source,
-              value ? base::make_optional(std::move(*value)) : base::nullopt,
-              std::move(external_data_fetcher));
-  Set(policy, std::move(entry));
-}
-
-void PolicyMap::Set(
-    const std::string& policy,
-    PolicyLevel level,
-    PolicyScope scope,
-    PolicySource source,
     base::Optional<base::Value> value,
     std::unique_ptr<ExternalDataFetcher> external_data_fetcher) {
   Entry entry(level, scope, source, std::move(value),
diff --git a/components/policy/core/common/policy_map.h b/components/policy/core/common/policy_map.h
index 5990345..9b07543 100644
--- a/components/policy/core/common/policy_map.h
+++ b/components/policy/core/common/policy_map.h
@@ -143,16 +143,6 @@
 
   // Overwrites any existing information stored in the map for the key |policy|.
   // Resets the error for that policy to the empty string.
-  // DEPRECATED: Use the other version that takes base::Optional<base::Value>
-  // below.
-  // TODO(crbug.com/1092469): Migrate the existing usages and delete this
-  // method.
-  void Set(const std::string& policy,
-           PolicyLevel level,
-           PolicyScope scope,
-           PolicySource source,
-           std::unique_ptr<base::Value> value,
-           std::unique_ptr<ExternalDataFetcher> external_data_fetcher);
   void Set(const std::string& policy,
            PolicyLevel level,
            PolicyScope scope,
diff --git a/components/policy/core/common/policy_service_impl.cc b/components/policy/core/common/policy_service_impl.cc
index 81dad68..aeb346a 100644
--- a/components/policy/core/common/policy_service_impl.cc
+++ b/components/policy/core/common/policy_service_impl.cc
@@ -47,21 +47,19 @@
   // first, and then only policies with those exact attributes are merged.
   PolicyMap::Entry current_priority;  // Defaults to the lowest priority.
   PolicySource inherited_source = POLICY_SOURCE_ENTERPRISE_DEFAULT;
-  std::unique_ptr<base::DictionaryValue> proxy_settings(
-      new base::DictionaryValue);
+  base::Value proxy_settings(base::Value::Type::DICTIONARY);
   for (size_t i = 0; i < base::size(kProxyPolicies); ++i) {
     const PolicyMap::Entry* entry = policies->Get(kProxyPolicies[i]);
     if (entry) {
       if (entry->has_higher_priority_than(current_priority)) {
-        proxy_settings->Clear();
+        proxy_settings = base::Value(base::Value::Type::DICTIONARY);
         current_priority = entry->DeepCopy();
         if (entry->source > inherited_source)  // Higher priority?
           inherited_source = entry->source;
       }
       if (!entry->has_higher_priority_than(current_priority) &&
           !current_priority.has_higher_priority_than(*entry)) {
-        proxy_settings->Set(kProxyPolicies[i],
-                            entry->value()->CreateDeepCopy());
+        proxy_settings.SetKey(kProxyPolicies[i], entry->value()->Clone());
       }
       policies->Erase(kProxyPolicies[i]);
     }
@@ -69,7 +67,7 @@
   // Sets the new |proxy_settings| if kProxySettings isn't set yet, or if the
   // new priority is higher.
   const PolicyMap::Entry* existing = policies->Get(key::kProxySettings);
-  if (!proxy_settings->empty() &&
+  if (!proxy_settings.DictEmpty() &&
       (!existing || current_priority.has_higher_priority_than(*existing))) {
     policies->Set(key::kProxySettings, current_priority.level,
                   current_priority.scope, inherited_source,
diff --git a/components/policy/core/common/policy_statistics_collector_unittest.cc b/components/policy/core/common/policy_statistics_collector_unittest.cc
index 2d01549..d6fdb11 100644
--- a/components/policy/core/common/policy_statistics_collector_unittest.cc
+++ b/components/policy/core/common/policy_statistics_collector_unittest.cc
@@ -116,8 +116,7 @@
 
   void SetPolicy(const std::string& name) {
     policy_map_.Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true),
-                    nullptr);
+                    POLICY_SOURCE_CLOUD, base::Value(true), nullptr);
   }
 
   void SetPolicyIgnoredByAtomicGroup(const std::string& name) {
diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py
index 6d6c9ea..0fed66a 100755
--- a/components/policy/tools/generate_policy_source.py
+++ b/components/policy/tools/generate_policy_source.py
@@ -1009,17 +1009,17 @@
 
   |value|: The deserialized value to convert to base::Value."""
   if type(value) == bool or type(value) == int:
-    return [], 'std::make_unique<base::Value>(%s)' % json.dumps(value)
+    return [], 'base::Value(%s)' % json.dumps(value)
   elif type(value) == str:
-    return [], 'std::make_unique<base::Value>("%s")' % value
+    return [], 'base::Value("%s")' % value
   elif type(value) == list:
-    setup = ['auto default_value = std::make_unique<base::ListValue>();']
+    setup = ['base::Value default_value(base::Value::Type::LIST);']
     for entry in value:
       decl, fetch = _GenerateDefaultValue(entry)
       # Nested lists are not supported.
       if decl:
         return [], None
-      setup.append('default_value->Append(%s);' % fetch)
+      setup.append('default_value.Append(%s);' % fetch)
     return setup, 'std::move(default_value)'
   return [], None
 
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py
index d256b782..e5dcafa 100644
--- a/components/sync/PRESUBMIT.py
+++ b/components/sync/PRESUBMIT.py
@@ -370,7 +370,7 @@
 
 def CheckChangeLintsClean(input_api, output_api):
   source_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=SYNC_SOURCE_FILES, black_list=None)
+    x, files_to_check=SYNC_SOURCE_FILES, files_to_skip=None)
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
 
diff --git a/components/sync_bookmarks/PRESUBMIT.py b/components/sync_bookmarks/PRESUBMIT.py
index ef269b0..ae36e52 100644
--- a/components/sync_bookmarks/PRESUBMIT.py
+++ b/components/sync_bookmarks/PRESUBMIT.py
@@ -15,7 +15,7 @@
 
 def CheckChangeLintsClean(input_api, output_api):
   source_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=SYNC_BOOKMARKS_SOURCE_FILES, black_list=None)
+    x, files_to_check=SYNC_BOOKMARKS_SOURCE_FILES, files_to_skip=None)
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
 
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler.cc b/components/sync_bookmarks/bookmark_remote_updates_handler.cc
index b3ec5b1..a92ed2d 100644
--- a/components/sync_bookmarks/bookmark_remote_updates_handler.cc
+++ b/components/sync_bookmarks/bookmark_remote_updates_handler.cc
@@ -4,6 +4,7 @@
 
 #include "components/sync_bookmarks/bookmark_remote_updates_handler.h"
 
+#include <algorithm>
 #include <memory>
 #include <set>
 #include <string>
@@ -94,27 +95,40 @@
   }
 }
 
+syncer::UniquePosition ComputeUniquePositionForTrackedBookmarkNode(
+    const SyncedBookmarkTracker* bookmark_tracker,
+    const bookmarks::BookmarkNode* bookmark_node) {
+  DCHECK(bookmark_tracker);
+
+  const SyncedBookmarkTracker::Entity* child_entity =
+      bookmark_tracker->GetEntityForBookmarkNode(bookmark_node);
+  DCHECK(child_entity);
+  // TODO(crbug.com/1113139): precompute UniquePosition to prevent its
+  // calculation on each remote update.
+  return syncer::UniquePosition::FromProto(
+      child_entity->metadata()->unique_position());
+}
+
 size_t ComputeChildNodeIndex(const bookmarks::BookmarkNode* parent,
                              const sync_pb::UniquePosition& unique_position,
                              const SyncedBookmarkTracker* bookmark_tracker) {
-  // TODO(crbug.com/1084150): remove after investigations are completed.
-  TRACE_EVENT0("sync", "ComputeChildNodeIndex");
+  DCHECK(parent);
+  DCHECK(bookmark_tracker);
 
   const syncer::UniquePosition position =
       syncer::UniquePosition::FromProto(unique_position);
-  for (size_t i = 0; i < parent->children().size(); ++i) {
-    const bookmarks::BookmarkNode* child = parent->children()[i].get();
-    const SyncedBookmarkTracker::Entity* child_entity =
-        bookmark_tracker->GetEntityForBookmarkNode(child);
-    DCHECK(child_entity);
-    const syncer::UniquePosition child_position =
-        syncer::UniquePosition::FromProto(
-            child_entity->metadata()->unique_position());
-    if (position.LessThan(child_position)) {
-      return i;
-    }
-  }
-  return parent->children().size();
+
+  auto iter = std::partition_point(
+      parent->children().begin(), parent->children().end(),
+      [bookmark_tracker,
+       position](const std::unique_ptr<bookmarks::BookmarkNode>& child) {
+        // Return true for all |parent|'s children whose position is less than
+        // |position|.
+        return !position.LessThan(ComputeUniquePositionForTrackedBookmarkNode(
+            bookmark_tracker, child.get()));
+      });
+
+  return iter - parent->children().begin();
 }
 
 void ApplyRemoteUpdate(
@@ -429,6 +443,14 @@
 }
 
 // static
+size_t BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+    const bookmarks::BookmarkNode* parent,
+    const sync_pb::UniquePosition& unique_position,
+    const SyncedBookmarkTracker* bookmark_tracker) {
+  return ComputeChildNodeIndex(parent, unique_position, bookmark_tracker);
+}
+
+// static
 std::vector<const syncer::UpdateResponseData*>
 BookmarkRemoteUpdatesHandler::ReorderUpdates(
     const syncer::UpdateResponseDataList* updates) {
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler.h b/components/sync_bookmarks/bookmark_remote_updates_handler.h
index 6f71b9f..8b501ff 100644
--- a/components/sync_bookmarks/bookmark_remote_updates_handler.h
+++ b/components/sync_bookmarks/bookmark_remote_updates_handler.h
@@ -56,6 +56,11 @@
     return valid_updates_without_full_title_;
   }
 
+  static size_t ComputeChildNodeIndexForTest(
+      const bookmarks::BookmarkNode* parent,
+      const sync_pb::UniquePosition& unique_position,
+      const SyncedBookmarkTracker* bookmark_tracker);
+
  private:
   // Reorders incoming updates such that parent creation is before child
   // creation and child deletion is before parent deletion, and deletions should
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc
index a927aec..26fed76 100644
--- a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc
+++ b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc
@@ -2035,6 +2035,94 @@
   EXPECT_TRUE(entity->has_final_guid());
 }
 
+TEST(BookmarkRemoteUpdatesHandlerTest,
+     ShouldComputeRightChildNodeIndexForEmptyParent) {
+  const std::string suffix = syncer::UniquePosition::RandomSuffix();
+  const syncer::UniquePosition pos1 =
+      syncer::UniquePosition::InitialPosition(suffix);
+
+  std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
+      bookmarks::TestBookmarkClient::CreateModel();
+  std::unique_ptr<SyncedBookmarkTracker> tracker =
+      SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
+          bookmark_model.get(),
+          CreateMetadataForPermanentNodes(bookmark_model.get()));
+
+  const bookmarks::BookmarkNode* bookmark_bar_node =
+      bookmark_model->bookmark_bar_node();
+
+  // Should always return 0 for any UniquePosition in the initial state.
+  EXPECT_EQ(0u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node, pos1.ToProto(), tracker.get()));
+}
+
+TEST(BookmarkRemoteUpdatesHandlerTest, ShouldComputeRightChildNodeIndex) {
+  std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
+      bookmarks::TestBookmarkClient::CreateModel();
+
+  const bookmarks::BookmarkNode* bookmark_bar_node =
+      bookmark_model->bookmark_bar_node();
+  const std::string suffix = syncer::UniquePosition::RandomSuffix();
+
+  const syncer::UniquePosition pos1 =
+      syncer::UniquePosition::InitialPosition(suffix);
+  const syncer::UniquePosition pos2 =
+      syncer::UniquePosition::After(pos1, suffix);
+  const syncer::UniquePosition pos3 =
+      syncer::UniquePosition::After(pos2, suffix);
+
+  // Create 3 nodes using remote update.
+  const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
+      bookmark_bar_node, /*index=*/0, /*title=*/base::string16());
+  const bookmarks::BookmarkNode* node2 = bookmark_model->AddFolder(
+      bookmark_bar_node, /*index=*/1, /*title=*/base::string16());
+  const bookmarks::BookmarkNode* node3 = bookmark_model->AddFolder(
+      bookmark_bar_node, /*index=*/2, /*title=*/base::string16());
+
+  sync_pb::BookmarkModelMetadata model_metadata =
+      CreateMetadataForPermanentNodes(bookmark_model.get());
+  *model_metadata.add_bookmarks_metadata() =
+      CreateNodeMetadata(node1->id(), "folder1_id", pos1);
+  *model_metadata.add_bookmarks_metadata() =
+      CreateNodeMetadata(node2->id(), "folder2_id", pos2);
+  *model_metadata.add_bookmarks_metadata() =
+      CreateNodeMetadata(node3->id(), "folder3_id", pos3);
+
+  std::unique_ptr<SyncedBookmarkTracker> tracker =
+      SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
+          bookmark_model.get(), std::move(model_metadata));
+
+  // Check for the same position as existing bookmarks have. In practice this
+  // shouldn't happen.
+  EXPECT_EQ(1u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node, pos1.ToProto(), tracker.get()));
+  EXPECT_EQ(2u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node, pos2.ToProto(), tracker.get()));
+  EXPECT_EQ(3u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node, pos3.ToProto(), tracker.get()));
+
+  EXPECT_EQ(0u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node,
+                    syncer::UniquePosition::Before(pos1, suffix).ToProto(),
+                    tracker.get()));
+  EXPECT_EQ(1u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node,
+                    syncer::UniquePosition::Between(/*before=*/pos1,
+                                                    /*after=*/pos2, suffix)
+                        .ToProto(),
+                    tracker.get()));
+  EXPECT_EQ(2u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node,
+                    syncer::UniquePosition::Between(/*before=*/pos2,
+                                                    /*after=*/pos3, suffix)
+                        .ToProto(),
+                    tracker.get()));
+  EXPECT_EQ(3u, BookmarkRemoteUpdatesHandler::ComputeChildNodeIndexForTest(
+                    bookmark_bar_node,
+                    syncer::UniquePosition::After(pos3, suffix).ToProto(),
+                    tracker.get()));
+}
+
 }  // namespace
 
 }  // namespace sync_bookmarks
diff --git a/components/sync_sessions/PRESUBMIT.py b/components/sync_sessions/PRESUBMIT.py
index 3768c7d..f375bb6 100644
--- a/components/sync_sessions/PRESUBMIT.py
+++ b/components/sync_sessions/PRESUBMIT.py
@@ -14,7 +14,7 @@
 
 def CheckChangeLintsClean(input_api, output_api):
   source_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=SYNC_SESSIONS_SOURCE_FILES, black_list=None)
+    x, files_to_check=SYNC_SESSIONS_SOURCE_FILES, files_to_skip=None)
   return input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
 
diff --git a/components/url_formatter/README.md b/components/url_formatter/README.md
new file mode 100644
index 0000000..bbe2582
--- /dev/null
+++ b/components/url_formatter/README.md
@@ -0,0 +1,15 @@
+The URL Formatter component contains utilities to convert between URLs and
+human-entered/human-readable strings.  Broadly, consuming human-entered URLs
+happens via "fixup", which tries to make "reasonable" adjustments to strings to
+convert them into URLs (e.g. auto-prepending schemes, but also many more, some
+of which may be surprising).  Producing human-readable URLs happens via
+"formatting", which can strip unimportant parts of the URL, unescape/decode
+sections, etc.
+
+These functions are meant to work in conjunction with the stricter, more limited
+capabilities of GURL, and were originally designed for use with the omnibox,
+though they've since been used in other parts of the UI as well.
+
+Because these functions are powerful, it's possible to introduce security risks
+with incautious use.  Be sure you understand what you need and what they're
+doing before using them; don't just copy existing callers.
diff --git a/components/webdata/README b/components/webdata/README
deleted file mode 100644
index a82334ca..0000000
--- a/components/webdata/README
+++ /dev/null
@@ -1,5 +0,0 @@
-WebData is not allowed to depend on content/, because it is used by iOS.
-If dependences on content/ need to be added to WebData, it will have to be made
-into a layered component: see
-http://www.chromium.org/developers/design-documents/layered-components-design
-for more information.
diff --git a/components/webdata/README.md b/components/webdata/README.md
new file mode 100644
index 0000000..88c6fb1
--- /dev/null
+++ b/components/webdata/README.md
@@ -0,0 +1,8 @@
+The webdata component manages the "web database", a SQLite database stored in
+the user's profile containing various webpage-related metadata such as autofill
+and web search engine data.
+
+This component is not allowed to depend on content/, because it is used by iOS.
+If dependencies on content/ need to be added, this component will have to be
+made into a layered component: see
+https://www.chromium.org/developers/design-documents/layered-components-design .
diff --git a/components/webdata_services/README.md b/components/webdata_services/README.md
new file mode 100644
index 0000000..11ecf5e
--- /dev/null
+++ b/components/webdata_services/README.md
@@ -0,0 +1,5 @@
+The webdata services component contains the wrappers used to access the specific
+services built atop the web database (see //components/webdata/).  Because there
+is a single database instance, the various services accessing different tables
+are created and destroyed together, and this component is what does that tying
+together.
diff --git a/content/browser/DEPS b/content/browser/DEPS
index ba84fad..14481d5 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -113,7 +113,6 @@
   "+third_party/blink/public/platform/web_fullscreen_video_status.h",
   "+third_party/blink/public/platform/web_mixed_content_context_type.h",
   "+third_party/blink/public/common/widget/screen_info.h",
-  "+third_party/blink/public/platform/web_text_autosizer_page_info.h",
   "+third_party/blink/public/platform/web_text_input_type.h",
   "+third_party/blink/public/platform/mac/web_scrollbar_theme.h",
   "+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h",
diff --git a/content/browser/accessibility/accessibility_event_recorder.h b/content/browser/accessibility/accessibility_event_recorder.h
index 6a9adf7..dfed6174 100644
--- a/content/browser/accessibility/accessibility_event_recorder.h
+++ b/content/browser/accessibility/accessibility_event_recorder.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/process/process_handle.h"
@@ -68,6 +69,8 @@
     callback_ = std::move(callback);
   }
 
+  void StopListeningToEvents() { callback_ = base::NullCallback(); }
+
   // Called to ensure the event recorder has finished recording async events.
   virtual void FlushAsyncEvents() {}
 
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc
index afeb78a..40ba95a 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -89,6 +89,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
 
   void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
                                        base::DictionaryValue* dict) const;
@@ -324,4 +325,8 @@
   return "@ANDROID-DENY-NODE:";
 }
 
+const std::string AccessibilityTreeFormatterAndroid::GetRunUntilEventString() {
+  return "@ANDROID-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
index 3266071..91f6ff6 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -36,6 +36,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
 
   base::string16 ProcessTreeForOutput(
       const base::DictionaryValue& node,
@@ -747,4 +748,9 @@
   return "@AURALINUX-DENY-NODE:";
 }
 
+const std::string
+AccessibilityTreeFormatterAuraLinux::GetRunUntilEventString() {
+  return "@AURALINUX-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
index 8820306..2f5be04 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -632,4 +632,8 @@
   return "@BLINK-DENY-NODE:";
 }
 
+const std::string AccessibilityTreeFormatterBlink::GetRunUntilEventString() {
+  return "@BLINK-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.h b/content/browser/accessibility/accessibility_tree_formatter_blink.h
index 29f82df..440ced2e 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_blink.h
+++ b/content/browser/accessibility/accessibility_tree_formatter_blink.h
@@ -42,6 +42,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
 
   void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
                                        base::DictionaryValue* dict) const;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index 6074fd6..d4ff1fc 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -110,6 +110,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
 
   void AddProperties(const BrowserAccessibilityCocoa* node,
                      const LineIndexesMap& line_indexes_map,
@@ -817,6 +818,10 @@
   return "@MAC-DENY-NODE:";
 }
 
+const std::string AccessibilityTreeFormatterMac::GetRunUntilEventString() {
+  return "@MAC-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
 
 #pragma clang diagnostic pop
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
index b718114..b751a10e 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
@@ -1200,4 +1200,8 @@
   return "@UIA-WIN-DENY-NODE:";
 }
 
+const std::string AccessibilityTreeFormatterUia::GetRunUntilEventString() {
+  return "@UIA-WIN-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h
index 45fbaaa..86c85f2 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h
+++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h
@@ -100,6 +100,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
   base::string16 ProcessTreeForOutput(
       const base::DictionaryValue& node,
       base::DictionaryValue* filtered_result = nullptr) override;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc
index cf876bc..f4f137e 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -71,6 +71,7 @@
   const std::string GetAllowString() override;
   const std::string GetDenyString() override;
   const std::string GetDenyNodeString() override;
+  const std::string GetRunUntilEventString() override;
   void AddProperties(const Microsoft::WRL::ComPtr<IAccessible>,
                      base::DictionaryValue* dict,
                      LONG root_x,
@@ -1036,4 +1037,8 @@
   return "@WIN-DENY-NODE:";
 }
 
+const std::string AccessibilityTreeFormatterWin::GetRunUntilEventString() {
+  return "@WIN-RUN-UNTIL-EVENT:";
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index cd07323..e1db266 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -171,7 +171,7 @@
     const std::string& no_load_expected_str = "@NO-LOAD-EXPECTED:";
     const std::string& wait_str = "@WAIT-FOR:";
     const std::string& execute_str = "@EXECUTE-AND-WAIT-FOR:";
-    const std::string& until_str = "@RUN-UNTIL-EVENT:";
+    const std::string& until_str = formatter_->GetRunUntilEventString();
     const std::string& default_action_on_str = "@DEFAULT-ACTION-ON:";
     if (base::StartsWith(line, allow_empty_str, base::CompareCase::SENSITIVE)) {
       property_filters_.push_back(
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index d430f19..35b8f41 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -93,13 +93,18 @@
   void RunEventTest(const base::FilePath::CharType* file_path);
 
  private:
+  void OnEventRecorded(AccessibilityNotificationWaiter* waiter,
+                       const std::string& event) {
+    waiter->Quit();
+  }
+
   base::string16 initial_tree_;
   base::string16 final_tree_;
 };
 
 bool IsRecordingComplete(AccessibilityEventRecorder& event_recorder,
                          std::vector<std::string>& run_until) {
-  // If no @RUN-UNTIL-EVENT directives, then having any events is enough.
+  // If no @*-RUN-UNTIL-EVENT directives, then having any events is enough.
   LOG(ERROR) << "=== IsRecordingComplete#1 run_until size=" << run_until.size();
   if (run_until.empty())
     return true;
@@ -145,16 +150,27 @@
     waiter.reset(new AccessibilityNotificationWaiter(
         shell()->web_contents(), ui::kAXModeComplete, ax::mojom::Event::kNone));
 
+    // It's possible for platform events to be received after all blink or
+    // generated events have been fired. Unblock the |waiter| when this happens.
+    event_recorder->ListenToEvents(
+        base::BindRepeating(&DumpAccessibilityEventsTest::OnEventRecorded,
+                            base::Unretained(this), waiter.get()));
+
     base::Value go_results =
         ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "go()");
     run_go_again = go_results.is_bool() && go_results.GetBool();
 
     for (;;) {
-      waiter->WaitForNotification();  // Run at least once.
+      // Wait for at least one event. This may unblock either when |waiter|
+      // observes either an ax::mojom::Event or ui::AXEventGenerator::Event, or
+      // when |event_recorder| records a platform event.
+      waiter->WaitForNotification();
       if (IsRecordingComplete(*event_recorder, run_until))
         break;
     }
 
+    event_recorder->StopListeningToEvents();
+
     // More than one accessibility event could have been generated.
     // To make sure we've received all accessibility events, add a
     // sentinel by calling SignalEndOfTest and waiting for a kEndOfTest
@@ -529,6 +545,22 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsAriaHiddenDescendants) {
+  RunEventTest(FILE_PATH_LITERAL("aria-hidden-descendants.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsAriaHiddenDescendantsAlreadyIgnored) {
+  RunEventTest(
+      FILE_PATH_LITERAL("aria-hidden-descendants-already-ignored.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsCSSDisplayDescendants) {
+  RunEventTest(FILE_PATH_LITERAL("css-display-descendants.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
                        AccessibilityEventsCSSFlexTextUpdate) {
   RunEventTest(FILE_PATH_LITERAL("css-flex-text-update.html"));
 }
@@ -539,6 +571,11 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsCSSVisibilityDescendants) {
+  RunEventTest(FILE_PATH_LITERAL("css-visibility-descendants.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
                        AccessibilityEventsCSSCollapse) {
   RunEventTest(FILE_PATH_LITERAL("css-visibility-collapse.html"));
 }
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 5a75e00..4d8877a4 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -346,6 +346,21 @@
 }
 
 // static
+void BrowserContext::FirePushSubscriptionChangeEvent(
+    BrowserContext* browser_context,
+    const GURL& origin,
+    int64_t service_worker_registration_id,
+    blink::mojom::PushSubscriptionPtr new_subscription,
+    blink::mojom::PushSubscriptionPtr old_subscription,
+    base::OnceCallback<void(blink::mojom::PushDeliveryStatus)> callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  PushMessagingRouter::FireSubscriptionChangeEvent(
+      browser_context, origin, service_worker_registration_id,
+      std::move(new_subscription), std::move(old_subscription),
+      std::move(callback));
+}
+
+// static
 void BrowserContext::NotifyWillBeDestroyed(BrowserContext* browser_context) {
   TRACE_EVENT1("shutdown", "BrowserContext::NotifyWillBeDestroyed",
                "browser_context", browser_context);
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index bd599f8..4d70646 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -218,6 +218,10 @@
   return std::string();
 }
 
+bool DevToolsAgentHostImpl::CanAccessOpener() {
+  return false;
+}
+
 std::string DevToolsAgentHostImpl::GetDescription() {
   return std::string();
 }
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index 3e8e4a8..ac5abf76 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -40,6 +40,7 @@
       scoped_refptr<base::RefCountedMemory> data) override;
   std::string GetParentId() override;
   std::string GetOpenerId() override;
+  bool CanAccessOpener() override;
   std::string GetDescription() override;
   GURL GetFaviconURL() override;
   std::string GetFrontendURL() override;
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc
index ecb7483..cd06933 100644
--- a/content/browser/devtools/protocol/target_handler.cc
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -85,6 +85,7 @@
           .SetUrl(host->GetURL().spec())
           .SetType(host->GetType())
           .SetAttached(host->IsAttached())
+          .SetCanAccessOpener(host->CanAccessOpener())
           .Build();
   if (!host->GetOpenerId().empty())
     target_info->SetOpenerId(host->GetOpenerId());
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 33fb314..6b7d5286 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -668,6 +668,10 @@
   return opener ? opener->devtools_frame_token().ToString() : std::string();
 }
 
+bool RenderFrameDevToolsAgentHost::CanAccessOpener() {
+  return (frame_tree_node_ && frame_tree_node_->opener());
+}
+
 std::string RenderFrameDevToolsAgentHost::GetType() {
   if (web_contents() &&
       static_cast<WebContentsImpl*>(web_contents())->IsPortal()) {
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index 9bacadd..f366576 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -88,6 +88,7 @@
   WebContents* GetWebContents() override;
   std::string GetParentId() override;
   std::string GetOpenerId() override;