diff --git a/DEPS b/DEPS
index 0385c33..729c68ef 100644
--- a/DEPS
+++ b/DEPS
@@ -162,7 +162,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '9e5c47936b171e03978bfe2611e71157d34bc539',
+  'skia_revision': 'a47836e01af99b1ace19fdc35d7f0df47718d7d6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -174,7 +174,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': '58c5b07b47cf30cf970e27d39fc88d08f51a5907',
+  'angle_revision': '79ad0411911b2fc84834c3705f55707be9e4b498',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -281,7 +281,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': '76261e2a7df1fda011a5edd7a894c42b4fa6af95',
+  'spv_tools_revision': '7f7236f1eba0afae2669ea777896f0435be4c96d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1246,7 +1246,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '23d211c88c92518846537e05293ab015b25af940',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c85e95e7f84b90619edc118575ee15abd6dc3514',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1414,7 +1414,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'c77df78931bca91f3e35343b038ba4ad986b1ab4',
+    Var('webrtc_git') + '/src.git' + '@' + '45b01c7962da7bbd08a35ba59ad3e360457c6563',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1455,7 +1455,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b09e9fc89fa7507f180b1bec9e6663458f91120e',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c1ec0cbb921b362d60fb4e5f7dc95d49e804c746',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/assistant/assistant_interaction_controller.cc b/ash/assistant/assistant_interaction_controller.cc
index 5f7c43b6..3c69811d 100644
--- a/ash/assistant/assistant_interaction_controller.cc
+++ b/ash/assistant/assistant_interaction_controller.cc
@@ -73,8 +73,7 @@
 
 AssistantInteractionController::AssistantInteractionController(
     AssistantController* assistant_controller)
-    : assistant_controller_(assistant_controller),
-      assistant_interaction_subscriber_binding_(this) {
+    : assistant_controller_(assistant_controller) {
   AddModelObserver(this);
   assistant_controller_->AddObserver(this);
   Shell::Get()->highlighter_controller()->AddObserver(this);
@@ -91,9 +90,8 @@
   assistant_ = assistant;
 
   // Subscribe to Assistant interaction events.
-  chromeos::assistant::mojom::AssistantInteractionSubscriberPtr ptr;
-  assistant_interaction_subscriber_binding_.Bind(mojo::MakeRequest(&ptr));
-  assistant_->AddAssistantInteractionSubscriber(std::move(ptr));
+  assistant_->AddAssistantInteractionSubscriber(
+      assistant_interaction_subscriber_receiver_.BindNewPipeAndPassRemote());
 }
 
 void AssistantInteractionController::AddModelObserver(
diff --git a/ash/assistant/assistant_interaction_controller.h b/ash/assistant/assistant_interaction_controller.h
index f2419c1..927e8bf48 100644
--- a/ash/assistant/assistant_interaction_controller.h
+++ b/ash/assistant/assistant_interaction_controller.h
@@ -19,7 +19,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace ash {
 
@@ -138,8 +138,8 @@
   // Owned by AssistantController.
   chromeos::assistant::mojom::Assistant* assistant_ = nullptr;
 
-  mojo::Binding<chromeos::assistant::mojom::AssistantInteractionSubscriber>
-      assistant_interaction_subscriber_binding_;
+  mojo::Receiver<chromeos::assistant::mojom::AssistantInteractionSubscriber>
+      assistant_interaction_subscriber_receiver_{this};
 
   AssistantInteractionModel model_;
 
diff --git a/ash/assistant/test/test_assistant_service.h b/ash/assistant/test/test_assistant_service.h
index f4ed2a3..5fea364 100644
--- a/ash/assistant/test/test_assistant_service.h
+++ b/ash/assistant/test/test_assistant_service.h
@@ -32,8 +32,9 @@
                                      bool allow_tts) override {}
   void StopActiveInteraction(bool cancel_conversation) override {}
   void AddAssistantInteractionSubscriber(
-      chromeos::assistant::mojom::AssistantInteractionSubscriberPtr subscriber)
-      override {}
+      mojo::PendingRemote<
+          chromeos::assistant::mojom::AssistantInteractionSubscriber>
+          subscriber) override {}
   void RetrieveNotification(
       chromeos::assistant::mojom::AssistantNotificationPtr notification,
       int action_index) override {}
diff --git a/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc b/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc
index 9ee7a84..39bd02c 100644
--- a/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc
+++ b/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc
@@ -240,8 +240,9 @@
   ASSERT_FALSE(LaunchTimeoutRunning());
 }
 
+// TODO(crbug.com/1002488): Test is flaky.
 TEST_F(LockScreenNoteDisplayStateHandlerTest,
-       EjectWhenScreenOffAndNoteNotAvailable) {
+       DISABLED_EjectWhenScreenOffAndNoteNotAvailable) {
   TurnScreenOffForUserInactivity();
 
   Shell::Get()->tray_action()->UpdateLockScreenNoteState(
diff --git a/ash/login/ui/parent_access_view.cc b/ash/login/ui/parent_access_view.cc
index d0745af..292fa69b 100644
--- a/ash/login/ui/parent_access_view.cc
+++ b/ash/login/ui/parent_access_view.cc
@@ -842,6 +842,7 @@
       title_label_->SetEnabledColor(kErrorColor);
       title_label_->SetText(
           l10n_util::GetStringUTF16(IDS_ASH_LOGIN_PARENT_ACCESS_TITLE_ERROR));
+      title_label_->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
       return;
     }
   }
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc b/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc
index 8f81cfd..335153b9 100644
--- a/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc
+++ b/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc
@@ -36,11 +36,9 @@
   connector_->Connect(device::mojom::kServiceName,
                       bluetooth_system_factory.BindNewPipeAndPassReceiver());
 
-  device::mojom::BluetoothSystemClientPtr client_ptr;
-  bluetooth_system_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
-
   bluetooth_system_factory->Create(
-      bluetooth_system_.BindNewPipeAndPassReceiver(), std::move(client_ptr));
+      bluetooth_system_.BindNewPipeAndPassReceiver(),
+      bluetooth_system_client_receiver_.BindNewPipeAndPassRemote());
   bluetooth_system_->GetState(
       base::BindOnce(&TrayBluetoothHelperExperimental::OnStateChanged,
                      // See base::Unretained() note at the top.
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_experimental.h b/ash/system/bluetooth/tray_bluetooth_helper_experimental.h
index 9959a55..f9faf7b 100644
--- a/ash/system/bluetooth/tray_bluetooth_helper_experimental.h
+++ b/ash/system/bluetooth/tray_bluetooth_helper_experimental.h
@@ -10,7 +10,7 @@
 #include "ash/ash_export.h"
 #include "ash/system/bluetooth/tray_bluetooth_helper.h"
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/device/public/mojom/bluetooth_system.mojom.h"
 
@@ -49,8 +49,8 @@
   service_manager::Connector* connector_;
 
   mojo::Remote<device::mojom::BluetoothSystem> bluetooth_system_;
-  mojo::Binding<device::mojom::BluetoothSystemClient>
-      bluetooth_system_client_binding_{this};
+  mojo::Receiver<device::mojom::BluetoothSystemClient>
+      bluetooth_system_client_receiver_{this};
 
   device::mojom::BluetoothSystem::State cached_state_ =
       device::mojom::BluetoothSystem::State::kUnavailable;
diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java
index 8594e60d..4c5eaee8 100644
--- a/base/android/java/src/org/chromium/base/ContentUriUtils.java
+++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java
@@ -20,7 +20,6 @@
 import org.chromium.base.annotations.CalledByNative;
 
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 
 /**
@@ -165,12 +164,8 @@
                     return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
                 }
             }
-        } catch (FileNotFoundException e) {
-            Log.w(TAG, "Cannot find content uri: " + uriString, e);
-        } catch (SecurityException e) {
-            Log.w(TAG, "Cannot open content uri: " + uriString, e);
         } catch (Exception e) {
-            Log.w(TAG, "Unknown content uri: " + uriString, e);
+            Log.w(TAG, "Cannot open content uri: %s", uriString, e);
         }
         return null;
     }
@@ -238,7 +233,7 @@
             // There are a few Exceptions we can hit here (e.g. SecurityException), but we don't
             // particularly care what kind of Exception we hit. If we hit one, just don't return a
             // display name.
-            Log.w(TAG, "Cannot open content uri: " + uriString, e);
+            Log.w(TAG, "Cannot open content uri: %s", uriString, e);
         }
 
         // If we are unable to query the content URI, just return null.
@@ -323,7 +318,7 @@
             }
         } catch (IllegalArgumentException e) {
             // This happens when the given File is outside the paths supported by the provider.
-            Log.e(TAG, "Cannot retrieve content uri from file: " + filePathString, e);
+            Log.e(TAG, "Cannot retrieve content uri from file: %s", filePathString, e);
         }
         return null;
     }
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc
index 6812646..18db689 100644
--- a/base/process/process_unittest.cc
+++ b/base/process/process_unittest.cc
@@ -271,13 +271,7 @@
 // backgrounding and restoring.
 // Note: a platform may not be willing or able to lower the priority of
 // a process. The calls to SetProcessBackground should be noops then.
-// Flaky on Windows: https://crbug.com/931721.
-#if defined(OS_WIN)
-#define MAYBE_SetProcessBackgrounded DISABLED_SetProcessBackgrounded
-#else
-#define MAYBE_SetProcessBackgrounded SetProcessBackgrounded
-#endif
-TEST_F(ProcessTest, MAYBE_SetProcessBackgrounded) {
+TEST_F(ProcessTest, SetProcessBackgrounded) {
   if (!Process::CanBackgroundProcesses())
     return;
   Process process(SpawnChild("SimpleChildProcess"));
@@ -305,15 +299,9 @@
   EXPECT_EQ(old_priority, new_priority);
 }
 
-// Flaky on Windows: https://crbug.com/931721.
-#if defined(OS_WIN)
-#define MAYBE_SetProcessBackgroundedSelf DISABLED_SetProcessBackgroundedSelf
-#else
-#define MAYBE_SetProcessBackgroundedSelf SetProcessBackgroundedSelf
-#endif
 // Same as SetProcessBackgrounded but to this very process. It uses
 // a different code path at least for Windows.
-TEST_F(ProcessTest, MAYBE_SetProcessBackgroundedSelf) {
+TEST_F(ProcessTest, SetProcessBackgroundedSelf) {
   if (!Process::CanBackgroundProcesses())
     return;
   Process process = Process::Current();
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index dd3a0986..ea52fc2 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1675,12 +1675,6 @@
     ]
   }
 
-  java_cpp_enum("signin_metrics_enum_javagen") {
-    sources = [
-      "../components/signin/public/base/signin_metrics.h",
-    ]
-  }
-
   java_cpp_enum("assist_ranker_prediction_enum_javagen") {
     sources = [
       "browser/android/contextualsearch/contextual_search_ranker_logger_impl.h",
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index ba2c5070..ce24a80 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -420,7 +420,6 @@
     "//chrome:payments_journey_logger_enum_javagen",
     "//chrome:pref_enum_javagen",
     "//chrome:quick_action_category_enum_javagen",
-    "//chrome:signin_metrics_enum_javagen",
     "//chrome/browser/notifications/scheduler/public:jni_enums",
     "//chrome/browser:sharing_device_capability_generated_enum",
     "//chrome/browser:sharing_send_message_result_generated_enum",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java
index 456ffb7..5f3f68b 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java
@@ -222,7 +222,8 @@
             if (availablePaymentMethods == null) availablePaymentMethods = Collections.emptyList();
             view.mPaymentMethodSection.onAvailablePaymentMethodsChanged(availablePaymentMethods);
             return true;
-        } else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PROFILES) {
+        } else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PROFILES
+                || propertyKey == AssistantCollectUserDataModel.DEFAULT_EMAIL) {
             List<PersonalDataManager.AutofillProfile> autofillProfiles =
                     model.get(AssistantCollectUserDataModel.AVAILABLE_PROFILES);
             if (autofillProfiles == null) {
@@ -232,7 +233,8 @@
                 view.mContactDetailsSection.onProfilesChanged(autofillProfiles,
                         model.get(AssistantCollectUserDataModel.REQUEST_EMAIL),
                         model.get(AssistantCollectUserDataModel.REQUEST_NAME),
-                        model.get(AssistantCollectUserDataModel.REQUEST_PHONE));
+                        model.get(AssistantCollectUserDataModel.REQUEST_PHONE),
+                        model.get(AssistantCollectUserDataModel.DEFAULT_EMAIL));
             }
             if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
                 view.mPaymentMethodSection.onProfilesChanged(autofillProfiles);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
index 1be147b..0a03bf9 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
@@ -59,6 +59,10 @@
     /** The status of the third party terms & conditions. */
     public static final WritableIntPropertyKey TERMS_STATUS = new WritableIntPropertyKey();
 
+    /** The email address of the preferred profile. */
+    public static final WritableObjectPropertyKey<String> DEFAULT_EMAIL =
+            new WritableObjectPropertyKey<>();
+
     public static final WritableBooleanPropertyKey REQUEST_NAME = new WritableBooleanPropertyKey();
     public static final WritableBooleanPropertyKey REQUEST_EMAIL = new WritableBooleanPropertyKey();
     public static final WritableBooleanPropertyKey REQUEST_PHONE = new WritableBooleanPropertyKey();
@@ -102,8 +106,8 @@
 
     public AssistantCollectUserDataModel() {
         super(DELEGATE, WEB_CONTENTS, VISIBLE, SHIPPING_ADDRESS, PAYMENT_METHOD, CONTACT_DETAILS,
-                LOGIN_SECTION_TITLE, SELECTED_LOGIN, TERMS_STATUS, REQUEST_NAME, REQUEST_EMAIL,
-                REQUEST_PHONE, REQUEST_SHIPPING_ADDRESS, REQUEST_PAYMENT,
+                LOGIN_SECTION_TITLE, SELECTED_LOGIN, TERMS_STATUS, DEFAULT_EMAIL, REQUEST_NAME,
+                REQUEST_EMAIL, REQUEST_PHONE, REQUEST_SHIPPING_ADDRESS, REQUEST_PAYMENT,
                 ACCEPT_TERMS_AND_CONDITIONS_TEXT, SHOW_TERMS_AS_CHECKBOX, REQUEST_LOGIN_CHOICE,
                 AVAILABLE_PROFILES, AVAILABLE_AUTOFILL_PAYMENT_METHODS,
                 SUPPORTED_BASIC_CARD_NETWORKS, SUPPORTED_PAYMENT_METHODS, AVAILABLE_LOGINS,
@@ -122,6 +126,7 @@
         set(REQUEST_SHIPPING_ADDRESS, false);
         set(REQUEST_LOGIN_CHOICE, false);
         set(REQUIRE_BILLING_POSTAL_CODE, false);
+        set(DEFAULT_EMAIL, "");
     }
 
     @CalledByNative
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
index 662f0c69..2baba4d4 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
@@ -108,7 +108,7 @@
      * set of profiles, while keeping the selected item if possible.
      */
     void onProfilesChanged(List<AutofillProfile> profiles, boolean requestPayerEmail,
-            boolean requestPayerName, boolean requestPayerPhone) {
+            boolean requestPayerName, boolean requestPayerPhone, String defaultEmail) {
         if (mIgnoreProfileChangeNotifications) {
             return;
         }
@@ -141,6 +141,17 @@
             }
         }
 
+        // Default selection: select most complete profile with the default email, if possible.
+        if (selectedContactIndex == -1 && !defaultEmail.isEmpty()) {
+            // Note: contacts are already sorted by completeness.
+            for (int i = 0; i < contacts.size(); i++) {
+                if (TextUtils.equals(contacts.get(i).getPayerEmail(), defaultEmail)) {
+                    selectedContactIndex = i;
+                    break;
+                }
+            }
+        }
+
         // Replace current set of items, keep selection if possible.
         setItems(contacts, selectedContactIndex);
     }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
index a4d0fdd4..6c9357c 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
@@ -683,6 +683,48 @@
         return viewHolder;
     }
 
+    /**
+     * If the default email is set, the most complete profile with that email address should be
+     * default-selected.
+     */
+    @Test
+    @MediumTest
+    public void testDefaultEmail() throws Exception {
+        AssistantCollectUserDataModel model = new AssistantCollectUserDataModel();
+        AssistantCollectUserDataCoordinator coordinator = createCollectUserDataCoordinator(model);
+        AutofillAssistantCollectUserDataTestHelper.MockDelegate delegate =
+                new AutofillAssistantCollectUserDataTestHelper.MockDelegate();
+        AutofillAssistantCollectUserDataTestHelper
+                .ViewHolder viewHolder = TestThreadUtils.runOnUiThreadBlocking(
+                () -> new AutofillAssistantCollectUserDataTestHelper.ViewHolder(coordinator));
+
+        /* Set up fake profiles such that the correct default choice is last. */
+        mHelper.addDummyProfile("Jane Doe", "jane@gmail.com", "98004");
+        mHelper.addDummyProfile("", "joe@gmail.com", "");
+        mHelper.addDummyProfile("Joe Doe", "joe@gmail.com", "98004");
+
+        /* Request all PR sections. */
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            model.set(AssistantCollectUserDataModel.REQUEST_NAME, true);
+            model.set(AssistantCollectUserDataModel.REQUEST_EMAIL, true);
+            model.set(AssistantCollectUserDataModel.DEFAULT_EMAIL, "joe@gmail.com");
+            model.set(AssistantCollectUserDataModel.DELEGATE, delegate);
+            model.set(AssistantCollectUserDataModel.VISIBLE, true);
+        });
+
+        for (int i = 0; i < viewHolder.mContactList.getItemCount(); i++) {
+            if (viewHolder.mContactList.isChecked(viewHolder.mContactList.getItem(i))) {
+                testContact("joe@gmail.com", "Joe Doe\njoe@gmail.com",
+                        viewHolder.mContactSection.getCollapsedView(),
+                        viewHolder.mContactList.getItem(i));
+                break;
+            }
+        }
+
+        assertThat(delegate.mContact.getPayerEmail(), is("joe@gmail.com"));
+        assertThat(delegate.mContact.getPayerName(), is("Joe Doe"));
+    }
+
     private View getPaymentSummaryErrorView(ViewHolder viewHolder) {
         return viewHolder.mPaymentSection.findViewById(R.id.payment_method_summary)
                 .findViewById(R.id.incomplete_error);
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
index ae51e39..22b2c3d 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
@@ -8,7 +8,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/keyboard_accessory"
     android:layout_gravity="start|bottom"
-    android:contentDescription="@string/autofill_keyboard_accessory_content_description"
+    android:contentDescription="@string/autofill_keyboard_accessory_modern_content_description"
     android:scrollbars="none"
     android:visibility="gone"
     android:orientation="vertical"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings.grd b/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings.grd
index 99044d0..1f82297c 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings.grd
+++ b/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings.grd
@@ -103,9 +103,12 @@
   </translations>
   <release allow_pseudo="false" seq="1">
     <messages fallback_to_english="true">
-      <message name="IDS_AUTOFILL_KEYBOARD_ACCESSORY_CONTENT_DESCRIPTION" desc="The text announced by the screen reader when the autofill suggestions are shown.">
+      <message name="IDS_AUTOFILL_KEYBOARD_ACCESSORY_CONTENT_DESCRIPTION" desc="The text announced by the screen reader when the password suggestions are shown.">
         Passwords available
       </message>
+      <message name="IDS_AUTOFILL_KEYBOARD_ACCESSORY_MODERN_CONTENT_DESCRIPTION" desc="The text announced by the screen reader when the autofill suggestions and fallbacks are shown.">
+        Filling suggestions available in keyboard accessory
+      </message>
       <message name="IDS_KEYBOARD_ACCESSORY_SHEET_HIDE" desc="Description for the active icon button that closes an accessory sheet and brings back the keyboard.">
           Show keyboard
       </message>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings_grd/IDS_AUTOFILL_KEYBOARD_ACCESSORY_MODERN_CONTENT_DESCRIPTION.png.sha1 b/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings_grd/IDS_AUTOFILL_KEYBOARD_ACCESSORY_MODERN_CONTENT_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..a74a6a9
--- /dev/null
+++ b/chrome/android/features/keyboard_accessory/internal/java/strings/android_keyboard_accessory_strings_grd/IDS_AUTOFILL_KEYBOARD_ACCESSORY_MODERN_CONTENT_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+d943c1c4c060f60baed75b91d2e9273302ea7f5c
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
index 7e0fea6..8d77aaa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
@@ -20,7 +20,6 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
@@ -29,6 +28,7 @@
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountsChangeObserver;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.components.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java
index bc4ebf6..1f5ef62 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java
@@ -225,7 +225,7 @@
     private float mMaximumHeight;
 
     private boolean mIsFullWidthSizePanelForTesting;
-    protected boolean mOverrideIsFullWidthSizePanelForTesting;
+    private boolean mOverrideIsFullWidthSizePanelForTesting;
 
     /**
      * Called when the layout has changed.
@@ -264,9 +264,8 @@
      * @return Whether the given width matches the criteria required for a full width Panel.
      */
     protected boolean doesMatchFullWidthCriteria(float containerWidth) {
-        if (mOverrideIsFullWidthSizePanelForTesting) {
-            return mIsFullWidthSizePanelForTesting;
-        }
+        if (mOverrideIsFullWidthSizePanelForTesting) return mIsFullWidthSizePanelForTesting;
+
         return containerWidth <= SMALL_PANEL_WIDTH_THRESHOLD_DP;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index 805439c8..0b22d63a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -391,15 +391,6 @@
         return getBarHeight() + getBarBannerControl().getHeightPeekingPx() * mPxToDp;
     }
 
-    @Override
-    protected boolean doesMatchFullWidthCriteria(float containerWidth) {
-        if (!mOverrideIsFullWidthSizePanelForTesting && mActivity != null
-                && mActivity.getBottomSheet() != null) {
-            return true;
-        }
-        return super.doesMatchFullWidthCriteria(containerWidth);
-    }
-
     // ============================================================================================
     // Animation Handling
     // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
index a1940daf..d0cf9e725 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
@@ -376,7 +376,7 @@
             List<ContactsPickerListener.Contact> contacts, int umaId) {
         int selectCount = contacts != null ? contacts.size() : 0;
         int contactCount = mPickerAdapter.getAllContacts().size();
-        int percentageShared = (100 * selectCount) / contactCount;
+        int percentageShared = contactCount > 0 ? (100 * selectCount) / contactCount : 0;
 
         int propertiesRequested = ContactsPickerPropertiesRequested.PROPERTIES_NONE;
         if (includeNames) propertiesRequested |= ContactsPickerPropertiesRequested.PROPERTIES_NAMES;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
index d81302c..ed4e05e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
@@ -11,10 +11,10 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ntp.cards.SignInPromo;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninFragmentBase;
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.components.signin.ChildAccountStatus;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 /** A {@link Fragment} to handle sign-in within the first run experience. */
 public class SigninFirstRunFragment extends SigninFragmentBase implements FirstRunFragment {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
index cf3badb..32880feb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -22,7 +22,6 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
@@ -31,6 +30,7 @@
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountsChangeObserver;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.components.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
index babce97f..781e8a6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -31,11 +31,11 @@
 import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession;
 import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab;
 import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionWindow;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SyncPromoView;
 import org.chromium.chrome.browser.util.UrlUtilities;
 import org.chromium.chrome.browser.util.ViewUtils;
 import org.chromium.chrome.browser.widget.RoundedIconGenerator;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.mojom.WindowOpenDisposition;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index b5f5bcc..d1a3c20 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -14,13 +14,13 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountsChangeObserver;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 /**
  * Shows a card prompting the user to sign in. This item is also an {@link OptionalLeaf}, and sign
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java
index 65a6a41..5f14a5af 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java
@@ -43,11 +43,11 @@
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninUtils;
-import org.chromium.chrome.browser.signin.SignoutReason;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ChromeSigninController;
 import org.chromium.components.signin.GAIAServiceType;
+import org.chromium.components.signin.metrics.SignoutReason;
 
 import java.util.List;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
index 593498e..007aa1a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
@@ -21,7 +21,6 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninActivity;
 import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
@@ -32,6 +31,7 @@
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountsChangeObserver;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.sync.AndroidSyncSettings;
 
 import java.lang.annotation.Retention;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java
index 8244a12..11f2356 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java
@@ -51,7 +51,6 @@
 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SignoutReason;
 import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge;
 import org.chromium.chrome.browser.sync.GoogleServiceAuthError;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
@@ -59,6 +58,7 @@
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.ui.UiUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
index cc14d14..fb8b436a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
@@ -16,9 +16,9 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SigninHelper;
 import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SignoutReason;
 import org.chromium.chrome.browser.sync.SyncController;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SignoutReason;
 
 /**
  * Starts and monitors various sync and Google services related tasks.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java
index 019fd3d..ddef85c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java
@@ -18,6 +18,7 @@
 import org.chromium.chrome.browser.ChromeBaseAppCompatActivity;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
index 9fa39d50..7d0a7c37 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.preferences.sync.SyncAndServicesPreferences;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
index 7b8420d3..d90f574 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -27,6 +27,7 @@
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.components.signin.ChromeSigninController;
 import org.chromium.components.signin.OAuth2TokenService;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 
 import java.io.IOException;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
index 1ff51a8..91882b8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -33,6 +33,9 @@
 import org.chromium.components.signin.ChromeSigninController;
 import org.chromium.components.signin.identitymanager.CoreAccountInfo;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
+import org.chromium.components.signin.metrics.SigninReason;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoController.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoController.java
index f6da7f7b..f92f5f8e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoController.java
@@ -21,6 +21,7 @@
 import org.chromium.chrome.browser.metrics.ImpressionTracker;
 import org.chromium.chrome.browser.metrics.OneShotImpressionListener;
 import org.chromium.chrome.browser.signin.SigninActivity.AccessPoint;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 /**
  * A controller for configuring the sign in promo. It sets up the sign in promo depending on the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
index 1fd147a..d2705c39d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.ui.base.WindowAndroid;
 
 import java.util.Collections;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java
index c5f314586..5755f55 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java
@@ -21,6 +21,7 @@
 import org.chromium.chrome.browser.preferences.sync.SyncAndServicesPreferences;
 import org.chromium.chrome.browser.signin.SigninActivity.AccessPoint;
 import org.chromium.chrome.browser.util.IntentUtils;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.components.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
@@ -212,4 +213,4 @@
         // AndroidSyncSettings calls this method from non-UI threads.
         PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, this::update);
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
index 6de0de7f..8bb36bb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
@@ -35,13 +35,13 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninActivity;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ProfileDataSource;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.signin.test.util.AccountHolder;
 import org.chromium.components.signin.test.util.AccountManagerTestRule;
 import org.chromium.components.signin.test.util.FakeAccountManagerDelegate;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
index 8d8785f..4ead758 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
@@ -240,7 +240,7 @@
     }
 
     private void dismissDialog() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> mDialog.dismiss());
+        TestThreadUtils.runOnUiThreadBlocking(() -> mDialog.cancel());
     }
 
     private TopView getTopView() throws Exception {
@@ -516,4 +516,17 @@
         clickSearchButton();
         dismissDialog();
     }
+
+    @Test
+    @LargeTest
+    public void testEmptyContactListCrash() throws Throwable {
+        PickerAdapter.setTestContacts(new ArrayList<ContactDetails>());
+
+        createDialog(/* multiselect = */ true, /* includeNames = */ true,
+                /* includeEmails = */ true,
+                /* includeTel = */ true);
+        Assert.assertTrue(mDialog.isShowing());
+
+        dismissDialog();
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index 5036cac3..634bc0a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -231,8 +231,8 @@
             }
         });
 
-        TestTouchUtils.singleClickView(
-                InstrumentationRegistry.getInstrumentation(), tab.getView(), 0, 0);
+        TestTouchUtils.singleClickView(InstrumentationRegistry.getInstrumentation(), tab.getView(),
+                tab.getView().getWidth() - 5, tab.getView().getHeight() - 5);
 
         CriteriaHelper.pollUiThread(new Criteria("Activity did not regain focus.") {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
index e75fde2..def3b35 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
@@ -178,8 +178,8 @@
             }
         });
 
-        TestTouchUtils.singleClickView(
-                InstrumentationRegistry.getInstrumentation(), tab.getView(), 0, 0);
+        TestTouchUtils.singleClickView(InstrumentationRegistry.getInstrumentation(), tab.getView(),
+                tab.getView().getWidth() - 5, tab.getView().getHeight() - 5);
 
         CriteriaHelper.pollUiThread(new Criteria("Activity did not regain focus.") {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
index 743dd57c..b9d776b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -50,7 +50,6 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
-import org.chromium.chrome.browser.signin.SignoutReason;
 import org.chromium.chrome.browser.widget.DateDividedAdapter;
 import org.chromium.chrome.browser.widget.selection.SelectableItemView;
 import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder;
@@ -59,6 +58,7 @@
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
index 6bdb3b0..effa6b2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -47,7 +47,6 @@
 import org.chromium.chrome.browser.ntp.cards.PersonalizedPromoViewHolder;
 import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo;
 import org.chromium.chrome.browser.signin.DisplayableProfileData;
-import org.chromium.chrome.browser.signin.SigninAccessPoint;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.browser.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction;
@@ -71,6 +70,7 @@
 import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
 import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.NetworkChangeNotifier;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
index 5c4bcbd6..c356b093 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
@@ -43,6 +43,7 @@
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.components.bookmarks.BookmarkId;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.browser.test.util.TestTouchUtils;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
index 062a79a..a9cf7a5c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -20,11 +20,11 @@
 import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory;
 import org.chromium.chrome.browser.identity.UuidBasedUniqueIdentificationGenerator;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SignoutReason;
 import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.protocol.AutofillWalletSpecifics;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
index e8686fc..d58e391 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -36,6 +36,7 @@
 import org.chromium.components.signin.identitymanager.CoreAccountId;
 import org.chromium.components.signin.identitymanager.CoreAccountInfo;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 
 import java.util.concurrent.atomic.AtomicInteger;
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni
index a58b8b09..70a2070 100644
--- a/chrome/android/trichrome.gni
+++ b/chrome/android/trichrome.gni
@@ -108,21 +108,29 @@
     }
 
     if (android_64bit_target_cpu) {
-      # Include the actual browser-bitness libmonochrome library, and an
-      # opposite-bitness placeholder library to ensure that the library is
-      # treated as multiarch and gets its Java code precompiled for both
-      # architectures.
+      # Include the actual browser-bitness libmonochrome library, dependencies
+      # (crashpad and linker), and an opposite-bitness placeholder library to
+      # ensure that the library is treated as multiarch and gets its Java code
+      # precompiled for both architectures.
       native_lib_placeholders = [ "libdummy.so" ]
       if (build_apk_secondary_abi) {
         secondary_abi_shared_libraries =
             [ "//chrome/android:monochrome_secondary_abi_lib" ]
 
         _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+
         deps += [ _trampoline ]
         _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
         secondary_abi_loadable_modules =
             [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
       }
+
+      if (use_chromium_linker) {
+        deps += [ "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" ]
+        secondary_abi_loadable_modules +=
+            [ "$_secondary_out_dir/libchromium_android_linker.so" ]
+      }
+
       if (trichrome_shared_assets) {
         deps += [ "//android_webview:v8_snapshot_secondary_abi_assets" ]
       }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 05afeb7b..5cef9b9 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -144,7 +144,6 @@
 #include "services/network/public/cpp/network_switches.h"
 #include "services/service_manager/sandbox/features.h"
 #include "services/service_manager/sandbox/switches.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "third_party/blink/public/common/experiments/memory_ablation_experiment.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/forcedark/forcedark_switches.h"
@@ -3749,11 +3748,6 @@
      kOsAll,
      FEATURE_VALUE_TYPE(features::kEnableAmbientAuthenticationInGuestSession)},
 
-    {"enable-filesystem-in-incognito",
-     flag_descriptions::kEnableFilesystemInIncognitoName,
-     flag_descriptions::kEnableFilesystemInIncognitoDescription, kOsAll,
-     FEATURE_VALUE_TYPE(storage::features::kEnableFilesystemInIncognito)},
-
     {"enable-send-tab-to-self-show-sending-ui",
      flag_descriptions::kSendTabToSelfShowSendingUIName,
      flag_descriptions::kSendTabToSelfShowSendingUIDescription, kOsAll,
diff --git a/chrome/browser/browser_switcher/README.md b/chrome/browser/browser_switcher/README.md
new file mode 100644
index 0000000..ff1c7818
--- /dev/null
+++ b/chrome/browser/browser_switcher/README.md
@@ -0,0 +1,88 @@
+# Legacy Browser Support (BrowserSwitcher internally)
+
+BrowserSwitcher is a Chrome module that listens to navigations, and
+automatically switches to another browser (typically IE) for a predefined set of
+URLs.
+
+It is a port of the old Legacy Browser Support extension, to make it easier to
+deploy across organizations.
+
+Setup instructions for administrators can be found
+[here](https://support.google.com/chrome/a/answer/9270076).
+
+## Configuration
+
+The policies in the [BrowserSwitcher
+group](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcher)
+let admins configure this feature, to decide which URLs should open in Chrome
+and which should open in the alternate browser.
+
+### Sitelist and Greylist
+
+There are 2 types of rules for LBS:
+
+* Sitelist (AKA URL list): when the user visits one of these URLs in Chrome, it
+  opens in the alternate browser. If any other URL is viewed in IE, it bounces
+  back to Chrome.
+
+* Greylist: these URLs do not trigger a browser switch. i.e., it stays in Chrome
+  if viewed in Chrome, and it stays in IE if viewed in IE.
+
+These rules can be applied from 3 different sources:
+
+* Directly, with Chrome policies:
+  [BrowserSwitcherUrlList](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcherUrlList)
+  and
+  [BrowserSwitcherUrlGreylist](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcherUrlGreylist)
+  control the sitelist and the greylist, respectively.
+
+* EMIE site list: IE/Edge can be
+  [configured](https://docs.microsoft.com/en-us/internet-explorer/ie11-deploy-guide/turn-on-enterprise-mode-and-use-a-site-list)
+  to open websites in IE, with a certain renderer version. BrowserSwitcher can
+  share the same rules IE uses, using the
+  [BrowserSwitcherUseIeSitelist](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcherUseIeSitelist)
+  policy. The rules are specified as a URL, that points to an XML file that
+  Chrome downloads.
+
+* Other XML site list: Specifies a URL to an XML file (like the EMIE site list),
+  but the rules aren't shared with IE. These rules are controlled by the
+  [BrowserSwitcherExternalSitelistUrl](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcherExternalSitelistUrl)
+  and
+  [BrowserSwitcherExternalGreylistUrl](https://www.chromium.org/administrators/policy-list-3#BrowserSwitcherExternalGreylistUrl)
+  policies.
+
+If rules from multiple sources are present, they are combined into one
+list. This means you can create some rules with Chrome policies, and add more
+rules from the EMIE site list.
+
+If multiple rules match one navigation, then the longest rule applies. For
+instance:
+
+1. Let's say `sitelist = [ "example.com", "!foo.example.com" ]`
+2. User visits `http://foo.example.com/` in Chrome
+3. The website opens in Chrome, because `!foo.example.com` is longer than
+  `example.com`, and it starts with a `!` (which inverts the rule).
+
+### Debugging/Troubleshooting
+
+Enterprise admins and developers can visit the
+`chrome://browser-switch/internals` page to view the state of LBS. This page
+displays the list of rules, and lets you re-download XML sitelists immediately.
+
+## BHO
+
+On Windows, a BHO (an IE add-on) can be used to automatically bounce back to
+Chrome from IE when visiting a non-whitelisted URL.
+
+### Sharing State with Chrome
+
+The BHO cannot access all Chrome policies, which are needed to decide if a
+navigation should bounce back to Chrome.
+
+To solve this problem, BrowserSwitcher writes a `cache.dat` file in
+`AppData\Local\Google\BrowserSwitcher`.  It contains the sitelist + greylist in
+a format that's easy to parse for the BHO. Whenever new rules are added or
+removed, it re-writes the `cache.dat` file.
+
+This is the same mechanism that the old extension uses, so this feature is
+compatible with the old BHO.
diff --git a/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc b/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
index ccf37aa..63fd102 100644
--- a/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
@@ -27,7 +27,7 @@
 void GetAllOriginsInfoForServiceWorkerCallback(
     BrowsingDataServiceWorkerHelper::FetchCallback callback,
     const std::vector<StorageUsageInfo>& origins) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   DCHECK(!callback.is_null());
 
   std::list<StorageUsageInfo> result;
@@ -37,8 +37,8 @@
     result.push_back(origin);
   }
 
-  base::PostTask(FROM_HERE, {BrowserThread::UI},
-                 base::BindOnce(std::move(callback), result));
+  content::RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI,
+                                 base::BindOnce(std::move(callback), result));
 }
 
 }  // namespace
@@ -54,33 +54,34 @@
 void BrowsingDataServiceWorkerHelper::StartFetching(FetchCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!callback.is_null());
-  base::PostTask(FROM_HERE, {BrowserThread::IO},
-                 base::BindOnce(&BrowsingDataServiceWorkerHelper::
-                                    FetchServiceWorkerUsageInfoOnIOThread,
-                                this, std::move(callback)));
+  content::RunOrPostTaskOnThread(
+      FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
+      base::BindOnce(&BrowsingDataServiceWorkerHelper::
+                         FetchServiceWorkerUsageInfoOnCoreThread,
+                     this, std::move(callback)));
 }
 
 void BrowsingDataServiceWorkerHelper::DeleteServiceWorkers(const GURL& origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  base::PostTask(
-      FROM_HERE, {BrowserThread::IO},
+  content::RunOrPostTaskOnThread(
+      FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
       base::BindOnce(
-          &BrowsingDataServiceWorkerHelper::DeleteServiceWorkersOnIOThread,
+          &BrowsingDataServiceWorkerHelper::DeleteServiceWorkersOnCoreThread,
           this, origin));
 }
 
-void BrowsingDataServiceWorkerHelper::FetchServiceWorkerUsageInfoOnIOThread(
+void BrowsingDataServiceWorkerHelper::FetchServiceWorkerUsageInfoOnCoreThread(
     FetchCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   DCHECK(!callback.is_null());
 
   service_worker_context_->GetAllOriginsInfo(base::BindOnce(
       &GetAllOriginsInfoForServiceWorkerCallback, std::move(callback)));
 }
 
-void BrowsingDataServiceWorkerHelper::DeleteServiceWorkersOnIOThread(
+void BrowsingDataServiceWorkerHelper::DeleteServiceWorkersOnCoreThread(
     const GURL& origin) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   service_worker_context_->DeleteForOrigin(origin, base::DoNothing());
 }
 
diff --git a/chrome/browser/browsing_data/browsing_data_service_worker_helper.h b/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
index af09453..f59e436 100644
--- a/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
@@ -54,11 +54,11 @@
  private:
   friend class base::RefCountedThreadSafe<BrowsingDataServiceWorkerHelper>;
 
-  // Enumerates all Service Worker instances on the IO thread.
-  void FetchServiceWorkerUsageInfoOnIOThread(FetchCallback callback);
+  // Enumerates all Service Worker instances on the service worker core thread.
+  void FetchServiceWorkerUsageInfoOnCoreThread(FetchCallback callback);
 
-  // Deletes Service Workers for an origin the IO thread.
-  void DeleteServiceWorkersOnIOThread(const GURL& origin);
+  // Deletes Service Workers for an origin on the service worker core thread.
+  void DeleteServiceWorkersOnCoreThread(const GURL& origin);
 
   DISALLOW_COPY_AND_ASSIGN(BrowsingDataServiceWorkerHelper);
 };
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc
index 1bdefd4..6e9a370 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.cc
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -209,6 +209,7 @@
     MAP_PROVISIONING_RESULT(ARC_DISABLED);
     MAP_PROVISIONING_RESULT(SUCCESS_ALREADY_PROVISIONED);
     MAP_PROVISIONING_RESULT(UNSUPPORTED_ACCOUNT_TYPE);
+    MAP_PROVISIONING_RESULT(CHROME_ACCOUNT_NOT_FOUND);
   }
 
 #undef MAP_PROVISIONING_RESULT
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.h b/chrome/browser/chromeos/arc/arc_optin_uma.h
index addaafa5..991e32ea 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.h
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.h
@@ -163,7 +163,10 @@
   // Account type is not supported for authorization.
   UNSUPPORTED_ACCOUNT_TYPE = 22,
 
-  kMaxValue = UNSUPPORTED_ACCOUNT_TYPE,
+  // Account is not present in Chrome OS Account Manager.
+  CHROME_ACCOUNT_NOT_FOUND = 23,
+
+  kMaxValue = CHROME_ACCOUNT_NOT_FOUND,
 };
 
 enum class OptInFlowResult : int {
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
index 4ac1ca1..4f448e3 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/singleton.h"
+#include "base/optional.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/account_manager/account_manager_migrator.h"
@@ -99,6 +100,7 @@
     MAP_PROVISIONING_RESULT(SUCCESS);
     MAP_PROVISIONING_RESULT(SUCCESS_ALREADY_PROVISIONED);
     MAP_PROVISIONING_RESULT(UNSUPPORTED_ACCOUNT_TYPE);
+    MAP_PROVISIONING_RESULT(CHROME_ACCOUNT_NOT_FOUND);
   }
 #undef MAP_PROVISIONING_RESULT
 
@@ -172,11 +174,14 @@
   if (user->IsDeviceLocalAccount())
     return true;
 
-  const std::string gaia_id =
+  const base::Optional<AccountInfo> account_info =
       identity_manager
           ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
-              account_name)
-          ->gaia;
+              account_name);
+  if (!account_info)
+    return false;
+
+  const std::string& gaia_id = account_info->gaia;
   DCHECK(!gaia_id.empty());
   return IsPrimaryGaiaAccount(gaia_id);
 }
@@ -664,12 +669,16 @@
     const std::string& account_name,
     RequestAccountInfoCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
   base::Optional<AccountInfo> account_info =
       identity_manager_
           ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
               account_name);
-  DCHECK(account_info.has_value());
+  if (!account_info.has_value()) {
+    // Account is in ARC, but not in Chrome OS Account Manager.
+    std::move(callback).Run(mojom::ArcSignInStatus::CHROME_ACCOUNT_NOT_FOUND,
+                            nullptr);
+    return;
+  }
 
   const std::string& account_id = account_info->account_id;
   DCHECK(!account_id.empty());
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
index be8e3b2..88bd0fb 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -505,6 +505,22 @@
             auth_instance().sign_in_status());
 }
 
+IN_PROC_BROWSER_TEST_F(
+    ArcAuthServiceTest,
+    FetchSecondaryAccountInfoReturnsErrorForNotFoundAccounts) {
+  SetAccountAndProfile(user_manager::USER_TYPE_REGULAR);
+  // Don't add account with kSecondaryAccountEmail.
+
+  base::RunLoop run_loop;
+  auth_instance().RequestAccountInfo(kSecondaryAccountEmail,
+                                     run_loop.QuitClosure());
+  run_loop.Run();
+
+  EXPECT_FALSE(auth_instance().account_info());
+  EXPECT_EQ(mojom::ArcSignInStatus::CHROME_ACCOUNT_NOT_FOUND,
+            auth_instance().sign_in_status());
+}
+
 IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchGoogleAccountsFromArc) {
   SetAccountAndProfile(user_manager::USER_TYPE_REGULAR);
 
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index b183bcf7..f2b12c6b 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -93,6 +93,7 @@
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "net/base/filename_util.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
@@ -1704,8 +1705,7 @@
 
 AutotestPrivateSendAssistantTextQueryFunction::
     AutotestPrivateSendAssistantTextQueryFunction()
-    : assistant_interaction_subscriber_binding_(this),
-      result_(std::make_unique<base::DictionaryValue>()) {}
+    : result_(std::make_unique<base::DictionaryValue>()) {}
 
 AutotestPrivateSendAssistantTextQueryFunction::
     ~AutotestPrivateSendAssistantTextQueryFunction() = default;
@@ -1730,9 +1730,8 @@
   AssistantClient::Get()->BindAssistant(mojo::MakeRequest(&assistant_));
 
   // Subscribe to Assistant interaction events.
-  chromeos::assistant::mojom::AssistantInteractionSubscriberPtr ptr;
-  assistant_interaction_subscriber_binding_.Bind(mojo::MakeRequest(&ptr));
-  assistant_->AddAssistantInteractionSubscriber(std::move(ptr));
+  assistant_->AddAssistantInteractionSubscriber(
+      assistant_interaction_subscriber_receiver_.BindNewPipeAndPassRemote());
 
   // Start text interaction with Assistant server.
   assistant_->StartTextInteraction(params->query, /*allow_tts*/ false);
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
index 6c26e4f..4977a8a 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
@@ -19,7 +19,7 @@
 #include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h"
 #include "chromeos/services/machine_learning/public/mojom/model.mojom.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "ui/snapshot/screenshot_grabber.h"
 
 namespace crostini {
@@ -556,8 +556,8 @@
   void Timeout();
 
   chromeos::assistant::mojom::AssistantPtr assistant_;
-  mojo::Binding<chromeos::assistant::mojom::AssistantInteractionSubscriber>
-      assistant_interaction_subscriber_binding_;
+  mojo::Receiver<chromeos::assistant::mojom::AssistantInteractionSubscriber>
+      assistant_interaction_subscriber_receiver_{this};
   base::OneShotTimer timeout_timer_;
   std::unique_ptr<base::DictionaryValue> result_;
 };
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
index 8fb66cd..98d663db 100644
--- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
@@ -1745,15 +1745,32 @@
   os_update_status->set_new_required_platform_version(
       required_platfrom_version.GetString());
 
+  const chromeos::UpdateEngineClient::Status update_engine_status =
+      chromeos::DBusThreadManager::Get()
+          ->GetUpdateEngineClient()
+          ->GetLastStatus();
+
+  // Get last reboot timestamp.
+  const base::Time last_reboot_timestamp =
+      base::Time::Now() - base::SysInfo::Uptime();
+
+  os_update_status->set_last_reboot_timestamp(
+      last_reboot_timestamp.ToJavaTime());
+
+  // Get last check timestamp.
+  // As the timestamp precision return from UpdateEngine is in seconds (see
+  // time_t). It should be converted to milliseconds before being reported.
+  const base::Time last_checked_timestamp =
+      base::Time::FromTimeT(update_engine_status.last_checked_time);
+
+  os_update_status->set_last_checked_timestamp(
+      last_checked_timestamp.ToJavaTime());
+
   if (platform_version == required_platfrom_version) {
     os_update_status->set_update_status(em::OsUpdateStatus::OS_UP_TO_DATE);
     return true;
   }
 
-  const chromeos::UpdateEngineClient::Status update_engine_status =
-      chromeos::DBusThreadManager::Get()
-          ->GetUpdateEngineClient()
-          ->GetLastStatus();
   if (update_engine_status.status ==
           chromeos::UpdateEngineClient::UPDATE_STATUS_DOWNLOADING ||
       update_engine_status.status ==
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
index 3296434..6cfa7ba 100644
--- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -133,6 +133,7 @@
 const char kLastLaunchTimeWindowStartFormatted[] =
     "Sat, 1 Sep 2018 00:00:00 GMT";
 const long kLastLaunchTimeWindowStartInJavaTime = 1535760000000;
+const char kDefaultPlatformVersion[] = "1234.0.0";
 
 class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
  public:
@@ -1966,16 +1967,16 @@
 }
 
 TEST_F(DeviceStatusCollectorTest, NoOsUpdateStatusByDefault) {
-  MockPlatformVersion("1234.0.0");
+  MockPlatformVersion(kDefaultPlatformVersion);
   MockAutoLaunchKioskAppWithRequiredPlatformVersion(
-      fake_kiosk_device_local_account_, "1234.0.0");
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
 
   GetStatus();
   EXPECT_FALSE(device_status_.has_os_update_status());
 }
 
 TEST_F(DeviceStatusCollectorTest, ReportOsUpdateStatusUpToDate) {
-  MockPlatformVersion("1234.0.0");
+  MockPlatformVersion(kDefaultPlatformVersion);
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportOsUpdateStatus, true);
 
@@ -1998,7 +1999,7 @@
 }
 
 TEST_F(DeviceStatusCollectorTest, ReportOsUpdateStatus) {
-  MockPlatformVersion("1234.0.0");
+  MockPlatformVersion(kDefaultPlatformVersion);
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportOsUpdateStatus, true);
   MockAutoLaunchKioskAppWithRequiredPlatformVersion(
@@ -2044,10 +2045,76 @@
             device_status_.os_update_status().update_status());
 }
 
-TEST_F(DeviceStatusCollectorTest, NoRunningKioskAppByDefault) {
-  MockPlatformVersion("1234.0.0");
+TEST_F(DeviceStatusCollectorTest, NoLastCheckedTimestampByDefault) {
+  MockPlatformVersion(kDefaultPlatformVersion);
   MockAutoLaunchKioskAppWithRequiredPlatformVersion(
-      fake_kiosk_device_local_account_, "1234.0.0");
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
+
+  GetStatus();
+  EXPECT_FALSE(device_status_.os_update_status().has_last_checked_timestamp());
+}
+
+TEST_F(DeviceStatusCollectorTest, ReportLastCheckedTimestamp) {
+  MockPlatformVersion(kDefaultPlatformVersion);
+  MockAutoLaunchKioskAppWithRequiredPlatformVersion(
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
+
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportOsUpdateStatus, true);
+
+  // Check update multiple times, the timestamp stored in device status should
+  // change accordingly.
+  const int64 kLastCheckedTimes[] = {10, 20, 30};
+
+  for (size_t i = 0; i < base::size(kLastCheckedTimes); ++i) {
+    chromeos::UpdateEngineClient::Status update_status;
+    update_status.new_version = kDefaultPlatformVersion;
+    update_status.last_checked_time = kLastCheckedTimes[i];
+    update_engine_client_->PushLastStatus(update_status);
+
+    GetStatus();
+    ASSERT_TRUE(device_status_.os_update_status().has_last_checked_timestamp());
+
+    // The timestamp precision in UpdateEngine is in seconds, but the
+    // DeviceStatusCollector is in milliseconds. Therefore, the number should be
+    // multiplied by 1000 before validation.
+    ASSERT_EQ(kLastCheckedTimes[i] * 1000,
+              device_status_.os_update_status().last_checked_timestamp());
+  }
+}
+
+TEST_F(DeviceStatusCollectorTest, NoLastRebootTimestampByDefault) {
+  MockPlatformVersion(kDefaultPlatformVersion);
+  MockAutoLaunchKioskAppWithRequiredPlatformVersion(
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
+
+  GetStatus();
+  EXPECT_FALSE(device_status_.os_update_status().has_last_reboot_timestamp());
+}
+
+TEST_F(DeviceStatusCollectorTest, ReportLastRebootTimestamp) {
+  MockPlatformVersion(kDefaultPlatformVersion);
+  MockAutoLaunchKioskAppWithRequiredPlatformVersion(
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
+
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportOsUpdateStatus, true);
+
+  GetStatus();
+  ASSERT_TRUE(device_status_.os_update_status().has_last_reboot_timestamp());
+
+  // No good way to inject specific last reboot timestamp of the test machine,
+  // so just make sure UnixEpoch < RebootTime < Now.
+  EXPECT_GT(device_status_.os_update_status().last_reboot_timestamp(),
+            base::Time::UnixEpoch().ToJavaTime());
+  EXPECT_LT(device_status_.os_update_status().last_reboot_timestamp(),
+            base::Time::Now().ToJavaTime());
+}
+
+TEST_F(DeviceStatusCollectorTest, NoRunningKioskAppByDefault) {
+  MockPlatformVersion(kDefaultPlatformVersion);
+  MockAutoLaunchKioskAppWithRequiredPlatformVersion(
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
   status_collector_->set_kiosk_account(
       std::make_unique<policy::DeviceLocalAccount>(
           fake_kiosk_device_local_account_));
@@ -2060,9 +2127,9 @@
 TEST_F(DeviceStatusCollectorTest, NoRunningKioskAppWhenNotInKioskSession) {
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportRunningKioskApp, true);
-  MockPlatformVersion("1234.0.0");
+  MockPlatformVersion(kDefaultPlatformVersion);
   MockAutoLaunchKioskAppWithRequiredPlatformVersion(
-      fake_kiosk_device_local_account_, "1234.0.0");
+      fake_kiosk_device_local_account_, kDefaultPlatformVersion);
 
   GetStatus();
   EXPECT_FALSE(device_status_.has_running_kiosk_app());
@@ -2071,7 +2138,7 @@
 TEST_F(DeviceStatusCollectorTest, ReportRunningKioskApp) {
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportRunningKioskApp, true);
-  MockPlatformVersion("1234.0.0");
+  MockPlatformVersion(kDefaultPlatformVersion);
   MockAutoLaunchKioskAppWithRequiredPlatformVersion(
       fake_kiosk_device_local_account_, "1235");
   MockRunningKioskApp(fake_kiosk_device_local_account_, false /* arc_kiosk */);
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 927eece..ef3f14c 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -44,7 +44,6 @@
 #include "extensions/common/manifest_constants.h"
 #include "pdf/buildflags.h"
 #include "printing/buildflags/buildflags.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "ui/accessibility/accessibility_switches.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -542,10 +541,9 @@
 #endif  // BUILDFLAG(ENABLE_NACL)
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-    std::string id = Add(IDR_QUICKOFFICE_MANIFEST,
-                         base::FilePath(FILE_PATH_LITERAL(
-                             "/usr/share/chromeos-assets/quickoffice")));
-    EnableFileSystemInGuestMode(id);
+    Add(IDR_QUICKOFFICE_MANIFEST,
+        base::FilePath(
+            FILE_PATH_LITERAL("/usr/share/chromeos-assets/quickoffice")));
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
     Add(IDR_ECHO_MANIFEST,
@@ -656,29 +654,6 @@
                           extension_misc::kEspeakSpeechSynthesisExtensionId));
 }
 
-void ComponentLoader::EnableFileSystemInGuestMode(const std::string& id) {
-  if (!IsNormalSession()) {
-    // TODO(dpolukhin): Hack to enable HTML5 temporary file system for
-    // the extension. Some component extensions don't work without temporary
-    // file system access. Make sure temporary file system is enabled in the off
-    // the record browser context (as that is the one used in guest session).
-    content::BrowserContext* off_the_record_context =
-        ExtensionsBrowserClient::Get()->GetOffTheRecordContext(profile_);
-    GURL site = content::SiteInstance::GetSiteForURL(
-        off_the_record_context, Extension::GetBaseURLFromExtensionId(id));
-    storage::FileSystemContext* file_system_context =
-        content::BrowserContext::GetStoragePartitionForSite(
-            off_the_record_context, site)
-            ->GetFileSystemContext();
-    // Incognito file system is enabled by default. This function can be removed
-    // when the feature flag is removed.
-    if (!base::FeatureList::IsEnabled(
-            storage::features::kEnableFilesystemInIncognito)) {
-      file_system_context->EnableTemporaryFileSystemInIncognito();
-    }
-  }
-}
-
 void ComponentLoader::FinishAddComponentFromDir(
     const base::FilePath& root_directory,
     const char* extension_id,
@@ -707,8 +682,6 @@
 
 void ComponentLoader::FinishLoadSpeechSynthesisExtension(
     const char* extension_id) {
-  EnableFileSystemInGuestMode(extension_id);
-
   // TODO(https://crbug.com/947305): mitigation for extension not awake after
   // load.
   extensions::ProcessManager::Get(profile_)->WakeEventPage(extension_id,
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h
index de5c2d5..59dea62 100644
--- a/chrome/browser/extensions/component_loader.h
+++ b/chrome/browser/extensions/component_loader.h
@@ -194,9 +194,6 @@
   void UnloadComponent(ComponentExtensionInfo* component);
 
 #if defined(OS_CHROMEOS)
-  // Enable HTML5 FileSystem for given component extension in Guest mode.
-  void EnableFileSystemInGuestMode(const std::string& id);
-
   // Used as a reply callback by |AddComponentFromDir|.
   // Called with a |root_directory| and parsed |manifest| and invokes
   // |done_cb| after adding the extension.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 2dca794e..51233da0 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1208,11 +1208,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "enable-filesystem-in-incognito",
-    "owners": [ "rhalavati" ],
-    "expiry_milestone": 78
-  },
-  {
     "name": "enable-filtering-scroll-events",
     "owners": [ "axantoine", "eirage", "nzolghadr", "input-dev" ],
     "expiry_milestone": 80
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index fb95a1b..6c18c2e22 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -556,10 +556,6 @@
     "Enables save data feature. May cause user's traffic to be proxied via "
     "Google's data reduction proxy.";
 
-const char kEnableFilesystemInIncognitoName[] = "Filesystem API in Incognito";
-const char kEnableFilesystemInIncognitoDescription[] =
-    "Enable Filesystem API in incognito mode.";
-
 const char kEnableNoScriptPreviewsName[] = "NoScript previews";
 
 const char kEnableNoScriptPreviewsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 60722534..7a05b15 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -347,9 +347,6 @@
 extern const char kEnableSaveDataName[];
 extern const char kEnableSaveDataDescription[];
 
-extern const char kEnableFilesystemInIncognitoName[];
-extern const char kEnableFilesystemInIncognitoDescription[];
-
 extern const char kEnableNoScriptPreviewsName[];
 extern const char kEnableNoScriptPreviewsDescription[];
 
diff --git a/chrome/browser/local_discovery/local_domain_resolver_unittest.cc b/chrome/browser/local_discovery/local_domain_resolver_unittest.cc
index 5675c4e9..605715d 100644
--- a/chrome/browser/local_discovery/local_domain_resolver_unittest.cc
+++ b/chrome/browser/local_discovery/local_domain_resolver_unittest.cc
@@ -103,7 +103,7 @@
 
   net::MockMDnsSocketFactory socket_factory_;
   net::MDnsClientImpl mdns_client_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(LocalDomainResolverTest, ResolveDomainA) {
diff --git a/chrome/browser/local_discovery/service_discovery_client_unittest.cc b/chrome/browser/local_discovery/service_discovery_client_unittest.cc
index e5901af6..12dea4d 100644
--- a/chrome/browser/local_discovery/service_discovery_client_unittest.cc
+++ b/chrome/browser/local_discovery/service_discovery_client_unittest.cc
@@ -231,7 +231,7 @@
   net::MockMDnsSocketFactory socket_factory_;
   net::MDnsClientImpl mdns_client_;
   ServiceDiscoveryClientImpl service_discovery_client_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(ServiceDiscoveryTest, AddRemoveService) {
diff --git a/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc b/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc
deleted file mode 100644
index b7117933..0000000
--- a/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
-#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler_impl.h"
-#include "chrome/browser/notifications/scheduler/public/display_agent.h"
-#include "chrome/browser/notifications/scheduler/public/features.h"
-#include "chrome/browser/notifications/scheduler/public/notification_params.h"
-#include "chrome/browser/notifications/scheduler/public/notification_schedule_service.h"
-#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client.h"
-#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client_registrar.h"
-#include "chrome/browser/notifications/scheduler/schedule_service_factory_helper.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
-
-namespace notifications {
-namespace {
-
-const base::FilePath::CharType kTestDir[] =
-    FILE_PATH_LITERAL("NotificationScheduleServiceTest");
-
-class TestClient : public NotificationSchedulerClient {
- public:
-  TestClient() {}
-  ~TestClient() override = default;
-
- private:
-  // NotificationSchedulerClient implementation.
-  void BeforeShowNotification(
-      std::unique_ptr<NotificationData> notification_data,
-      NotificationDataCallback callback) override {
-    std::move(callback).Run(std::move(notification_data));
-  }
-
-  void OnSchedulerInitialized(bool success,
-                              std::set<std::string> guids) override {}
-
-  void OnUserAction(const UserActionData& action_data) override {}
-
-  DISALLOW_COPY_AND_ASSIGN(TestClient);
-};
-
-class TestBackgroundTaskScheduler : public NotificationBackgroundTaskScheduler {
- public:
-  TestBackgroundTaskScheduler() = default;
-  ~TestBackgroundTaskScheduler() override = default;
-
-  // Waits until a background task has been updated.
-  void WaitForTaskUpdated() {
-    DCHECK(!run_loop_);
-    run_loop_ = std::make_unique<base::RunLoop>();
-    run_loop_->Run();
-  }
-
-  base::TimeDelta window_start() { return window_start_; }
-
- private:
-  void QuitRunLoopIfNeeded() {
-    if (run_loop_ && run_loop_->running()) {
-      run_loop_->Quit();
-    }
-  }
-
-  // NotificationBackgroundTaskScheduler implementation.
-  void Schedule(notifications::SchedulerTaskTime scheduler_task_time,
-                base::TimeDelta window_start,
-                base::TimeDelta window_end) override {
-    QuitRunLoopIfNeeded();
-  }
-
-  void Cancel() override { QuitRunLoopIfNeeded(); }
-
-  base::TimeDelta window_start_;
-  std::unique_ptr<base::RunLoop> run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestBackgroundTaskScheduler);
-};
-
-// Browser test for notification scheduling system. Uses real database
-// instances. Mainly to cover service initialization flow in chrome layer.
-class NotificationScheduleServiceTest : public InProcessBrowserTest {
- public:
-  NotificationScheduleServiceTest() : task_scheduler_(nullptr) {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kNotificationScheduleService}, {});
-  }
-
-  ~NotificationScheduleServiceTest() override {}
-
- protected:
-  void SetUpOnMainThread() override {
-    InProcessBrowserTest::SetUpOnMainThread();
-    ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
-  }
-
-  void TearDownOnMainThread() override {
-    InProcessBrowserTest::TearDownOnMainThread();
-    ASSERT_TRUE(tmp_dir_.Delete());
-  }
-
-  // Initializes |service_|. Injects database test data before this call.
-  void Init() {
-    auto* profile = browser()->profile();
-    auto client = std::make_unique<TestClient>();
-    auto client_registrar =
-        std::make_unique<NotificationSchedulerClientRegistrar>();
-    client_registrar->RegisterClient(SchedulerClientType::kTest1,
-                                     std::move(client));
-    auto display_agent = notifications::DisplayAgent::Create();
-    auto background_task_scheduler =
-        std::make_unique<TestBackgroundTaskScheduler>();
-    task_scheduler_ = background_task_scheduler.get();
-    auto* db_provider =
-        content::BrowserContext::GetDefaultStoragePartition(profile)
-            ->GetProtoDatabaseProvider();
-    NotificationScheduleService* service =
-        static_cast<NotificationScheduleService*>(
-            CreateNotificationScheduleService(
-                std::move(client_registrar),
-                std::move(background_task_scheduler), std::move(display_agent),
-                db_provider, tmp_dir_.GetPath().Append(kTestDir),
-                profile->IsOffTheRecord()));
-    service_ = std::unique_ptr<NotificationScheduleService>(service);
-  }
-
-  NotificationScheduleService* schedule_service() { return service_.get(); }
-
-  TestBackgroundTaskScheduler* task_scheduler() {
-    DCHECK(task_scheduler_);
-    return task_scheduler_;
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-  base::ScopedTempDir tmp_dir_;
-  std::unique_ptr<NotificationScheduleService> service_;
-  TestBackgroundTaskScheduler* task_scheduler_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationScheduleServiceTest);
-};
-
-// Test to schedule a notification.
-IN_PROC_BROWSER_TEST_F(NotificationScheduleServiceTest, ScheduleNotification) {
-  Init();
-  ScheduleParams schedule_params;
-  schedule_params.deliver_time_start = base::Time::Now();
-  schedule_params.deliver_time_end =
-      base::Time::Now() + base::TimeDelta::FromMinutes(5);
-  NotificationData data;
-  data.title = base::UTF8ToUTF16("title");
-  data.message = base::UTF8ToUTF16("message");
-  auto params = std::make_unique<notifications::NotificationParams>(
-      notifications::SchedulerClientType::kTest1, std::move(data),
-      std::move(schedule_params));
-  schedule_service()->Schedule(std::move(params));
-
-  // A background task should be scheduled.
-  task_scheduler()->WaitForTaskUpdated();
-  EXPECT_LE(task_scheduler()->window_start(), base::TimeDelta::FromMinutes(5));
-}
-
-}  // namespace
-}  // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/public/notification_schedule_service.h b/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
index b12f0d2..17e7ef0 100644
--- a/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
+++ b/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
@@ -42,10 +42,9 @@
   // Returns the user action handler to process notification events.
   virtual UserActionHandler* GetUserActionHandler() = 0;
 
-  ~NotificationScheduleService() override = default;
-
  protected:
   NotificationScheduleService() = default;
+  ~NotificationScheduleService() override = default;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(NotificationScheduleService);
diff --git a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
index f6ad7dd..13863fe6 100644
--- a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
+++ b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
@@ -49,8 +49,11 @@
           WebFeature::kPaymentRequestShowWithoutGesture,
           WebFeature::kHTMLImports,
           WebFeature::kHTMLImportsHasStyleSheets,
+          WebFeature::kHTMLImportsOnReverseOriginTrials,
           WebFeature::kElementCreateShadowRoot,
+          WebFeature::kElementCreateShadowRootOnReverseOriginTrials,
           WebFeature::kDocumentRegisterElement,
+          WebFeature::kDocumentRegisterElementOnReverseOriginTrials,
           WebFeature::kCredentialManagerCreatePublicKeyCredential,
           WebFeature::kCredentialManagerGetPublicKeyCredential,
           WebFeature::kCredentialManagerMakePublicKeyCredentialSuccess,
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 2e7d7261..2677f74 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -679,7 +679,7 @@
 }
 
 password_manager::PasswordStore*
-ChromePasswordManagerClient::GetPasswordStore() const {
+ChromePasswordManagerClient::GetProfilePasswordStore() const {
   // Always use EXPLICIT_ACCESS as the password manager checks IsIncognito
   // itself when it shouldn't access the PasswordStore.
   // TODO(gcasto): Is is safe to change this to
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index a432537f..23ffcf50 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -124,7 +124,7 @@
   bool IsIsolationForPasswordSitesEnabled() const override;
 
   PrefService* GetPrefs() const override;
-  password_manager::PasswordStore* GetPasswordStore() const override;
+  password_manager::PasswordStore* GetProfilePasswordStore() const override;
   password_manager::SyncState GetPasswordSyncState() const override;
   bool WasLastNavigationHTTPError() const override;
   net::CertStatus GetMainFrameCertStatus() const override;
diff --git a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc
index 9eeb683..4601e7c9 100644
--- a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc
+++ b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc
@@ -59,7 +59,7 @@
 
   bool IsSavingAndFillingEnabled(const GURL& url) const override;
   void GeneratePassword() override;
-  password_manager::PasswordStore* GetPasswordStore() const override;
+  password_manager::PasswordStore* GetProfilePasswordStore() const override;
 
  private:
   scoped_refptr<MockPasswordStore> mock_password_store_;
@@ -97,8 +97,8 @@
 
 void TestPasswordManagerClient::GeneratePassword() {}
 
-password_manager::PasswordStore* TestPasswordManagerClient::GetPasswordStore()
-    const {
+password_manager::PasswordStore*
+TestPasswordManagerClient::GetProfilePasswordStore() const {
   return mock_password_store_.get();
 }
 
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index 99693dbe..f675bbe 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -2996,8 +2996,14 @@
   ExpectLeavePictureInPicture(active_web_contents);
 }
 
+// TODO(crbug.com/1002489): Test is flaky on Linux.
+#if defined(OS_LINUX)
+#define MAYBE_UpdateMaxSize DISABLED_UpdateMaxSize
+#else
+#define MAYBE_UpdateMaxSize UpdateMaxSize
+#endif
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
-                       UpdateMaxSize) {
+                       MAYBE_UpdateMaxSize) {
   LoadTabAndEnterPictureInPicture(
       browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 2bdbd99..45e09c1 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -495,6 +495,9 @@
 // Deprecated 8/2019
 const char kHintLoadedCounts[] = "optimization_guide.hint_loaded_counts";
 
+// Deprecated 9/2019
+const char kGoogleServicesUsername[] = "google.services.username";
+
 // Register prefs used only for migration (clearing or moving to a new key).
 void RegisterProfilePrefsForMigration(
     user_prefs::PrefRegistrySyncable* registry) {
@@ -571,6 +574,7 @@
   registry->RegisterBooleanPref(kInsecureExtensionUpdatesEnabled, false);
 
   registry->RegisterDictionaryPref(kHintLoadedCounts);
+  registry->RegisterStringPref(kGoogleServicesUsername, std::string());
 }
 
 }  // namespace
@@ -1179,4 +1183,7 @@
   // Added 8/2019
   profile_prefs->ClearPref(kInsecureExtensionUpdatesEnabled);
   profile_prefs->ClearPref(kHintLoadedCounts);
+
+  // Added 9/2019
+  profile_prefs->ClearPref(kGoogleServicesUsername);
 }
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index d382d47..65fafa55 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -151,10 +151,6 @@
     {19, prefs::kSwReporterPromptVersion, EnforcementLevel::ENFORCE_ON_LOAD,
      PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
 #endif
-    // This pref is deprecated and will be removed a few releases after M43.
-    // kGoogleServicesAccountId replaces it.
-    {21, prefs::kGoogleServicesUsername, EnforcementLevel::ENFORCE_ON_LOAD,
-     PrefTrackingStrategy::ATOMIC, ValueType::PERSONAL},
 #if defined(OS_WIN)
     {22, prefs::kSwReporterPromptSeed, EnforcementLevel::ENFORCE_ON_LOAD,
      PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 714af84..065317b 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -745,16 +745,6 @@
 
   HeavyAdServiceFactory::GetForBrowserContext(this)->Initialize(GetPath());
 
-  // Page Load Capping was remove in M74, so the database file should be removed
-  // when users upgrade Chrome.
-  // TODO(ryansturm): Remove this after M-79. https://crbug.com/937489
-  base::PostTask(
-      FROM_HERE,
-      {base::ThreadPool(), base::TaskPriority::LOWEST, base::MayBlock()},
-      base::BindOnce(base::IgnoreResult(&base::DeleteFile),
-                     GetPath().Append(chrome::kPageLoadCappingOptOutDBFilename),
-                     false));
-
   PushMessagingServiceImpl::InitializeForProfile(this);
 
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/resources/chromeos/login/encryption_migration.css b/chrome/browser/resources/chromeos/login/encryption_migration.css
index df67332..27cea4c 100644
--- a/chrome/browser/resources/chromeos/login/encryption_migration.css
+++ b/chrome/browser/resources/chromeos/login/encryption_migration.css
@@ -4,7 +4,8 @@
 
 oobe-dialog {
   height: 640px;
-  max-height: calc(100vh - 56px);  /* Subtracting LoginShelfView's height. */
+  /* Subtracting LoginShelfView's height. */
+  max-height: calc(100vh - var(--shelf-area-height));
   max-width: 100vw;
   min-height: 0 !important;  /* Making <oobe-dialog> shrinkable. */
   min-width: 0 !important;  /* Making <oobe-dialog> shrinkable. */
diff --git a/chrome/browser/resources/chromeos/login/md_screen_container.css b/chrome/browser/resources/chromeos/login/md_screen_container.css
index 1eb6aa0..18d96624 100644
--- a/chrome/browser/resources/chromeos/login/md_screen_container.css
+++ b/chrome/browser/resources/chromeos/login/md_screen_container.css
@@ -19,7 +19,8 @@
   display: flex;
   justify-content: center;
   left: 0;
-  min-height: 717px; /* This enables scrolling. Min resolution: 1024x768 */
+  /* This enables scrolling. Min resolution: 1024x768 */
+  min-height: calc(768px - var(--shelf-area-height));
   perspective: 1px; /* Workaround, see http://crbug.com/360567 */
   position: absolute;
   right: 0;
diff --git a/chrome/browser/signin/account_reconcilor_factory.cc b/chrome/browser/signin/account_reconcilor_factory.cc
index 629ad112..b58090fd 100644
--- a/chrome/browser/signin/account_reconcilor_factory.cc
+++ b/chrome/browser/signin/account_reconcilor_factory.cc
@@ -29,6 +29,8 @@
 #include "chrome/browser/chromeos/account_manager/account_migration_runner.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "chromeos/tpm/install_attributes.h"
+#include "components/signin/core/browser/active_directory_account_reconcilor_delegate.h"
 #include "components/user_manager/user_manager.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #endif
@@ -168,6 +170,13 @@
             IdentityManagerFactory::GetForProfile(profile));
       }
 
+      // Only for Active Directory accounts on Chrome OS.
+      if (chromeos::features::IsAccountManagerEnabled() &&
+          chromeos::InstallAttributes::Get()->IsActiveDirectoryManaged()) {
+        return std::make_unique<
+            signin::ActiveDirectoryAccountReconcilorDelegate>();
+      }
+
       // TODO(sinhak): Remove the if-condition (and use
       // |MirrorAccountReconcilorDelegate|) when all Chrome OS users have been
       // migrated to Account Manager.
diff --git a/chrome/browser/signin/mirror_browsertest.cc b/chrome/browser/signin/mirror_browsertest.cc
index f57d78e..488859b 100644
--- a/chrome/browser/signin/mirror_browsertest.cc
+++ b/chrome/browser/signin/mirror_browsertest.cc
@@ -115,8 +115,6 @@
 //    and not because it was on a secure Google domain.
 // This is a regression test for crbug.com/588492.
 IN_PROC_BROWSER_TEST_F(MirrorBrowserTest, MirrorRequestHeader) {
-  browser()->profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
-                                              "user@gmail.com");
   browser()->profile()->GetPrefs()->SetString(
       prefs::kGoogleServicesUserAccountId, "account_id");
 
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
index e06f5d6..a06927c 100644
--- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -5,6 +5,7 @@
 #include "base/base64.h"
 #include "base/macros.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/sync/test/integration/encryption_helper.h"
 #include "chrome/browser/sync/test/integration/feature_toggler.h"
 #include "chrome/browser/sync/test/integration/passwords_helper.h"
@@ -15,6 +16,7 @@
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/sync/password_sync_bridge.h"
 #include "components/password_manager/core/common/password_manager_features.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
 #include "components/sync/base/time.h"
 #include "components/sync/driver/profile_sync_service.h"
 #include "components/sync/driver/sync_driver_switches.h"
@@ -492,7 +494,7 @@
   ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
   GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
   GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete();
-  ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
+  ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion());
 
   ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
 
@@ -540,12 +542,63 @@
 }
 #endif  // !defined(OS_CHROMEOS)
 
+IN_PROC_BROWSER_TEST_F(SingleClientPasswordsWithAccountStorageSyncTest,
+                       SwitchesStoresOnEnablingSync) {
+  AddTestPasswordToFakeServer();
+
+  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
+
+  // On ChromeOS, Sync-the-feature starts automatically as soon as a primary
+  // account is signed in. To prevent that, explicitly set SyncRequested to
+  // false on ChromeOS.
+#if defined(OS_CHROMEOS)
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(false);
+#endif  // !defined(OS_CHROMEOS)
+
+  // Sign in to a primary account, but don't enable Sync-the-feature.
+  // Note: This state shouldn't actually be reachable (the flow for setting a
+  // primary account also enables Sync), but still best to cover it here.
+  ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
+  ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
+  ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
+
+  // Make sure the password showed up in the account store.
+  password_manager::PasswordStore* account_store =
+      passwords_helper::GetAccountPasswordStore(0);
+  ASSERT_EQ(passwords_helper::GetAllLogins(account_store).size(), 1u);
+
+  // Turn on Sync-the-feature.
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
+  GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete();
+  ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion());
+  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
+
+  // Make sure the password is now in the profile store, but *not* in the
+  // account store anymore.
+  password_manager::PasswordStore* profile_store =
+      passwords_helper::GetPasswordStore(0);
+  EXPECT_EQ(passwords_helper::GetAllLogins(profile_store).size(), 1u);
+  EXPECT_EQ(passwords_helper::GetAllLogins(account_store).size(), 0u);
+
+  // Turn off Sync-the-feature again.
+  // Note: Turning Sync off without signing out isn't actually exposed to the
+  // user, so this generally shouldn't happen. Still best to cover it here.
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(false);
+  ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
+  ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
+
+  // Now the password should be in both stores: The profile store does *not* get
+  // cleared when Sync gets disabled.
+  EXPECT_EQ(passwords_helper::GetAllLogins(profile_store).size(), 1u);
+  EXPECT_EQ(passwords_helper::GetAllLogins(account_store).size(), 1u);
+}
+
 // The unconsented primary account isn't supported on ChromeOS (see
 // IdentityManager::ComputeUnconsentedPrimaryAccountInfo()) so Sync won't start
 // up for a secondary account.
 #if !defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(SingleClientPasswordsWithAccountStorageSyncTest,
-                       SwitchesFromAccountToProfileStore) {
+                       SwitchesStoresOnMakingAccountPrimary) {
   AddTestPasswordToFakeServer();
 
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
@@ -561,7 +614,7 @@
       passwords_helper::GetAccountPasswordStore(0);
   ASSERT_EQ(passwords_helper::GetAllLogins(account_store).size(), 1u);
 
-  // Turn on Sync-the-feature.
+  // Make the account primary and turn on Sync-the-feature.
   secondary_account_helper::MakeAccountPrimary(GetProfile(0), "user@email.com");
   GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
   GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete();
@@ -574,6 +627,20 @@
       passwords_helper::GetPasswordStore(0);
   EXPECT_EQ(passwords_helper::GetAllLogins(profile_store).size(), 1u);
   EXPECT_EQ(passwords_helper::GetAllLogins(account_store).size(), 0u);
+
+  // Clear the primary account to put Sync into transport mode again.
+  // Note: Clearing the primary account without also signing out isn't exposed
+  // to the user, so this shouldn't happen. Still best to cover it here.
+  signin::ClearPrimaryAccount(
+      IdentityManagerFactory::GetForProfile(GetProfile(0)),
+      signin::ClearPrimaryAccountPolicy::KEEP_ALL_ACCOUNTS);
+  ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
+  ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
+
+  // Now the password should be in both stores: The profile store does *not* get
+  // cleared when Sync gets disabled.
+  EXPECT_EQ(passwords_helper::GetAllLogins(profile_store).size(), 1u);
+  EXPECT_EQ(passwords_helper::GetAllLogins(account_store).size(), 1u);
 }
 #endif  // !defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
index da37ac68..968b9e9d4 100644
--- a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
@@ -2,11 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <stdint.h>
-
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/test/scoped_feature_list.h"
+#include "base/test/bind_test_util.h"
 #include "base/time/time.h"
 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
 #include "chrome/browser/sync/test/integration/encryption_helper.h"
@@ -18,13 +16,9 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/sync/test/integration/user_events_helper.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
-#include "components/sync/driver/sync_driver_switches.h"
-#include "components/sync/model/model_type_sync_bridge.h"
 #include "components/sync/protocol/user_event_specifics.pb.h"
 #include "components/sync_user_events/user_event_service.h"
-#include "components/variations/variations_associated_data.h"
 
-using fake_server::FakeServer;
 using sync_pb::CommitResponse;
 using sync_pb::SyncEntity;
 using sync_pb::UserEventSpecifics;
@@ -38,74 +32,6 @@
   return type;
 }
 
-CommitResponse::ResponseType TransientErrorFirst(
-    bool* first,
-    UserEventSpecifics* retry_specifics,
-    const syncer::LoopbackServerEntity& entity) {
-  if (*first) {
-    *first = false;
-    SyncEntity sync_entity;
-    entity.SerializeAsProto(&sync_entity);
-    *retry_specifics = sync_entity.specifics().user_event();
-    return CommitResponse::TRANSIENT_ERROR;
-  } else {
-    return CommitResponse::SUCCESS;
-  }
-}
-
-// A more simplistic version of UserEventEqualityChecker that only checks the
-// case of the events. This is helpful if you do not know (or control) some of
-// the fields of the events that are created.
-class UserEventCaseChecker : public SingleClientStatusChangeChecker {
- public:
-  UserEventCaseChecker(
-      syncer::ProfileSyncService* service,
-      FakeServer* fake_server,
-      std::multiset<UserEventSpecifics::EventCase> expected_cases)
-      : SingleClientStatusChangeChecker(service),
-        fake_server_(fake_server),
-        expected_cases_(expected_cases) {}
-
-  bool IsExitConditionSatisfied() override {
-    std::vector<SyncEntity> entities =
-        fake_server_->GetSyncEntitiesByModelType(syncer::USER_EVENTS);
-
-    // |entities.size()| is only going to grow, if |entities.size()| ever
-    // becomes bigger then all hope is lost of passing, stop now.
-    EXPECT_GE(expected_cases_.size(), entities.size());
-
-    if (expected_cases_.size() > entities.size()) {
-      return false;
-    }
-
-    // Number of events on server matches expected, exit condition is satisfied.
-    // Let's verify that content matches as well. It is safe to modify
-    // |expected_specifics_|.
-    for (const SyncEntity& entity : entities) {
-      UserEventSpecifics::EventCase actual =
-          entity.specifics().user_event().event_case();
-      auto iter = expected_cases_.find(actual);
-      if (iter != expected_cases_.end()) {
-        expected_cases_.erase(iter);
-      } else {
-        ADD_FAILURE() << actual;
-      }
-    }
-
-    return true;
-  }
-
-  std::string GetDebugMessage() const override {
-    return "Waiting server side USER_EVENTS to match expected.";
-  }
-
- private:
-  FakeServer* fake_server_;
-  std::multiset<UserEventSpecifics::EventCase> expected_cases_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserEventCaseChecker);
-};
-
 class SingleClientUserEventsSyncTest : public SyncTest {
  public:
   SingleClientUserEventsSyncTest() : SyncTest(SINGLE_CLIENT) {
@@ -170,24 +96,38 @@
 #endif
 IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, MAYBE_RetryParallel) {
   ASSERT_TRUE(SetupSync());
-  bool first = true;
+
   const UserEventSpecifics specifics1 =
       CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1));
   const UserEventSpecifics specifics2 =
       CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(2));
-  UserEventSpecifics retry_specifics;
 
   syncer::UserEventService* event_service =
       browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0));
 
+  // Set up the server so that the first entity that arrives results in a
+  // transient error.
   // We're not really sure if |specifics1| or |specifics2| is going to see the
   // error, so record the one that does into |retry_specifics| and use it in
   // expectations.
-  GetFakeServer()->OverrideResponseType(
-      base::Bind(&TransientErrorFirst, &first, &retry_specifics));
+  bool first = true;
+  UserEventSpecifics retry_specifics;
+  GetFakeServer()->OverrideResponseType(base::BindLambdaForTesting(
+      [&](const syncer::LoopbackServerEntity& entity) {
+        if (first) {
+          first = false;
+          SyncEntity sync_entity;
+          entity.SerializeAsProto(&sync_entity);
+          retry_specifics = sync_entity.specifics().user_event();
+          return CommitResponse::TRANSIENT_ERROR;
+        }
+        return CommitResponse::SUCCESS;
+      }));
 
   event_service->RecordUserEvent(specifics2);
   event_service->RecordUserEvent(specifics1);
+  // The entity that got the transient error is still considered "committed" by
+  // the fake server, so we should see it *and* its retry.
   EXPECT_TRUE(ExpectUserEvents({specifics1, specifics2}));
   EXPECT_TRUE(ExpectUserEvents({specifics1, specifics2, retry_specifics}));
 }
diff --git a/chrome/browser/ui/ash/assistant/assistant_client.cc b/chrome/browser/ui/ash/assistant/assistant_client.cc
index 61fe20d6d..b8b191e2 100644
--- a/chrome/browser/ui/ash/assistant/assistant_client.cc
+++ b/chrome/browser/ui/ash/assistant/assistant_client.cc
@@ -86,14 +86,12 @@
 
   initialized_ = true;
 
-  chromeos::assistant::mojom::ClientPtr client_ptr;
-  client_binding_.Bind(mojo::MakeRequest(&client_ptr));
-
   bool is_test = base::CommandLine::ForCurrentProcess()->HasSwitch(
       ::switches::kBrowserTest);
   auto* service =
       AssistantServiceConnection::GetForProfile(profile_)->service();
-  service->Init(std::move(client_ptr), device_actions_.AddBinding(), is_test);
+  service->Init(client_receiver_.BindNewPipeAndPassRemote(),
+                device_actions_.AddReceiver(), is_test);
   assistant_image_downloader_ = std::make_unique<AssistantImageDownloader>();
   assistant_setup_ = std::make_unique<AssistantSetup>(service);
 
diff --git a/chrome/browser/ui/ash/assistant/assistant_client.h b/chrome/browser/ui/ash/assistant/assistant_client.h
index c941b40..245ae02 100644
--- a/chrome/browser/ui/ash/assistant/assistant_client.h
+++ b/chrome/browser/ui/ash/assistant/assistant_client.h
@@ -14,8 +14,8 @@
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
 #include "components/session_manager/core/session_manager_observer.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
 class AssistantImageDownloader;
@@ -100,7 +100,7 @@
   void OnUserProfileLoaded(const AccountId& account_id) override;
   void OnUserSessionStarted(bool is_primary_user) override;
 
-  mojo::Binding<chromeos::assistant::mojom::Client> client_binding_{this};
+  mojo::Receiver<chromeos::assistant::mojom::Client> client_receiver_{this};
 
   DeviceActions device_actions_;
 
diff --git a/chrome/browser/ui/ash/assistant/device_actions.cc b/chrome/browser/ui/ash/assistant/device_actions.cc
index 3e66641..250bf50 100644
--- a/chrome/browser/ui/ash/assistant/device_actions.cc
+++ b/chrome/browser/ui/ash/assistant/device_actions.cc
@@ -120,13 +120,14 @@
 DeviceActions::DeviceActions() : scoped_prefs_observer_(this) {}
 
 DeviceActions::~DeviceActions() {
-  bindings_.CloseAllBindings();
+  receivers_.Clear();
 }
 
-chromeos::assistant::mojom::DeviceActionsPtr DeviceActions::AddBinding() {
-  chromeos::assistant::mojom::DeviceActionsPtr ptr;
-  bindings_.AddBinding(this, mojo::MakeRequest(&ptr));
-  return ptr;
+mojo::PendingRemote<chromeos::assistant::mojom::DeviceActions>
+DeviceActions::AddReceiver() {
+  mojo::PendingRemote<chromeos::assistant::mojom::DeviceActions> pending_remote;
+  receivers_.Add(this, pending_remote.InitWithNewPipeAndPassReceiver());
+  return pending_remote;
 }
 
 void DeviceActions::SetWifiEnabled(bool enabled) {
diff --git a/chrome/browser/ui/ash/assistant/device_actions.h b/chrome/browser/ui/ash/assistant/device_actions.h
index e44a28b9..d3f64a89 100644
--- a/chrome/browser/ui/ash/assistant/device_actions.h
+++ b/chrome/browser/ui/ash/assistant/device_actions.h
@@ -9,8 +9,8 @@
 #include "base/scoped_observer.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 
 class DeviceActions : public ash::AndroidIntentHelper,
                       public chromeos::assistant::mojom::DeviceActions,
@@ -19,7 +19,7 @@
   DeviceActions();
   ~DeviceActions() override;
 
-  chromeos::assistant::mojom::DeviceActionsPtr AddBinding();
+  mojo::PendingRemote<chromeos::assistant::mojom::DeviceActions> AddReceiver();
 
   // mojom::DeviceActions overrides:
   void SetWifiEnabled(bool enabled) override;
@@ -46,7 +46,7 @@
   void OnAppRemoved(const std::string& id) override;
 
   ScopedObserver<ArcAppListPrefs, DeviceActions> scoped_prefs_observer_;
-  mojo::BindingSet<chromeos::assistant::mojom::DeviceActions> bindings_;
+  mojo::ReceiverSet<chromeos::assistant::mojom::DeviceActions> receivers_;
   mojo::InterfacePtrSet<chromeos::assistant::mojom::AppListEventSubscriber>
       app_list_subscribers_;
   DISALLOW_COPY_AND_ASSIGN(DeviceActions);
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
index b01b04a9..f110b63 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
@@ -20,6 +20,7 @@
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "chrome/browser/password_manager/account_storage/account_password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
@@ -165,15 +166,21 @@
 }
 
 PasswordManagerPresenter::~PasswordManagerPresenter() {
-  PasswordStore* store = GetPasswordStore();
-  if (store)
-    store->RemoveObserver(this);
+  for (bool use_account_store : {false, true}) {
+    PasswordStore* store = GetPasswordStore(use_account_store);
+    if (store) {
+      store->RemoveObserver(this);
+    }
+  }
 }
 
 void PasswordManagerPresenter::Initialize() {
-  PasswordStore* store = GetPasswordStore();
-  if (store)
-    store->AddObserver(this);
+  for (bool use_account_store : {false, true}) {
+    PasswordStore* store = GetPasswordStore(use_account_store);
+    if (store) {
+      store->AddObserver(this);
+    }
+  }
 }
 
 void PasswordManagerPresenter::OnLoginsChanged(
@@ -187,12 +194,16 @@
   password_map_.clear();
   exception_map_.clear();
 
-  PasswordStore* store = GetPasswordStore();
-  if (!store)
-    return;
-
   CancelAllRequests();
-  store->GetAllLoginsWithAffiliationAndBrandingInformation(this);
+
+  // Request an update from both stores (if they exist). This will send out two
+  // updates to |password_view_| as the two result sets come in.
+  for (bool use_account_store : {false, true}) {
+    PasswordStore* store = GetPasswordStore(use_account_store);
+    if (store) {
+      store->GetAllLoginsWithAffiliationAndBrandingInformation(this);
+    }
+  }
 }
 
 const autofill::PasswordForm* PasswordManagerPresenter::GetPassword(
@@ -307,7 +318,7 @@
 #endif
 
 void PasswordManagerPresenter::AddLogin(const autofill::PasswordForm& form) {
-  PasswordStore* store = GetPasswordStore();
+  PasswordStore* store = GetPasswordStore(form.IsUsingAccountStore());
   if (!store)
     return;
 
@@ -317,7 +328,7 @@
 }
 
 void PasswordManagerPresenter::RemoveLogin(const autofill::PasswordForm& form) {
-  PasswordStore* store = GetPasswordStore();
+  PasswordStore* store = GetPasswordStore(form.IsUsingAccountStore());
   if (!store)
     return;
 
@@ -356,14 +367,14 @@
     }
   }
 
-  PasswordStore* store = GetPasswordStore();
-  if (!store)
-    return;
-
   // An updated username implies a change in the primary key, thus we need to
   // make sure to call the right API. Update every entry in the equivalence
   // class.
   for (const auto& old_form : old_forms) {
+    PasswordStore* store = GetPasswordStore(old_form->IsUsingAccountStore());
+    if (!store)
+      continue;
+
     autofill::PasswordForm new_form = *old_form;
     new_form.username_value = new_username;
     if (new_password)
@@ -400,17 +411,31 @@
 bool PasswordManagerPresenter::TryRemovePasswordEntries(
     PasswordFormMap* form_map,
     PasswordFormMap::const_iterator forms_iter) {
-  PasswordStore* store = GetPasswordStore();
-  if (!store)
-    return false;
-
   const FormVector& forms = forms_iter->second;
   DCHECK(!forms.empty());
 
+  bool use_account_store = forms[0]->IsUsingAccountStore();
+  PasswordStore* store = GetPasswordStore(use_account_store);
+  if (!store)
+    return false;
+
+  // Note: All entries in |forms| have the same SortKey, i.e. effectively the
+  // same origin, username and password. Given our legacy unique key in the
+  // underlying password store it is possible that we have several entries with
+  // the same origin, username and password, but different username_elements and
+  // password_elements. For the user all of these credentials are the same,
+  // which is why we have this SortKey deduplication logic when presenting them
+  // to the user.
+  // This also means that restoring |forms[0]| is enough here, as all other
+  // forms would have the same origin, username and password anyway.
   undo_manager_.AddUndoOperation(
       std::make_unique<RemovePasswordOperation>(this, *forms[0]));
-  for (const auto& form : forms)
+  for (const auto& form : forms) {
+    // PasswordFormMap is indexed by sort key, which includes the store
+    // (profile / account), so all forms here must come from the same store.
+    DCHECK_EQ(use_account_store, form->IsUsingAccountStore());
     store->RemoveLogin(*form);
+  }
 
   form_map->erase(forms_iter);
   return true;
@@ -440,7 +465,13 @@
   password_view_->SetPasswordExceptionList(GetEntryList(exception_map_));
 }
 
-PasswordStore* PasswordManagerPresenter::GetPasswordStore() {
+PasswordStore* PasswordManagerPresenter::GetPasswordStore(
+    bool use_account_store) {
+  if (use_account_store) {
+    return AccountPasswordStoreFactory::GetForProfile(
+               password_view_->GetProfile(), ServiceAccessType::EXPLICIT_ACCESS)
+        .get();
+  }
   return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(),
                                              ServiceAccessType::EXPLICIT_ACCESS)
       .get();
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter.h b/chrome/browser/ui/passwords/settings/password_manager_presenter.h
index ae0136b..642cef8 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.h
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.h
@@ -146,7 +146,7 @@
   void SetPasswordExceptionList();
 
   // Returns the password store associated with the currently active profile.
-  password_manager::PasswordStore* GetPasswordStore();
+  password_manager::PasswordStore* GetPasswordStore(bool use_account_store);
 
   PasswordFormMap password_map_;
   PasswordFormMap exception_map_;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 3054560..5598e64 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -170,6 +170,7 @@
   }
   BuildIdentity();
   BuildAutofillButtons();
+  BuildSelectableProfiles();
 }
 
 void ProfileMenuView::OnAvatarMenuChanged(
@@ -346,13 +347,15 @@
                               kUserMenu_SignOutAllAccounts);
 }
 
-void ProfileMenuView::OnOtherProfileButtonClicked(int profile_index) {
+void ProfileMenuView::OnOtherProfileSelected(
+    const base::FilePath& profile_path) {
   RecordClick(ActionableItem::kOtherProfileButton);
   // TODO(crbug.com/995757): Remove user action.
   base::RecordAction(base::UserMetricsAction("ProfileChooser_ProfileClicked"));
-  avatar_menu_->SwitchToProfile(profile_index, /*always_create=*/false,
-                                ProfileMetrics::SWITCH_PROFILE_ICON);
   Hide();
+  profiles::SwitchToProfile(profile_path, /*always_create=*/false,
+                            ProfileManager::CreateCallback(),
+                            ProfileMetrics::SWITCH_PROFILE_ICON);
 }
 
 void ProfileMenuView::OnCookiesClearedOnExitLinkClicked() {
@@ -411,6 +414,22 @@
                           base::Unretained(this)));
 }
 
+void ProfileMenuView::BuildSelectableProfiles() {
+  auto profile_entries = g_browser_process->profile_manager()
+                             ->GetProfileAttributesStorage()
+                             .GetAllProfilesAttributes();
+  for (ProfileAttributesEntry* profile_entry : profile_entries) {
+    // The current profile is excluded.
+    if (profile_entry->GetPath() == browser()->profile()->GetPath())
+      continue;
+
+    AddSelectableProfile(
+        profile_entry->GetAvatarIcon(), profile_entry->GetName(),
+        base::BindRepeating(&ProfileMenuView::OnOtherProfileSelected,
+                            base::Unretained(this), profile_entry->GetPath()));
+  }
+}
+
 void ProfileMenuView::AddProfileMenuView(AvatarMenu* avatar_menu) {
   // Separate items into active and alternatives.
   const AvatarMenu::Item* active_item = nullptr;
@@ -740,8 +759,8 @@
           profiles::SHAPE_CIRCLE);
       views::Button* button = CreateAndAddButton(
           *image.ToImageSkia(), profiles::GetProfileSwitcherTextForItem(item),
-          base::BindRepeating(&ProfileMenuView::OnOtherProfileButtonClicked,
-                              base::Unretained(this), profile_index));
+          base::BindRepeating(&ProfileMenuView::OnOtherProfileSelected,
+                              base::Unretained(this), item.profile_path));
 
       if (!first_profile_button_)
         first_profile_button_ = button;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.h b/chrome/browser/ui/views/profiles/profile_menu_view.h
index bde08a2a..08876c81 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.h
@@ -83,7 +83,7 @@
   void OnSigninButtonClicked();
   void OnSigninAccountButtonClicked(AccountInfo account);
   void OnSignoutButtonClicked();
-  void OnOtherProfileButtonClicked(int profile_index);
+  void OnOtherProfileSelected(const base::FilePath& profile_path);
   void OnCookiesClearedOnExitLinkClicked();
 
   // Should be called inside each button/link action.
@@ -100,6 +100,7 @@
   // Helper methods for building the menu.
   void BuildIdentity();
   void BuildAutofillButtons();
+  void BuildSelectableProfiles();
 
   // Adds the profile chooser view.
   void AddProfileMenuView(AvatarMenu* avatar_menu);
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index 70b4025..cd84957 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -218,6 +218,28 @@
   RegisterClickAction(button, std::move(action));
 }
 
+void ProfileMenuViewBase::AddSelectableProfile(const gfx::Image& image,
+                                               const base::string16& name,
+                                               base::RepeatingClosure action) {
+  constexpr int kTopMargin = 8;
+  constexpr int kImageSize = 22;
+
+  // Initialize layout if this is the first time a button is added.
+  if (!selectable_profiles_container_->GetLayoutManager()) {
+    selectable_profiles_container_->SetLayoutManager(
+        std::make_unique<views::BoxLayout>(
+            views::BoxLayout::Orientation::kVertical,
+            gfx::Insets(kTopMargin, 0, 0, 0)));
+  }
+
+  gfx::Image sized_image =
+      profiles::GetSizedAvatarIcon(image, /*is_rectangle=*/true, kImageSize,
+                                   kImageSize, profiles::SHAPE_CIRCLE);
+  views::Button* button = selectable_profiles_container_->AddChildView(
+      std::make_unique<HoverButton>(this, sized_image.AsImageSkia(), name));
+  RegisterClickAction(button, std::move(action));
+}
+
 ax::mojom::Role ProfileMenuViewBase::GetAccessibleWindowRole() {
   // Return |ax::mojom::Role::kDialog| which will make screen readers announce
   // the following in the listed order:
@@ -308,6 +330,8 @@
       components->AddChildView(std::make_unique<views::View>());
   shortcut_features_container_ =
       components->AddChildView(std::make_unique<views::View>());
+  selectable_profiles_container_ =
+      components->AddChildView(std::make_unique<views::View>());
 
   // Create a scroll view to hold the components.
   auto scroll_view = std::make_unique<views::ScrollView>();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.h b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
index 70bade10..3ede808 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
@@ -100,6 +100,9 @@
   void AddShortcutFeatureButton(const gfx::VectorIcon& icon,
                                 const base::string16& text,
                                 base::RepeatingClosure action);
+  void AddSelectableProfile(const gfx::Image& image,
+                            const base::string16& name,
+                            base::RepeatingClosure action);
 
   // Initializes a new group of menu items. A separator is added before them if
   // |add_separator| is true.
@@ -200,6 +203,7 @@
   // Component containers.
   views::View* identity_info_container_ = nullptr;
   views::View* shortcut_features_container_ = nullptr;
+  views::View* selectable_profiles_container_ = nullptr;
 
   CloseBubbleOnTabActivationHelper close_bubble_helper_;
 
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
index 52ce18c..6b4ae8f 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
@@ -17,9 +17,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/dbus/menu/menu.h"
-#include "components/dbus/menu/properties_interface.h"
-#include "components/dbus/menu/success_barrier_callback.h"
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/dbus_properties.h"
+#include "components/dbus/properties/success_barrier_callback.h"
+#include "components/dbus/properties/types.h"
 #include "components/dbus/thread_linux/dbus_thread_linux.h"
 #include "dbus/bus.h"
 #include "dbus/exported_object.h"
@@ -279,7 +279,7 @@
       bus_->GetExportedObject(dbus::ObjectPath(kPathDbusMenu)), barrier_);
   UpdateMenuImpl(delegate_->GetMenuModel(), false);
 
-  properties_ = std::make_unique<DbusPropertiesInterface>(item_, barrier_);
+  properties_ = std::make_unique<DbusProperties>(item_, barrier_);
   properties_->RegisterInterface(kInterfaceStatusNotifierItem);
   auto set_property = [&](const std::string& property_name, auto&& value) {
     properties_->SetProperty(kInterfaceStatusNotifierItem, property_name,
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h
index bd15a50..67121638 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h
@@ -24,7 +24,7 @@
 }  // namespace gfx
 
 class DbusMenu;
-class DbusPropertiesInterface;
+class DbusProperties;
 
 // A status icon following the StatusNotifierItem specification.
 // https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/
@@ -93,7 +93,7 @@
 
   base::RepeatingCallback<void(bool)> barrier_;
 
-  std::unique_ptr<DbusPropertiesInterface> properties_;
+  std::unique_ptr<DbusProperties> properties_;
 
   std::unique_ptr<DbusMenu> menu_;
   // A menu that contains the click action (if there is a click action) and a
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn
index d8ff81b..3c3060d2 100644
--- a/chrome/browser/web_applications/components/BUILD.gn
+++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -13,6 +13,7 @@
     "external_install_options.h",
     "externally_installed_web_app_prefs.cc",
     "externally_installed_web_app_prefs.h",
+    "file_handler_manager.cc",
     "file_handler_manager.h",
     "install_bounce_metric.cc",
     "install_bounce_metric.h",
diff --git a/chrome/browser/web_applications/components/file_handler_manager.cc b/chrome/browser/web_applications/components/file_handler_manager.cc
new file mode 100644
index 0000000..5ab054b
--- /dev/null
+++ b/chrome/browser/web_applications/components/file_handler_manager.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/web_applications/components/file_handler_manager.h"
+
+namespace web_app {
+
+FileHandlerManager::FileHandlerManager(Profile* profile)
+    : profile_(profile), registrar_observer_(this) {}
+
+FileHandlerManager::~FileHandlerManager() = default;
+
+void FileHandlerManager::SetSubsystems(AppRegistrar* registrar) {
+  registrar_ = registrar;
+  registrar_observer_.Add(registrar);
+}
+
+void FileHandlerManager::OnWebAppInstalled(const AppId& installed_app_id) {
+  // TODO(davidbienvenu): Hook up with file association registration code on
+  // windows.
+}
+
+void FileHandlerManager::OnWebAppUninstalled(const AppId& installed_app_id) {
+  // TODO(davidbienvenu): Hook up to file association de-registration code on
+  // windows.
+}
+
+void FileHandlerManager::OnAppRegistrarDestroyed() {
+  registrar_observer_.RemoveAll();
+}
+
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/file_handler_manager.h b/chrome/browser/web_applications/components/file_handler_manager.h
index 2ec512cb..91a8b22c 100644
--- a/chrome/browser/web_applications/components/file_handler_manager.h
+++ b/chrome/browser/web_applications/components/file_handler_manager.h
@@ -8,6 +8,9 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "components/services/app_service/public/cpp/file_handler_info.h"
 
@@ -15,10 +18,13 @@
 
 namespace web_app {
 
-class FileHandlerManager {
+class FileHandlerManager : public AppRegistrarObserver {
  public:
-  explicit FileHandlerManager(Profile* profile) : profile_(profile) {}
-  virtual ~FileHandlerManager() = default;
+  explicit FileHandlerManager(Profile* profile);
+  ~FileHandlerManager() override;
+
+  // |registrar| is used to observe OnWebAppInstalled/Uninstalled events.
+  void SetSubsystems(AppRegistrar* registrar);
 
   // Gets all file handlers for |app_id|. |nullptr| if the app has no file
   // handlers.
@@ -31,6 +37,14 @@
 
  private:
   Profile* const profile_;
+  AppRegistrar* registrar_ = nullptr;
+
+  // AppRegistrarObserver:
+  void OnWebAppInstalled(const AppId& app_id) override;
+  void OnWebAppUninstalled(const AppId& app_id) override;
+  void OnAppRegistrarDestroyed() override;
+
+  ScopedObserver<AppRegistrar, AppRegistrarObserver> registrar_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(FileHandlerManager);
 };
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc
index def7ed34..36a1cb2c 100644
--- a/chrome/browser/web_applications/web_app_provider.cc
+++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -190,6 +190,7 @@
   system_web_app_manager_->SetSubsystems(pending_app_manager_.get(),
                                          registrar_.get(), ui_manager_.get());
   web_app_policy_manager_->SetSubsystems(pending_app_manager_.get());
+  file_handler_manager_->SetSubsystems(registrar_.get());
 
   connected_ = true;
 }
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index fabb5226..671ce0b3 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -168,8 +168,6 @@
     FPL("Offline Pages/prefech_store");
 const base::FilePath::CharType kOfflinePageRequestQueueDirname[] =
     FPL("Offline Pages/request_queue");
-const base::FilePath::CharType kPageLoadCappingOptOutDBFilename[] =
-    FPL("page_load_capping_opt_out.db");
 const base::FilePath::CharType kPreferencesFilename[] = FPL("Preferences");
 const base::FilePath::CharType kPreviewsOptOutDBFilename[] =
     FPL("previews_opt_out.db");
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index 541a58f..d29874a 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -63,7 +63,6 @@
 extern const base::FilePath::CharType kOfflinePageMetadataDirname[];
 extern const base::FilePath::CharType kOfflinePagePrefetchStoreDirname[];
 extern const base::FilePath::CharType kOfflinePageRequestQueueDirname[];
-extern const base::FilePath::CharType kPageLoadCappingOptOutDBFilename[];
 extern const base::FilePath::CharType kPreferencesFilename[];
 extern const base::FilePath::CharType kPreviewsOptOutDBFilename[];
 extern const base::FilePath::CharType kReadmeFilename[];
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index d4869c1..472cac83c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -983,7 +983,6 @@
       "../browser/net/websocket_browsertest.cc",
       "../browser/no_best_effort_tasks_browsertest.cc",
       "../browser/no_best_effort_tasks_during_startup_browsertest.cc",
-      "../browser/notifications/scheduler/notification_schedule_service_browsertest.cc",
       "../browser/ntp_snippets/content_suggestions_service_factory_browsertest.cc",
       "../browser/ntp_tiles/ntp_tiles_browsertest.cc",
       "../browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc",
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 16bcbae..bcfaea3 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3854,6 +3854,9 @@
   "ReportDeviceHardwareStatus": {
   },
 
+  "ReportDeviceOsUpdateStatus": {
+  },
+
   "ReportDeviceSessionStatus": {
   },
 
diff --git a/chromeos/dbus/biod/biod_client_unittest.cc b/chromeos/dbus/biod/biod_client_unittest.cc
index a5d803c..c905ccc4 100644
--- a/chromeos/dbus/biod/biod_client_unittest.cc
+++ b/chromeos/dbus/biod/biod_client_unittest.cc
@@ -158,7 +158,7 @@
 
   std::map<std::string, std::unique_ptr<dbus::Response>> pending_method_calls_;
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   // Mock bus and proxy for simulating calls.
   scoped_refptr<dbus::MockBus> bus_;
diff --git a/chromeos/dbus/cec_service_client_unittest.cc b/chromeos/dbus/cec_service_client_unittest.cc
index 94adc7f4..7f6b87a 100644
--- a/chromeos/dbus/cec_service_client_unittest.cc
+++ b/chromeos/dbus/cec_service_client_unittest.cc
@@ -104,7 +104,7 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<CecServiceClient> client_;
   scoped_refptr<dbus::MockBus> mock_bus_;
   scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
diff --git a/chromeos/dbus/oobe_configuration_client_unittest.cc b/chromeos/dbus/oobe_configuration_client_unittest.cc
index a5d9801..91bd311 100644
--- a/chromeos/dbus/oobe_configuration_client_unittest.cc
+++ b/chromeos/dbus/oobe_configuration_client_unittest.cc
@@ -102,7 +102,7 @@
   // The client to be tested.
   std::unique_ptr<OobeConfigurationClient> client_;
   // A message loop to emulate asynchronous behavior.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   // The mock bus.
   scoped_refptr<dbus::MockBus> mock_bus_;
   // The mock object proxy.
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc
index 6955836..ce4cae28 100644
--- a/chromeos/services/assistant/assistant_manager_service_impl.cc
+++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -432,8 +432,10 @@
 }
 
 void AssistantManagerServiceImpl::AddAssistantInteractionSubscriber(
-    mojom::AssistantInteractionSubscriberPtr subscriber) {
-  interaction_subscribers_.AddPtr(std::move(subscriber));
+    mojo::PendingRemote<mojom::AssistantInteractionSubscriber> subscriber) {
+  mojo::Remote<mojom::AssistantInteractionSubscriber> subscriber_remote(
+      std::move(subscriber));
+  interaction_subscribers_.Add(std::move(subscriber_remote));
 }
 
 void AssistantManagerServiceImpl::RetrieveNotification(
@@ -509,7 +511,8 @@
       base::TimeDelta::FromMilliseconds(time_ms));
 
   // Notify subscribers that a wait has been started.
-  interaction_subscribers_.ForAllPtrs([](auto* ptr) { ptr->OnWaitStarted(); });
+  for (auto& it : interaction_subscribers_)
+    it->OnWaitStarted();
 }
 
 // TODO(b/113541754): Deprecate this API when the server provides a fallback.
@@ -1226,9 +1229,8 @@
                              : mojom::AssistantInteractionType::kText;
   }
 
-  interaction_subscribers_.ForAllPtrs([&metadata_ptr](auto* ptr) {
-    ptr->OnInteractionStarted(metadata_ptr->Clone());
-  });
+  for (auto& it : interaction_subscribers_)
+    it->OnInteractionStarted(metadata_ptr->Clone());
 }
 
 void AssistantManagerServiceImpl::OnConversationTurnFinishedOnMainThread(
@@ -1249,20 +1251,20 @@
     case Resolution::NORMAL:
     case Resolution::NORMAL_WITH_FOLLOW_ON:
     case Resolution::NO_RESPONSE:
-      interaction_subscribers_.ForAllPtrs([](auto* ptr) {
-        ptr->OnInteractionFinished(
+      for (auto& it : interaction_subscribers_) {
+        it->OnInteractionFinished(
             mojom::AssistantInteractionResolution::kNormal);
-      });
+      }
 
       RecordQueryResponseTypeUMA();
       break;
     // Interaction ended due to interruption.
     case Resolution::BARGE_IN:
     case Resolution::CANCELLED:
-      interaction_subscribers_.ForAllPtrs([](auto* ptr) {
-        ptr->OnInteractionFinished(
+      for (auto& it : interaction_subscribers_) {
+        it->OnInteractionFinished(
             mojom::AssistantInteractionResolution::kInterruption);
-      });
+      }
 
       if (receive_inline_response_ || receive_modify_settings_proto_response_ ||
           !receive_url_response_.empty()) {
@@ -1271,25 +1273,25 @@
       break;
     // Interaction ended due to mic timeout.
     case Resolution::TIMEOUT:
-      interaction_subscribers_.ForAllPtrs([](auto* ptr) {
-        ptr->OnInteractionFinished(
+      for (auto& it : interaction_subscribers_) {
+        it->OnInteractionFinished(
             mojom::AssistantInteractionResolution::kMicTimeout);
-      });
+      }
       break;
     // Interaction ended due to error.
     case Resolution::COMMUNICATION_ERROR:
-      interaction_subscribers_.ForAllPtrs([](auto* ptr) {
-        ptr->OnInteractionFinished(
+      for (auto& it : interaction_subscribers_) {
+        it->OnInteractionFinished(
             mojom::AssistantInteractionResolution::kError);
-      });
+      }
       break;
     // Interaction ended because the device was not selected to produce a
     // response. This occurs due to multi-device hotword loss.
     case Resolution::DEVICE_NOT_SELECTED:
-      interaction_subscribers_.ForAllPtrs([](auto* ptr) {
-        ptr->OnInteractionFinished(
+      for (auto& it : interaction_subscribers_) {
+        it->OnInteractionFinished(
             mojom::AssistantInteractionResolution::kMultiDeviceHotwordLoss);
-      });
+      }
       break;
   }
 }
@@ -1299,23 +1301,22 @@
     const std::string& fallback) {
   receive_inline_response_ = true;
 
-  interaction_subscribers_.ForAllPtrs(
-      [&html, &fallback](auto* ptr) { ptr->OnHtmlResponse(html, fallback); });
+  for (auto& it : interaction_subscribers_)
+    it->OnHtmlResponse(html, fallback);
 }
 
 void AssistantManagerServiceImpl::OnShowSuggestionsOnMainThread(
     const std::vector<mojom::AssistantSuggestionPtr>& suggestions) {
-  interaction_subscribers_.ForAllPtrs([&suggestions](auto* ptr) {
-    ptr->OnSuggestionsResponse(mojo::Clone(suggestions));
-  });
+  for (auto& it : interaction_subscribers_)
+    it->OnSuggestionsResponse(mojo::Clone(suggestions));
 }
 
 void AssistantManagerServiceImpl::OnShowTextOnMainThread(
     const std::string& text) {
   receive_inline_response_ = true;
 
-  interaction_subscribers_.ForAllPtrs(
-      [&text](auto* ptr) { ptr->OnTextResponse(text); });
+  for (auto& it : interaction_subscribers_)
+    it->OnTextResponse(text);
 }
 
 void AssistantManagerServiceImpl::OnOpenUrlOnMainThread(const std::string& url,
@@ -1323,9 +1324,8 @@
   receive_url_response_ = url;
   const GURL gurl = GURL(url);
 
-  interaction_subscribers_.ForAllPtrs([&gurl, in_background](auto* ptr) {
-    ptr->OnOpenUrlResponse(gurl, in_background);
-  });
+  for (auto& it : interaction_subscribers_)
+    it->OnOpenUrlResponse(gurl, in_background);
 }
 
 void AssistantManagerServiceImpl::OnPlaybackStateChange(
@@ -1364,42 +1364,42 @@
         recognition_result) {
   switch (state) {
     case assistant_client::ConversationStateListener::RecognitionState::STARTED:
-      interaction_subscribers_.ForAllPtrs(
-          [](auto* ptr) { ptr->OnSpeechRecognitionStarted(); });
+      for (auto& it : interaction_subscribers_)
+        it->OnSpeechRecognitionStarted();
       break;
     case assistant_client::ConversationStateListener::RecognitionState::
         INTERMEDIATE_RESULT:
-      interaction_subscribers_.ForAllPtrs([&recognition_result](auto* ptr) {
-        ptr->OnSpeechRecognitionIntermediateResult(
+      for (auto& it : interaction_subscribers_) {
+        it->OnSpeechRecognitionIntermediateResult(
             recognition_result.high_confidence_text,
             recognition_result.low_confidence_text);
-      });
+      }
       break;
     case assistant_client::ConversationStateListener::RecognitionState::
         END_OF_UTTERANCE:
-      interaction_subscribers_.ForAllPtrs(
-          [](auto* ptr) { ptr->OnSpeechRecognitionEndOfUtterance(); });
+      for (auto& it : interaction_subscribers_)
+        it->OnSpeechRecognitionEndOfUtterance();
       break;
     case assistant_client::ConversationStateListener::RecognitionState::
         FINAL_RESULT:
-      interaction_subscribers_.ForAllPtrs([&recognition_result](auto* ptr) {
-        ptr->OnSpeechRecognitionFinalResult(
+      for (auto& it : interaction_subscribers_) {
+        it->OnSpeechRecognitionFinalResult(
             recognition_result.recognized_speech);
-      });
+      }
       break;
   }
 }
 
 void AssistantManagerServiceImpl::OnRespondingStartedOnMainThread(
     bool is_error_response) {
-  interaction_subscribers_.ForAllPtrs(
-      [is_error_response](auto* ptr) { ptr->OnTtsStarted(is_error_response); });
+  for (auto& it : interaction_subscribers_)
+    it->OnTtsStarted(is_error_response);
 }
 
 void AssistantManagerServiceImpl::OnSpeechLevelUpdatedOnMainThread(
     const float speech_level) {
-  interaction_subscribers_.ForAllPtrs(
-      [&speech_level](auto* ptr) { ptr->OnSpeechLevelUpdated(speech_level); });
+  for (auto& it : interaction_subscribers_)
+    it->OnSpeechLevelUpdated(speech_level);
 }
 
 void AssistantManagerServiceImpl::OnAlarmTimerStateChangedOnMainThread() {
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h
index 9c6d5b1..f7a56ab 100644
--- a/chromeos/services/assistant/assistant_manager_service_impl.h
+++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -26,8 +26,8 @@
 #include "libassistant/shared/public/device_state_listener.h"
 #include "libassistant/shared/public/media_manager.h"
 #include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 #include "services/device/public/mojom/battery_monitor.mojom.h"
 #include "services/media_session/public/mojom/media_controller.mojom.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
@@ -120,7 +120,8 @@
                                      bool allow_tts) override;
   void StopActiveInteraction(bool cancel_conversation) override;
   void AddAssistantInteractionSubscriber(
-      mojom::AssistantInteractionSubscriberPtr subscriber) override;
+      mojo::PendingRemote<mojom::AssistantInteractionSubscriber> subscriber)
+      override;
   void RetrieveNotification(mojom::AssistantNotificationPtr notification,
                             int action_index) override;
   void DismissNotification(
@@ -306,7 +307,7 @@
   // same ownership as assistant_manager_.
   assistant_client::AssistantManagerInternal* assistant_manager_internal_ =
       nullptr;
-  mojo::InterfacePtrSet<mojom::AssistantInteractionSubscriber>
+  mojo::RemoteSet<mojom::AssistantInteractionSubscriber>
       interaction_subscribers_;
   media_session::mojom::MediaControllerPtr media_controller_;
 
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc
index 9e03cfb0..755edb5b 100644
--- a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc
+++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc
@@ -72,7 +72,7 @@
     bool cancel_conversation) {}
 
 void FakeAssistantManagerServiceImpl::AddAssistantInteractionSubscriber(
-    mojom::AssistantInteractionSubscriberPtr subscriber) {}
+    mojo::PendingRemote<mojom::AssistantInteractionSubscriber> subscriber) {}
 
 void FakeAssistantManagerServiceImpl::RetrieveNotification(
     mojom::AssistantNotificationPtr notification,
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.h b/chromeos/services/assistant/fake_assistant_manager_service_impl.h
index 2e2c7ad..92198f9 100644
--- a/chromeos/services/assistant/fake_assistant_manager_service_impl.h
+++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.h
@@ -51,7 +51,8 @@
                                      bool allow_tts) override;
   void StopActiveInteraction(bool cancel_conversation) override;
   void AddAssistantInteractionSubscriber(
-      mojom::AssistantInteractionSubscriberPtr subscriber) override;
+      mojo::PendingRemote<mojom::AssistantInteractionSubscriber> subscriber)
+      override;
   void RetrieveNotification(mojom::AssistantNotificationPtr notification,
                             int action_index) override;
   void DismissNotification(
diff --git a/chromeos/services/assistant/public/mojom/assistant.mojom b/chromeos/services/assistant/public/mojom/assistant.mojom
index 920a9fc..3a31331 100644
--- a/chromeos/services/assistant/public/mojom/assistant.mojom
+++ b/chromeos/services/assistant/public/mojom/assistant.mojom
@@ -28,8 +28,8 @@
 interface AssistantService {
   // Initiates assistant and provides interfaces for assistant to call into the
   // browser.
-  Init(Client assistant_client_interface,
-       DeviceActions device_actions_interface,
+  Init(pending_remote<Client> assistant_client_interface,
+       pending_remote<DeviceActions> device_actions_interface,
        bool is_test);
 
   // Binds the main assistant backend interface.
@@ -99,7 +99,8 @@
 
   // Registers assistant interaction event subscriber. Subscribers'
   // implementation is responsible for selecting events of interest.
-  AddAssistantInteractionSubscriber(AssistantInteractionSubscriber subscriber);
+  AddAssistantInteractionSubscriber(
+      pending_remote<AssistantInteractionSubscriber> subscriber);
 
   // Retrieves a notification. A voiceless interaction will be sent to server to
   // retrieve the notification of |action_index|, which can trigger other
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc
index 293bddd..828bcb3 100644
--- a/chromeos/services/assistant/service.cc
+++ b/chromeos/services/assistant/service.cc
@@ -136,13 +136,13 @@
   return &assistant_state_;
 }
 
-void Service::Init(mojom::ClientPtr client,
-                   mojom::DeviceActionsPtr device_actions,
+void Service::Init(mojo::PendingRemote<mojom::Client> client,
+                   mojo::PendingRemote<mojom::DeviceActions> device_actions,
                    bool is_test) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   is_test_ = is_test;
-  client_ = std::move(client);
-  device_actions_ = std::move(device_actions);
+  client_.Bind(std::move(client));
+  device_actions_.Bind(std::move(device_actions));
 
   assistant_state_.Init(client_.get());
   assistant_state_.AddObserver(this);
diff --git a/chromeos/services/assistant/service.h b/chromeos/services/assistant/service.h
index 4ce3622..e1976d62 100644
--- a/chromeos/services/assistant/service.h
+++ b/chromeos/services/assistant/service.h
@@ -124,8 +124,8 @@
   friend class AssistantServiceTest;
 
   // mojom::AssistantService overrides
-  void Init(mojom::ClientPtr client,
-            mojom::DeviceActionsPtr device_actions,
+  void Init(mojo::PendingRemote<mojom::Client> client,
+            mojo::PendingRemote<mojom::DeviceActions> device_actions,
             bool is_test) override;
   void BindAssistant(mojo::PendingReceiver<mojom::Assistant> receiver) override;
   void BindSettingsManager(
@@ -176,8 +176,8 @@
   mojo::ReceiverSet<mojom::Assistant> assistant_receivers_;
 
   bool observing_ash_session_ = false;
-  mojom::ClientPtr client_;
-  mojom::DeviceActionsPtr device_actions_;
+  mojo::Remote<mojom::Client> client_;
+  mojo::Remote<mojom::DeviceActions> device_actions_;
 
   identity::mojom::IdentityAccessorPtr identity_accessor_;
 
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc
index ee45e5f..e78e6464 100644
--- a/chromeos/services/assistant/service_unittest.cc
+++ b/chromeos/services/assistant/service_unittest.cc
@@ -155,12 +155,10 @@
 
 class FakeDeviceActions : mojom::DeviceActions {
  public:
-  FakeDeviceActions() : binding_(this) {}
+  FakeDeviceActions() {}
 
-  mojom::DeviceActionsPtr CreateInterfacePtrAndBind() {
-    mojom::DeviceActionsPtr ptr;
-    binding_.Bind(mojo::MakeRequest(&ptr));
-    return ptr;
+  mojo::PendingRemote<mojom::DeviceActions> CreatePendingRemoteAndBind() {
+    return receiver_.BindNewPipeAndPassRemote();
   }
 
  private:
@@ -183,7 +181,7 @@
       chromeos::assistant::mojom::AppListEventSubscriberPtr subscriber)
       override {}
 
-  mojo::Binding<mojom::DeviceActions> binding_;
+  mojo::Receiver<mojom::DeviceActions> receiver_{this};
 
   DISALLOW_COPY_AND_ASSIGN(FakeDeviceActions);
 };
@@ -234,9 +232,8 @@
     service_->SetIdentityAccessorForTesting(
         fake_identity_accessor_.CreateInterfacePtrAndBind());
 
-    remote_service_->Init(mojom::ClientPtr(mojom::ClientPtrInfo(
-                              fake_assistant_client_.MakeRemote())),
-                          fake_device_actions_.CreateInterfacePtrAndBind(),
+    remote_service_->Init(fake_assistant_client_.MakeRemote(),
+                          fake_device_actions_.CreatePendingRemoteAndBind(),
                           /*is_test=*/true);
     base::RunLoop().RunUntilIdle();
   }
diff --git a/chromeos/services/assistant/test_support/mock_assistant.h b/chromeos/services/assistant/test_support/mock_assistant.h
index 189304b..4b7df36 100644
--- a/chromeos/services/assistant/test_support/mock_assistant.h
+++ b/chromeos/services/assistant/test_support/mock_assistant.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace gfx {
@@ -37,7 +38,8 @@
 
   MOCK_METHOD1(
       AddAssistantInteractionSubscriber,
-      void(chromeos::assistant::mojom::AssistantInteractionSubscriberPtr));
+      void(mojo::PendingRemote<
+           chromeos::assistant::mojom::AssistantInteractionSubscriber>));
 
   MOCK_METHOD2(RetrieveNotification,
                void(chromeos::assistant::mojom::AssistantNotificationPtr, int));
diff --git a/components/BUILD.gn b/components/BUILD.gn
index a0e26bf1..a25a222 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -387,7 +387,10 @@
   }
 
   if (use_dbus) {
-    deps += [ "//components/dbus/menu:unit_tests" ]
+    deps += [
+      "//components/dbus/menu:unit_tests",
+      "//components/dbus/properties:unit_tests",
+    ]
   }
 
   if (enable_plugins) {
diff --git a/components/arc/mojom/auth.mojom b/components/arc/mojom/auth.mojom
index f723c1e..c72a63c 100644
--- a/components/arc/mojom/auth.mojom
+++ b/components/arc/mojom/auth.mojom
@@ -78,6 +78,9 @@
 
   // Account type is not supported for authorization.
   [MinVersion=16] UNSUPPORTED_ACCOUNT_TYPE = 20,
+
+  // Account is not present in Chrome OS Account Manager.
+  [MinVersion=17] CHROME_ACCOUNT_NOT_FOUND = 21,
 };
 
 // These values describe account check status.
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
index 7ae1e1c..50b4ab8 100644
--- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -293,7 +293,7 @@
 
  private:
   ScopedTempDir temp_dir_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockAutofillWebDataBackend> backend_;
   AutofillTable table_;
   WebDatabase db_;
diff --git a/components/autofill/core/common/password_form.cc b/components/autofill/core/common/password_form.cc
index 60fc4468..c1a3086 100644
--- a/components/autofill/core/common/password_form.cc
+++ b/components/autofill/core/common/password_form.cc
@@ -148,6 +148,10 @@
          !HasNewPasswordElement();
 }
 
+bool PasswordForm::IsUsingAccountStore() const {
+  return from_store == Store::kAccountStore;
+}
+
 bool PasswordForm::operator==(const PasswordForm& form) const {
   return scheme == form.scheme && signon_realm == form.signon_realm &&
          origin == form.origin && action == form.action &&
diff --git a/components/autofill/core/common/password_form.h b/components/autofill/core/common/password_form.h
index b3508e05..81017534 100644
--- a/components/autofill/core/common/password_form.h
+++ b/components/autofill/core/common/password_form.h
@@ -338,6 +338,10 @@
   // not set.
   bool IsSingleUsername() const;
 
+  // Returns whether this form is stored in the account-scoped store, i.e.
+  // whether |from_store == Store::kAccountStore|.
+  bool IsUsingAccountStore() const;
+
   // Equality operators for testing.
   bool operator==(const PasswordForm& form) const;
   bool operator!=(const PasswordForm& form) const;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index 0212d44..74360d7 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -262,6 +262,10 @@
   // Get associated web contents.
   virtual content::WebContents* GetWebContents() = 0;
 
+  // Returns the e-mail address that corresponds to the access token or an empty
+  // string.
+  virtual std::string GetAccountEmailAddress() = 0;
+
   // Sets or updates contextual information.
   // Passing nullptr clears the contextual information.
   virtual void SetDetails(std::unique_ptr<Details> details) = 0;
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
index 851fc109..f5c840f7 100644
--- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc
+++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -403,6 +403,9 @@
     }
   }
 
+  collect_user_data_options->default_email =
+      delegate_->GetAccountEmailAddress();
+
   return collect_user_data_options;
 }
 
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h
index ccd86dcf..c708be31 100644
--- a/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -200,6 +200,7 @@
   MOCK_METHOD0(GetPersonalDataManager, autofill::PersonalDataManager*());
   MOCK_METHOD0(GetWebsiteLoginFetcher, WebsiteLoginFetcher*());
   MOCK_METHOD0(GetWebContents, content::WebContents*());
+  MOCK_METHOD0(GetAccountEmailAddress, std::string());
   MOCK_METHOD1(SetDetails, void(std::unique_ptr<Details> details));
   MOCK_METHOD1(SetInfoBox, void(const InfoBox& info_box));
   MOCK_METHOD0(ClearInfoBox, void());
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index d8a61ed..346786c 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -152,6 +152,10 @@
   return web_contents();
 }
 
+std::string Controller::GetAccountEmailAddress() {
+  return client_->GetAccountEmailAddress();
+}
+
 void Controller::SetTouchableElementArea(const ElementAreaProto& area) {
   touchable_element_area()->SetFromProto(area);
 }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h
index d02640a..686e61b 100644
--- a/components/autofill_assistant/browser/controller.h
+++ b/components/autofill_assistant/browser/controller.h
@@ -98,6 +98,7 @@
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   WebsiteLoginFetcher* GetWebsiteLoginFetcher() override;
   content::WebContents* GetWebContents() override;
+  std::string GetAccountEmailAddress() override;
   void SetTouchableElementArea(const ElementAreaProto& area) override;
   void SetStatusMessage(const std::string& message) override;
   std::string GetStatusMessage() const override;
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
index fb52eae9..5ee7fb8 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -54,6 +54,10 @@
   return nullptr;
 }
 
+std::string FakeScriptExecutorDelegate::GetAccountEmailAddress() {
+  return std::string();
+}
+
 void FakeScriptExecutorDelegate::EnterState(AutofillAssistantState state) {
   state_ = state;
 }
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h
index 40fe5a9..607e7f2 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.h
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -35,6 +35,7 @@
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   WebsiteLoginFetcher* GetWebsiteLoginFetcher() override;
   content::WebContents* GetWebContents() override;
+  std::string GetAccountEmailAddress() override;
   void EnterState(AutofillAssistantState state) override;
   void SetTouchableElementArea(const ElementAreaProto& element) override;
   void SetStatusMessage(const std::string& message) override;
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 6217a09..acef62b3 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -499,6 +499,10 @@
   return delegate_->GetWebContents();
 }
 
+std::string ScriptExecutor::GetAccountEmailAddress() {
+  return delegate_->GetAccountEmailAddress();
+}
+
 void ScriptExecutor::SetDetails(std::unique_ptr<Details> details) {
   return delegate_->SetDetails(std::move(details));
 }
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index 5b42d320..aa79feb 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -190,6 +190,7 @@
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   WebsiteLoginFetcher* GetWebsiteLoginFetcher() override;
   content::WebContents* GetWebContents() override;
+  std::string GetAccountEmailAddress() override;
   void SetDetails(std::unique_ptr<Details> details) override;
   void ClearInfoBox() override;
   void SetInfoBox(const InfoBox& info_box) override;
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h
index f72fdd1..f74b05e 100644
--- a/components/autofill_assistant/browser/script_executor_delegate.h
+++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -54,6 +54,7 @@
   virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
   virtual WebsiteLoginFetcher* GetWebsiteLoginFetcher() = 0;
   virtual content::WebContents* GetWebContents() = 0;
+  virtual std::string GetAccountEmailAddress() = 0;
   virtual void EnterState(AutofillAssistantState state) = 0;
 
   // Make the area of the screen that correspond to the given elements
diff --git a/components/browsing_data/core/history_notice_utils_unittest.cc b/components/browsing_data/core/history_notice_utils_unittest.cc
index e6c89390..165cf26 100644
--- a/components/browsing_data/core/history_notice_utils_unittest.cc
+++ b/components/browsing_data/core/history_notice_utils_unittest.cc
@@ -60,7 +60,7 @@
   std::unique_ptr<syncer::TestSyncService> sync_service_;
   std::unique_ptr<history::FakeWebHistoryService> history_service_;
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(HistoryNoticeUtilsTest, NotSyncing) {
diff --git a/components/cronet/native/runnables_unittest.cc b/components/cronet/native/runnables_unittest.cc
index 08900b4..49df32d 100644
--- a/components/cronet/native/runnables_unittest.cc
+++ b/components/cronet/native/runnables_unittest.cc
@@ -43,7 +43,7 @@
   bool callback_called() const { return callback_called_; }
 
   // Provide a message loop for use by TestExecutor instances.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  private:
   bool callback_called_ = false;
diff --git a/components/cronet/native/test/buffer_test.cc b/components/cronet/native/test/buffer_test.cc
index e313122..c0577a3 100644
--- a/components/cronet/native/test/buffer_test.cc
+++ b/components/cronet/native/test/buffer_test.cc
@@ -27,8 +27,7 @@
 
   // Provide a task environment for use by TestExecutor instances. Do not
   // initialize the ThreadPool as this is done by the Cronet_Engine
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  private:
   void set_on_destroy_called(bool value) { on_destroy_called_ = value; }
diff --git a/components/cronet/native/test/executors_test.cc b/components/cronet/native/test/executors_test.cc
index ff24e6ad..042ac512 100644
--- a/components/cronet/native/test/executors_test.cc
+++ b/components/cronet/native/test/executors_test.cc
@@ -24,8 +24,7 @@
 
   // Provide a task environment for use by TestExecutor instances. Do not
   // initialize the ThreadPool as this is done by the Cronet_Engine
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  private:
   void set_runnable_called(bool value) { runnable_called_ = value; }
diff --git a/components/cronet/native/test/url_request_test.cc b/components/cronet/native/test/url_request_test.cc
index 8687a3a2..ebf8ded1 100644
--- a/components/cronet/native/test/url_request_test.cc
+++ b/components/cronet/native/test/url_request_test.cc
@@ -486,8 +486,7 @@
  protected:
   // Provide a task environment for use by TestExecutor instances. Do not
   // initialize the ThreadPool as this is done by the Cronet_Engine
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   // Not owned, |request_finished_listener_| destroys itself when run. This
   // pointer is only needed to unregister the listener from the Engine in
diff --git a/components/dbus/menu/BUILD.gn b/components/dbus/menu/BUILD.gn
index ad0135d1..7db84121b 100644
--- a/components/dbus/menu/BUILD.gn
+++ b/components/dbus/menu/BUILD.gn
@@ -10,12 +10,6 @@
     "menu.h",
     "menu_property_list.cc",
     "menu_property_list.h",
-    "properties_interface.cc",
-    "properties_interface.h",
-    "success_barrier_callback.cc",
-    "success_barrier_callback.h",
-    "types.cc",
-    "types.h",
   ]
   defines = [ "IS_DBUS_IMPL" ]
   deps = [
@@ -23,6 +17,7 @@
     "//base:i18n",
   ]
   public_deps = [
+    "//components/dbus/properties",
     "//dbus",
     "//skia",
     "//ui/base",
@@ -37,8 +32,6 @@
   testonly = true
   sources = [
     "menu_property_list_unittest.cc",
-    "success_barrier_callback_unittest.cc",
-    "types_unittest.cc",
   ]
   deps = [
     ":menu",
diff --git a/components/dbus/menu/menu.cc b/components/dbus/menu/menu.cc
index b02b807..227877c1 100644
--- a/components/dbus/menu/menu.cc
+++ b/components/dbus/menu/menu.cc
@@ -15,8 +15,8 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "components/dbus/menu/properties_interface.h"
-#include "components/dbus/menu/success_barrier_callback.h"
+#include "components/dbus/properties/dbus_properties.h"
+#include "components/dbus/properties/success_barrier_callback.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/models/simple_menu_model.h"
@@ -163,7 +163,7 @@
         base::BindRepeating(&DbusMenu::OnExported, weak_factory_.GetWeakPtr()));
   }
 
-  properties_ = std::make_unique<DbusPropertiesInterface>(menu_, barrier_);
+  properties_ = std::make_unique<DbusProperties>(menu_, barrier_);
   properties_->RegisterInterface(kInterfaceDbusMenu);
   auto set_property = [&](const std::string& property_name, auto&& value) {
     properties_->SetProperty(kInterfaceDbusMenu, property_name,
diff --git a/components/dbus/menu/menu.h b/components/dbus/menu/menu.h
index e6f702a..8d2ea00 100644
--- a/components/dbus/menu/menu.h
+++ b/components/dbus/menu/menu.h
@@ -16,7 +16,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "components/dbus/menu/menu_property_list.h"
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/types.h"
 #include "dbus/bus.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
@@ -25,7 +25,7 @@
 class MenuModel;
 }
 
-class DbusPropertiesInterface;
+class DbusProperties;
 
 // Implements the com.canonical.dbusmenu interface.
 class COMPONENT_EXPORT(DBUS) DbusMenu {
@@ -152,7 +152,7 @@
 
   base::RepeatingCallback<void(bool)> barrier_;
 
-  std::unique_ptr<DbusPropertiesInterface> properties_;
+  std::unique_ptr<DbusProperties> properties_;
 
   uint32_t revision_ = 0;
   int32_t last_item_id_ = 0;
diff --git a/components/dbus/menu/menu_property_list.h b/components/dbus/menu/menu_property_list.h
index 93fd377..c2cf0e79 100644
--- a/components/dbus/menu/menu_property_list.h
+++ b/components/dbus/menu/menu_property_list.h
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/types.h"
 
 using MenuPropertyList = std::vector<std::string>;
 using MenuItemProperties = std::map<std::string, DbusVariant>;
diff --git a/components/dbus/menu/menu_property_list_unittest.cc b/components/dbus/menu/menu_property_list_unittest.cc
index f700bf6..b02783af 100644
--- a/components/dbus/menu/menu_property_list_unittest.cc
+++ b/components/dbus/menu/menu_property_list_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/strings/utf_string_conversions.h"
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/types.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/models/menu_model.h"
diff --git a/components/dbus/menu/properties_interface.h b/components/dbus/menu/properties_interface.h
deleted file mode 100644
index 33da20ed..0000000
--- a/components/dbus/menu/properties_interface.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DBUS_MENU_PROPERTIES_INTERFACE_H_
-#define COMPONENTS_DBUS_MENU_PROPERTIES_INTERFACE_H_
-
-#include "base/callback_forward.h"
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
-#include "components/dbus/menu/types.h"
-#include "dbus/bus.h"
-#include "dbus/exported_object.h"
-
-// https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
-class COMPONENT_EXPORT(DBUS) DbusPropertiesInterface {
- public:
-  using InitializedCallback = base::OnceCallback<void(bool success)>;
-
-  // Registers method handlers for the properties interface.  The handlers will
-  // not be removed until the bus is shut down.
-  DbusPropertiesInterface(dbus::ExportedObject* exported_object,
-                          InitializedCallback callback);
-  ~DbusPropertiesInterface();
-
-  void RegisterInterface(const std::string& interface);
-
-  template <typename T>
-  void SetProperty(const std::string& interface,
-                   const std::string& name,
-                   T&& value,
-                   bool emit_signal = true,
-                   bool send_change = true) {
-    auto it = properties_.find(interface);
-    DCHECK(it != properties_.end());
-    (it->second)[name] = MakeDbusVariant(std::move(value));
-    if (emit_signal)
-      EmitPropertiesChangedSignal(interface, name, send_change);
-  }
-
- private:
-  void OnExported(const std::string& interface_name,
-                  const std::string& method_name,
-                  bool success);
-
-  void OnGetAllProperties(dbus::MethodCall* method_call,
-                          dbus::ExportedObject::ResponseSender response_sender);
-  void OnGetProperty(dbus::MethodCall* method_call,
-                     dbus::ExportedObject::ResponseSender response_sender);
-  void OnSetProperty(dbus::MethodCall* method_call,
-                     dbus::ExportedObject::ResponseSender response_sender);
-
-  void EmitPropertiesChangedSignal(const std::string& interface,
-                                   const std::string& property_name,
-                                   bool send_change);
-
-  dbus::ExportedObject* exported_object_ = nullptr;
-
-  base::RepeatingCallback<void(bool)> barrier_;
-
-  // A map from interface name to a map of properties.  The properties map is
-  // from property name to property value.
-  std::map<std::string, std::map<std::string, DbusVariant>> properties_;
-
-  base::WeakPtrFactory<DbusPropertiesInterface> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(DbusPropertiesInterface);
-};
-
-#endif  // COMPONENTS_DBUS_MENU_PROPERTIES_INTERFACE_H_
diff --git a/components/dbus/properties/BUILD.gn b/components/dbus/properties/BUILD.gn
new file mode 100644
index 0000000..62ff831d
--- /dev/null
+++ b/components/dbus/properties/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+component("properties") {
+  sources = [
+    "dbus_properties.cc",
+    "dbus_properties.h",
+    "success_barrier_callback.cc",
+    "success_barrier_callback.h",
+    "types.cc",
+    "types.h",
+  ]
+  defines = [ "IS_DBUS_IMPL" ]
+  deps = [
+    "//base",
+    "//base:i18n",
+  ]
+  public_deps = [
+    "//dbus",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "success_barrier_callback_unittest.cc",
+    "types_unittest.cc",
+  ]
+  deps = [
+    ":properties",
+    "//base",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/dbus/properties/DEPS b/components/dbus/properties/DEPS
new file mode 100644
index 0000000..d6abddad
--- /dev/null
+++ b/components/dbus/properties/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+dbus",
+]
diff --git a/components/dbus/properties/OWNERS b/components/dbus/properties/OWNERS
new file mode 100644
index 0000000..296dc0d
--- /dev/null
+++ b/components/dbus/properties/OWNERS
@@ -0,0 +1,2 @@
+thestig@chromium.org
+thomasanderson@chromium.org
diff --git a/components/dbus/menu/properties_interface.cc b/components/dbus/properties/dbus_properties.cc
similarity index 71%
rename from components/dbus/menu/properties_interface.cc
rename to components/dbus/properties/dbus_properties.cc
index 0578181..4fe1536 100644
--- a/components/dbus/menu/properties_interface.cc
+++ b/components/dbus/properties/dbus_properties.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/dbus/menu/properties_interface.h"
+#include "components/dbus/properties/dbus_properties.h"
 
 #include <dbus/dbus-shared.h>
 
 #include "base/bind.h"
 #include "base/stl_util.h"
-#include "components/dbus/menu/success_barrier_callback.h"
+#include "components/dbus/properties/success_barrier_callback.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
 
@@ -24,19 +24,17 @@
 
 }  // namespace
 
-DbusPropertiesInterface::DbusPropertiesInterface(
-    dbus::ExportedObject* exported_object,
-    InitializedCallback callback)
+DbusProperties::DbusProperties(dbus::ExportedObject* exported_object,
+                               InitializedCallback callback)
     : exported_object_(exported_object) {
   static constexpr struct {
     const char* name;
-    void (DbusPropertiesInterface::*callback)(
-        dbus::MethodCall*,
-        dbus::ExportedObject::ResponseSender);
+    void (DbusProperties::*callback)(dbus::MethodCall*,
+                                     dbus::ExportedObject::ResponseSender);
   } methods[3] = {
-      {kMethodPropertiesGetAll, &DbusPropertiesInterface::OnGetAllProperties},
-      {kMethodPropertiesGet, &DbusPropertiesInterface::OnGetProperty},
-      {kMethodPropertiesSet, &DbusPropertiesInterface::OnSetProperty},
+      {kMethodPropertiesGetAll, &DbusProperties::OnGetAllProperties},
+      {kMethodPropertiesGet, &DbusProperties::OnGetProperty},
+      {kMethodPropertiesSet, &DbusProperties::OnSetProperty},
   };
 
   barrier_ = SuccessBarrierCallback(base::size(methods), std::move(callback));
@@ -44,27 +42,76 @@
     exported_object_->ExportMethod(
         DBUS_INTERFACE_PROPERTIES, method.name,
         base::BindRepeating(method.callback, weak_factory_.GetWeakPtr()),
-        base::BindRepeating(&DbusPropertiesInterface::OnExported,
+        base::BindRepeating(&DbusProperties::OnExported,
                             weak_factory_.GetWeakPtr()));
   }
 }
 
-DbusPropertiesInterface::~DbusPropertiesInterface() = default;
+DbusProperties::~DbusProperties() = default;
 
-void DbusPropertiesInterface::RegisterInterface(const std::string& interface) {
+void DbusProperties::RegisterInterface(const std::string& interface) {
   bool inserted =
       properties_.emplace(interface, std::map<std::string, DbusVariant>{})
           .second;
   DCHECK(inserted);
 }
 
-void DbusPropertiesInterface::OnExported(const std::string& interface_name,
-                                         const std::string& method_name,
-                                         bool success) {
+DbusVariant* DbusProperties::GetProperty(const std::string& interface,
+                                         const std::string& property_name) {
+  auto interface_it = properties_.find(interface);
+  if (interface_it == properties_.end())
+    return nullptr;
+  auto name_it = interface_it->second.find(property_name);
+  return name_it != interface_it->second.end() ? &name_it->second : nullptr;
+}
+
+void DbusProperties::PropertyUpdated(const std::string& interface,
+                                     const std::string& property_name,
+                                     bool send_change) {
+  if (!initialized_)
+    return;
+
+  // |signal| follows the PropertiesChanged API:
+  // org.freedesktop.DBus.Properties.PropertiesChanged(
+  //     STRING interface_name,
+  //     DICT<STRING,VARIANT> changed_properties,
+  //     ARRAY<STRING> invalidated_properties);
+  dbus::Signal signal(DBUS_INTERFACE_PROPERTIES, kSignalPropertiesChanged);
+  dbus::MessageWriter writer(&signal);
+  writer.AppendString(interface);
+
+  if (send_change) {
+    // Changed properties.
+    dbus::MessageWriter array_writer(nullptr);
+    writer.OpenArray("{sv}", &array_writer);
+    dbus::MessageWriter dict_entry_writer(nullptr);
+    array_writer.OpenDictEntry(&dict_entry_writer);
+    dict_entry_writer.AppendString(property_name);
+    properties_[interface][property_name].Write(&dict_entry_writer);
+    array_writer.CloseContainer(&dict_entry_writer);
+    writer.CloseContainer(&array_writer);
+
+    // Invalidated properties.
+    writer.AppendArrayOfStrings({});
+  } else {
+    // Changed properties.
+    DbusDictionary().Write(&writer);
+
+    // Invalidated properties.
+    writer.AppendArrayOfStrings({property_name});
+  }
+
+  exported_object_->SendSignal(&signal);
+}
+
+void DbusProperties::OnExported(const std::string& interface_name,
+                                const std::string& method_name,
+                                bool success) {
+  initialized_ = success;
   barrier_.Run(success);
 }
 
-void DbusPropertiesInterface::OnGetAllProperties(
+void DbusProperties::OnGetAllProperties(
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
   // org.freedesktop.DBus.Properties.GetAll(in STRING interface_name,
@@ -93,7 +140,7 @@
     writer.CloseContainer(&array_writer);
   } else if (interface == DBUS_INTERFACE_PROPERTIES) {
     // There are no properties to give for this interface.
-    DbusArray<DbusDictEntry<DbusString, DbusVariant>>().Write(&writer);
+    DbusDictionary().Write(&writer);
   } else {
     // The given interface is not supported, so return a null response.
     response = nullptr;
@@ -102,7 +149,7 @@
   response_sender.Run(std::move(response));
 }
 
-void DbusPropertiesInterface::OnGetProperty(
+void DbusProperties::OnGetProperty(
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
   // org.freedesktop.DBus.Properties.Get(in STRING interface_name,
@@ -125,47 +172,10 @@
   response_sender.Run(std::move(response));
 }
 
-void DbusPropertiesInterface::OnSetProperty(
+void DbusProperties::OnSetProperty(
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
   // Not needed for now.
   NOTIMPLEMENTED();
   response_sender.Run(dbus::Response::FromMethodCall(method_call));
 }
-
-void DbusPropertiesInterface::EmitPropertiesChangedSignal(
-    const std::string& interface,
-    const std::string& property_name,
-    bool send_change) {
-  // |signal| follows the PropertiesChanged API:
-  // org.freedesktop.DBus.Properties.PropertiesChanged(
-  //     STRING interface_name,
-  //     DICT<STRING,VARIANT> changed_properties,
-  //     ARRAY<STRING> invalidated_properties);
-  dbus::Signal signal(DBUS_INTERFACE_PROPERTIES, kSignalPropertiesChanged);
-  dbus::MessageWriter writer(&signal);
-  writer.AppendString(interface);
-
-  if (send_change) {
-    // Changed properties.
-    dbus::MessageWriter array_writer(nullptr);
-    writer.OpenArray("{sv}", &array_writer);
-    dbus::MessageWriter dict_entry_writer(nullptr);
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(property_name);
-    properties_[interface][property_name].Write(&dict_entry_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-    writer.CloseContainer(&array_writer);
-
-    // Invalidated properties.
-    writer.AppendArrayOfStrings({});
-  } else {
-    // Changed properties.
-    DbusArray<DbusDictEntry<DbusString, DbusVariant>>().Write(&writer);
-
-    // Invalidated properties.
-    writer.AppendArrayOfStrings({property_name});
-  }
-
-  exported_object_->SendSignal(&signal);
-}
diff --git a/components/dbus/properties/dbus_properties.h b/components/dbus/properties/dbus_properties.h
new file mode 100644
index 0000000..0a12aef8
--- /dev/null
+++ b/components/dbus/properties/dbus_properties.h
@@ -0,0 +1,85 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DBUS_PROPERTIES_DBUS_PROPERTIES_H_
+#define COMPONENTS_DBUS_PROPERTIES_DBUS_PROPERTIES_H_
+
+#include "base/callback_forward.h"
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/stl_util.h"
+#include "components/dbus/properties/types.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+
+// https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
+class COMPONENT_EXPORT(DBUS) DbusProperties {
+ public:
+  using InitializedCallback = base::OnceCallback<void(bool success)>;
+
+  // Registers method handlers for the properties interface.  The handlers will
+  // not be removed until the bus is shut down.
+  DbusProperties(dbus::ExportedObject* exported_object,
+                 InitializedCallback callback);
+  ~DbusProperties();
+
+  void RegisterInterface(const std::string& interface);
+
+  template <typename T>
+  void SetProperty(const std::string& interface,
+                   const std::string& name,
+                   T&& value,
+                   bool emit_signal = true,
+                   bool send_change = true) {
+    auto interface_it = properties_.find(interface);
+    DCHECK(interface_it != properties_.end());
+    auto property_it = interface_it->second.find(name);
+    DbusVariant new_value = MakeDbusVariant(std::move(value));
+    const bool send_signal =
+        emit_signal && (property_it == interface_it->second.end() ||
+                        property_it->second != new_value);
+    (interface_it->second)[name] = std::move(new_value);
+    if (send_signal)
+      PropertyUpdated(interface, name, send_change);
+  }
+
+  DbusVariant* GetProperty(const std::string& interface,
+                           const std::string& property_name);
+
+  // If emitting a PropertiesChangedSignal is desired, this should be called
+  // after an existing property is modified through any means other than
+  // SetProperty().
+  void PropertyUpdated(const std::string& interface,
+                       const std::string& property_name,
+                       bool send_change = true);
+
+ private:
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  void OnGetAllProperties(dbus::MethodCall* method_call,
+                          dbus::ExportedObject::ResponseSender response_sender);
+  void OnGetProperty(dbus::MethodCall* method_call,
+                     dbus::ExportedObject::ResponseSender response_sender);
+  void OnSetProperty(dbus::MethodCall* method_call,
+                     dbus::ExportedObject::ResponseSender response_sender);
+
+  bool initialized_ = false;
+
+  dbus::ExportedObject* exported_object_ = nullptr;
+
+  base::RepeatingCallback<void(bool)> barrier_;
+
+  // A map from interface name to a map of properties.  The properties map is
+  // from property name to property value.
+  std::map<std::string, std::map<std::string, DbusVariant>> properties_;
+
+  base::WeakPtrFactory<DbusProperties> weak_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(DbusProperties);
+};
+
+#endif  // COMPONENTS_DBUS_PROPERTIES_DBUS_PROPERTIES_H_
diff --git a/components/dbus/menu/success_barrier_callback.cc b/components/dbus/properties/success_barrier_callback.cc
similarity index 94%
rename from components/dbus/menu/success_barrier_callback.cc
rename to components/dbus/properties/success_barrier_callback.cc
index 2f6e35a..95b1a91 100644
--- a/components/dbus/menu/success_barrier_callback.cc
+++ b/components/dbus/properties/success_barrier_callback.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/dbus/menu/success_barrier_callback.h"
+#include "components/dbus/properties/success_barrier_callback.h"
 
 #include "base/bind.h"
 #include "base/callback.h"
diff --git a/components/dbus/menu/success_barrier_callback.h b/components/dbus/properties/success_barrier_callback.h
similarity index 79%
rename from components/dbus/menu/success_barrier_callback.h
rename to components/dbus/properties/success_barrier_callback.h
index b65944a..ec85fcb 100644
--- a/components/dbus/menu/success_barrier_callback.h
+++ b/components/dbus/properties/success_barrier_callback.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_DBUS_MENU_SUCCESS_BARRIER_CALLBACK_H_
-#define COMPONENTS_DBUS_MENU_SUCCESS_BARRIER_CALLBACK_H_
+#ifndef COMPONENTS_DBUS_PROPERTIES_SUCCESS_BARRIER_CALLBACK_H_
+#define COMPONENTS_DBUS_PROPERTIES_SUCCESS_BARRIER_CALLBACK_H_
 
 #include <cstddef>
 
@@ -20,4 +20,4 @@
     size_t num_calls,
     base::OnceCallback<void(bool)> done_callback);
 
-#endif  // COMPONENTS_DBUS_MENU_SUCCESS_BARRIER_CALLBACK_H_
+#endif  // COMPONENTS_DBUS_PROPERTIES_SUCCESS_BARRIER_CALLBACK_H_
diff --git a/components/dbus/menu/success_barrier_callback_unittest.cc b/components/dbus/properties/success_barrier_callback_unittest.cc
similarity index 95%
rename from components/dbus/menu/success_barrier_callback_unittest.cc
rename to components/dbus/properties/success_barrier_callback_unittest.cc
index 6a8f2d1..e13c0cb 100644
--- a/components/dbus/menu/success_barrier_callback_unittest.cc
+++ b/components/dbus/properties/success_barrier_callback_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/dbus/menu/success_barrier_callback.h"
+#include "components/dbus/properties/success_barrier_callback.h"
 
 #include "base/bind.h"
 #include "base/callback.h"
diff --git a/components/dbus/menu/types.cc b/components/dbus/properties/types.cc
similarity index 69%
rename from components/dbus/menu/types.cc
rename to components/dbus/properties/types.cc
index 4af3e77c..8625d70 100644
--- a/components/dbus/menu/types.cc
+++ b/components/dbus/properties/types.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/types.h"
 
 #include "dbus/message.h"
 #include "dbus/object_path.h"
@@ -57,6 +57,32 @@
   return "u";
 }
 
+DbusInt64::DbusInt64(int64_t value) : value_(value) {}
+DbusInt64::DbusInt64(DbusInt64&& other) = default;
+DbusInt64::~DbusInt64() = default;
+
+void DbusInt64::Write(dbus::MessageWriter* writer) const {
+  writer->AppendInt64(value_);
+}
+
+// static
+std::string DbusInt64::GetSignature() {
+  return "x";
+}
+
+DbusDouble::DbusDouble(double value) : value_(value) {}
+DbusDouble::DbusDouble(DbusDouble&& other) = default;
+DbusDouble::~DbusDouble() = default;
+
+void DbusDouble::Write(dbus::MessageWriter* writer) const {
+  writer->AppendDouble(value_);
+}
+
+// static
+std::string DbusDouble::GetSignature() {
+  return "d";
+}
+
 DbusString::DbusString(const std::string& value) : value_(value) {}
 DbusString::DbusString(DbusString&& other) = default;
 DbusString::~DbusString() = default;
@@ -131,3 +157,32 @@
 std::string DbusByteArray::GetSignature() {
   return "ay";  // lmao
 }
+
+DbusDictionary::DbusDictionary() = default;
+DbusDictionary::DbusDictionary(DbusDictionary&& other) = default;
+DbusDictionary::~DbusDictionary() = default;
+
+bool DbusDictionary::Put(const std::string& key, DbusVariant&& value) {
+  auto it = value_.find(key);
+  const bool updated = it == value_.end() || it->second != value;
+  value_[key] = std::move(value);
+  return updated;
+}
+
+void DbusDictionary::Write(dbus::MessageWriter* writer) const {
+  dbus::MessageWriter array_writer(nullptr);
+  writer->OpenArray("{sv}", &array_writer);
+  for (const auto& pair : value_) {
+    dbus::MessageWriter dict_entry_writer(nullptr);
+    array_writer.OpenDictEntry(&dict_entry_writer);
+    dict_entry_writer.AppendString(pair.first);
+    pair.second.Write(&dict_entry_writer);
+    array_writer.CloseContainer(&dict_entry_writer);
+  }
+  writer->CloseContainer(&array_writer);
+}
+
+// static
+std::string DbusDictionary::GetSignature() {
+  return "a{sv}";
+}
diff --git a/components/dbus/menu/types.h b/components/dbus/properties/types.h
similarity index 82%
rename from components/dbus/menu/types.h
rename to components/dbus/properties/types.h
index feb3177..454f0ab 100644
--- a/components/dbus/menu/types.h
+++ b/components/dbus/properties/types.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_DBUS_MENU_TYPES_H_
-#define COMPONENTS_DBUS_MENU_TYPES_H_
+#ifndef COMPONENTS_DBUS_PROPERTIES_TYPES_H_
+#define COMPONENTS_DBUS_PROPERTIES_TYPES_H_
 
 #include <stdint.h>
 
@@ -150,6 +150,40 @@
   uint32_t value_;
 };
 
+class COMPONENT_EXPORT(DBUS) DbusInt64 : public DbusTypeImpl<DbusInt64> {
+ public:
+  explicit DbusInt64(int64_t value);
+  DbusInt64(DbusInt64&& other);
+  ~DbusInt64() override;
+
+  // DbusType:
+  void Write(dbus::MessageWriter* writer) const override;
+
+  static std::string GetSignature();
+
+ private:
+  friend class DbusTypeImpl<DbusInt64>;
+
+  int64_t value_;
+};
+
+class COMPONENT_EXPORT(DBUS) DbusDouble : public DbusTypeImpl<DbusDouble> {
+ public:
+  explicit DbusDouble(double value);
+  DbusDouble(DbusDouble&& other);
+  ~DbusDouble() override;
+
+  // DbusType:
+  void Write(dbus::MessageWriter* writer) const override;
+
+  static std::string GetSignature();
+
+ private:
+  friend class DbusTypeImpl<DbusDouble>;
+
+  double value_;
+};
+
 class COMPONENT_EXPORT(DBUS) DbusString : public DbusTypeImpl<DbusString> {
  public:
   explicit DbusString(const std::string& value);
@@ -192,6 +226,13 @@
   DbusVariant(DbusVariant&& other);
   ~DbusVariant() override;
 
+  template <typename T>
+  T* GetAs() {
+    return value_ && value_->GetSignatureDynamic() == T::GetSignature()
+               ? reinterpret_cast<T*>(value_.get())
+               : nullptr;
+  }
+
   DbusVariant& operator=(DbusVariant&& other);
 
   explicit operator bool() const;
@@ -337,4 +378,31 @@
   return DbusDictEntry<K, V>(std::move(k), std::move(v));
 }
 
-#endif  // COMPONENTS_DBUS_MENU_TYPES_H_
+// A convenience class for DbusArray<DbusDictEntry<DbusString, DbusVariant>>,
+// which is a common idiom for DBus APIs.  Except this class has some subtle
+// differences:
+//   1. Duplicate keys are not allowed.
+//   2. You cannot control the ordering of keys.  They will always be in sorted
+//      order.
+class COMPONENT_EXPORT(DBUS) DbusDictionary
+    : public DbusTypeImpl<DbusDictionary> {
+ public:
+  DbusDictionary();
+  DbusDictionary(DbusDictionary&& other);
+  ~DbusDictionary() override;
+
+  // Returns true iff the value corresponding to |key| was updated.
+  bool Put(const std::string& key, DbusVariant&& value);
+
+  // DbusType:
+  void Write(dbus::MessageWriter* writer) const override;
+
+  static std::string GetSignature();
+
+ private:
+  friend class DbusTypeImpl<DbusDictionary>;
+
+  std::map<std::string, DbusVariant> value_;
+};
+
+#endif  // COMPONENTS_DBUS_PROPERTIES_TYPES_H_
diff --git a/components/dbus/menu/types_unittest.cc b/components/dbus/properties/types_unittest.cc
similarity index 97%
rename from components/dbus/menu/types_unittest.cc
rename to components/dbus/properties/types_unittest.cc
index e6ca145..cebf1fe 100644
--- a/components/dbus/menu/types_unittest.cc
+++ b/components/dbus/properties/types_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/dbus/menu/types.h"
+#include "components/dbus/properties/types.h"
 
 #include "base/memory/ref_counted_memory.h"
 #include "dbus/object_path.h"
diff --git a/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc b/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
index ad9e987..a3e5b12d 100644
--- a/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
+++ b/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
@@ -66,7 +66,7 @@
   }
 
   // DiscardableSharedMemoryManager requires a message loop.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<TestDiscardableSharedMemoryManager> manager_;
 };
 
@@ -240,7 +240,7 @@
   void SetUp() override { manager_.reset(new DiscardableSharedMemoryManager); }
 
   // DiscardableSharedMemoryManager requires a message loop.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<DiscardableSharedMemoryManager> manager_;
 };
 
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 08becde..64dfc22 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -368,9 +368,9 @@
   TRACE_EVENT1("exo", "Surface::RemoveSubSurface", "sub_surface",
                sub_surface->AsTracedValue());
 
-  window_->RemoveChild(sub_surface->window());
   if (sub_surface->window()->IsVisible())
     sub_surface->window()->Hide();
+  window_->RemoveChild(sub_surface->window());
 
   DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
   pending_sub_surfaces_.erase(
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc
index 871ddef..331b89a5 100644
--- a/components/exo/surface_unittest.cc
+++ b/components/exo/surface_unittest.cc
@@ -42,6 +42,24 @@
   return rects;
 }
 
+class SurfaceObserverForTest : public SurfaceObserver {
+ public:
+  SurfaceObserverForTest() = default;
+
+  void OnSurfaceDestroying(Surface* surface) override {}
+
+  void OnWindowOcclusionChanged(Surface* surface) override {
+    num_occlusion_changes_++;
+  }
+
+  int num_occlusion_changes() const { return num_occlusion_changes_; }
+
+ private:
+  int num_occlusion_changes_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(SurfaceObserverForTest);
+};
+
 class SurfaceTest : public test::ExoTestBase,
                     public ::testing::WithParamInterface<float> {
  public:
@@ -945,5 +963,36 @@
   EXPECT_FALSE(surface->HasPendingAcquireFence());
 }
 
+TEST_P(SurfaceTest, UpdatesOcclusionOnDestroyingSubsurface) {
+  gfx::Size buffer_size(256, 512);
+  auto buffer = std::make_unique<Buffer>(
+      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
+  auto surface = std::make_unique<Surface>();
+  auto shell_surface = std::make_unique<ShellSurface>(surface.get());
+  surface->Attach(buffer.get());
+  surface->Commit();
+
+  gfx::Size child_buffer_size(64, 128);
+  auto child_buffer = std::make_unique<Buffer>(
+      exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size));
+  auto child_surface = std::make_unique<Surface>();
+  auto sub_surface =
+      std::make_unique<SubSurface>(child_surface.get(), surface.get());
+  child_surface->Attach(child_buffer.get());
+  child_surface->Commit();
+  surface->Commit();
+
+  // Turn on occlusion tracking.
+  child_surface->SetOcclusionTracking(true);
+  SurfaceObserverForTest observer;
+  ScopedSurface scoped_child_surface(child_surface.get(), &observer);
+
+  // Destroy the subsurface and expect to get an occlusion update.
+  sub_surface.reset();
+  EXPECT_EQ(1, observer.num_occlusion_changes());
+  EXPECT_EQ(aura::Window::OcclusionState::HIDDEN,
+            child_surface->window()->occlusion_state());
+}
+
 }  // namespace
 }  // namespace exo
diff --git a/components/image_fetcher/core/image_data_fetcher_unittest.cc b/components/image_fetcher/core/image_data_fetcher_unittest.cc
index c658f782..5a6e56b 100644
--- a/components/image_fetcher/core/image_data_fetcher_unittest.cc
+++ b/components/image_fetcher/core/image_data_fetcher_unittest.cc
@@ -53,7 +53,7 @@
                void(const std::string&, const RequestMetadata&));
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
diff --git a/components/password_manager/core/browser/credential_manager_impl.cc b/components/password_manager/core/browser/credential_manager_impl.cc
index 9f6c9c3..6dc84d1 100644
--- a/components/password_manager/core/browser/credential_manager_impl.cc
+++ b/components/password_manager/core/browser/credential_manager_impl.cc
@@ -214,7 +214,7 @@
 }
 
 PasswordStore* CredentialManagerImpl::GetPasswordStore() {
-  return client_ ? client_->GetPasswordStore() : nullptr;
+  return client_ ? client_->GetProfilePasswordStore() : nullptr;
 }
 
 void CredentialManagerImpl::DoneRequiringUserMediation() {
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 77dfbaa9..5aa4e0d 100644
--- a/components/password_manager/core/browser/credential_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/credential_manager_impl_unittest.cc
@@ -107,7 +107,7 @@
     NotifyUserCouldBeAutoSignedInPtr(form.get());
   }
 
-  PasswordStore* GetPasswordStore() const override { return store_; }
+  PasswordStore* GetProfilePasswordStore() const override { return store_; }
 
   PrefService* GetPrefs() const override { return prefs_.get(); }
 
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager.cc b/components/password_manager/core/browser/credential_manager_password_form_manager.cc
index aa580710..5790f7c0 100644
--- a/components/password_manager/core/browser/credential_manager_password_form_manager.cc
+++ b/components/password_manager/core/browser/credential_manager_password_form_manager.cc
@@ -26,12 +26,13 @@
     CredentialManagerPasswordFormManagerDelegate* delegate,
     std::unique_ptr<FormSaver> form_saver,
     std::unique_ptr<FormFetcher> form_fetcher)
-    : PasswordFormManager(client,
-                          std::move(saved_form),
-                          std::move(form_fetcher),
-                          (form_saver ? std::move(form_saver)
-                                      : std::make_unique<FormSaverImpl>(
-                                            client->GetPasswordStore()))),
+    : PasswordFormManager(
+          client,
+          std::move(saved_form),
+          std::move(form_fetcher),
+          (form_saver ? std::move(form_saver)
+                      : std::make_unique<FormSaverImpl>(
+                            client->GetProfilePasswordStore()))),
       delegate_(delegate) {}
 
 CredentialManagerPasswordFormManager::~CredentialManagerPasswordFormManager() =
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc
index 0d17eae..fbf8b126 100644
--- a/components/password_manager/core/browser/form_fetcher_impl.cc
+++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -204,7 +204,7 @@
     return;
   }
 
-  PasswordStore* password_store = client_->GetPasswordStore();
+  PasswordStore* password_store = client_->GetProfilePasswordStore();
   if (!password_store) {
     if (logger)
       logger->LogMessage(Logger::STRING_NO_STORE);
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
index 106cb13..8cba0a6a 100644
--- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
+++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -94,7 +94,7 @@
                    : StubPasswordManagerClient::GetStoreResultFilter();
   }
 
-  PasswordStore* GetPasswordStore() const override { return store_; }
+  PasswordStore* GetProfilePasswordStore() const override { return store_; }
 
   std::unique_ptr<CredentialsFilter> filter_;
   PasswordStore* store_ = nullptr;
diff --git a/components/password_manager/core/browser/http_auth_manager_impl.cc b/components/password_manager/core/browser/http_auth_manager_impl.cc
index 7f57ce5..09cba8b 100644
--- a/components/password_manager/core/browser/http_auth_manager_impl.cc
+++ b/components/password_manager/core/browser/http_auth_manager_impl.cc
@@ -62,7 +62,7 @@
   form_manager_ = std::make_unique<PasswordFormManager>(
       client_, PasswordStore::FormDigest(observed_form),
       nullptr, /* form_fetcher */
-      std::make_unique<FormSaverImpl>(client_->GetPasswordStore()));
+      std::make_unique<FormSaverImpl>(client_->GetProfilePasswordStore()));
 }
 
 void HttpAuthManagerImpl::ProvisionallySaveForm(
diff --git a/components/password_manager/core/browser/http_auth_manager_unittest.cc b/components/password_manager/core/browser/http_auth_manager_unittest.cc
index a2d57dd..a82f596 100644
--- a/components/password_manager/core/browser/http_auth_manager_unittest.cc
+++ b/components/password_manager/core/browser/http_auth_manager_unittest.cc
@@ -56,7 +56,7 @@
   MOCK_METHOD2(AutofillHttpAuth,
                void(const autofill::PasswordForm&,
                     const PasswordFormManagerForUI*));
-  MOCK_CONST_METHOD0(GetPasswordStore, PasswordStore*());
+  MOCK_CONST_METHOD0(GetProfilePasswordStore, PasswordStore*());
   MOCK_METHOD0(PromptUserToSaveOrUpdatePasswordPtr, void());
 
   // Workaround for std::unique_ptr<> lacking a copy constructor.
@@ -103,7 +103,8 @@
     ASSERT_TRUE(
         store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
 
-    ON_CALL(client_, GetPasswordStore()).WillByDefault(Return(store_.get()));
+    ON_CALL(client_, GetProfilePasswordStore())
+        .WillByDefault(Return(store_.get()));
     EXPECT_CALL(*store_, GetSiteStatsImpl(_)).Times(AnyNumber());
 
     httpauth_manager_.reset(new HttpAuthManagerImpl(&client_));
diff --git a/components/password_manager/core/browser/http_password_store_migrator.cc b/components/password_manager/core/browser/http_password_store_migrator.cc
index a357313..3e168bb 100644
--- a/components/password_manager/core/browser/http_password_store_migrator.cc
+++ b/components/password_manager/core/browser/http_password_store_migrator.cc
@@ -50,7 +50,7 @@
   PasswordStore::FormDigest form(autofill::PasswordForm::Scheme::kHtml,
                                  http_origin.GetOrigin().spec(), http_origin);
   http_origin_domain_ = http_origin.GetOrigin();
-  client_->GetPasswordStore()->GetLogins(form, this);
+  client_->GetProfilePasswordStore()->GetLogins(form, this);
   client_->PostHSTSQueryForHost(
       https_origin, base::Bind(&OnHSTSQueryResultHelper, GetWeakPtr()));
 }
@@ -102,7 +102,7 @@
   got_hsts_query_result_ = true;
 
   if (is_hsts == HSTSResult::kYes)
-    client_->GetPasswordStore()->RemoveSiteStats(http_origin_domain_);
+    client_->GetProfilePasswordStore()->RemoveSiteStats(http_origin_domain_);
 
   if (got_password_store_results_)
     ProcessPasswordStoreResults();
@@ -120,10 +120,10 @@
   for (const auto& form : results_) {
     autofill::PasswordForm new_form =
         HttpPasswordStoreMigrator::MigrateHttpFormToHttps(*form);
-    client_->GetPasswordStore()->AddLogin(new_form);
+    client_->GetProfilePasswordStore()->AddLogin(new_form);
 
     if (mode_ == MigrationMode::MOVE)
-      client_->GetPasswordStore()->RemoveLogin(*form);
+      client_->GetProfilePasswordStore()->RemoveLogin(*form);
     *form = std::move(new_form);
   }
 
diff --git a/components/password_manager/core/browser/http_password_store_migrator_unittest.cc b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc
index b153632..a40ccaab 100644
--- a/components/password_manager/core/browser/http_password_store_migrator_unittest.cc
+++ b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc
@@ -96,7 +96,7 @@
   explicit MockPasswordManagerClient(PasswordStore* store) : store_(store) {}
 
   // PasswordManagerClient:
-  PasswordStore* GetPasswordStore() const override { return store_; }
+  PasswordStore* GetProfilePasswordStore() const override { return store_; }
   void PostHSTSQueryForHost(const GURL& gurl,
                             HSTSCallback callback) const override {
     saved_callback_ = std::move(callback);
diff --git a/components/password_manager/core/browser/leak_detection_delegate.cc b/components/password_manager/core/browser/leak_detection_delegate.cc
index d910d21..7cb4a0cf 100644
--- a/components/password_manager/core/browser/leak_detection_delegate.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate.cc
@@ -73,7 +73,7 @@
       helper_ = std::make_unique<LeakDetectionDelegateHelper>(base::BindOnce(
           &LeakDetectionDelegate::OnShowLeakDetectionNotification,
           base::Unretained(this)));
-      helper_->GetCredentialLeakType(client_->GetPasswordStore(),
+      helper_->GetCredentialLeakType(client_->GetProfilePasswordStore(),
                                      std::move(url), std::move(username),
                                      std::move(password));
     }
diff --git a/components/password_manager/core/browser/password_feature_manager_impl.cc b/components/password_manager/core/browser/password_feature_manager_impl.cc
index 9f78462..3e59f4ae 100644
--- a/components/password_manager/core/browser/password_feature_manager_impl.cc
+++ b/components/password_manager/core/browser/password_feature_manager_impl.cc
@@ -19,6 +19,7 @@
       return false;
     case SYNCING_WITH_CUSTOM_PASSPHRASE:
     case SYNCING_NORMAL_ENCRYPTION:
+    case ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION:
       return true;
   }
 }
@@ -32,6 +33,7 @@
     case SYNCING_WITH_CUSTOM_PASSPHRASE:
       return false;
     case SYNCING_NORMAL_ENCRYPTION:
+    case ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION:
       return true;
   }
 }
diff --git a/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc b/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc
index be60910..f2eaf091 100644
--- a/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc
+++ b/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc
@@ -134,7 +134,9 @@
 
   ~MockPasswordManagerClient() override { store_->ShutdownOnUIThread(); }
 
-  PasswordStore* GetPasswordStore() const override { return store_.get(); }
+  PasswordStore* GetProfilePasswordStore() const override {
+    return store_.get();
+  }
   PrefService* GetPrefs() const override { return prefs_.get(); }
   PasswordRequirementsService* GetPasswordRequirementsService() override {
     return &password_requirements_service_;
diff --git a/components/password_manager/core/browser/password_list_sorter.cc b/components/password_manager/core/browser/password_list_sorter.cc
index 223cb0e..ce39e0f 100644
--- a/components/password_manager/core/browser/password_list_sorter.cc
+++ b/components/password_manager/core/browser/password_list_sorter.cc
@@ -72,7 +72,13 @@
   }
 
   // To separate HTTP/HTTPS credentials, add the scheme to the key.
-  return key += kSortKeyPartsSeparator + link_url.scheme();
+  key += kSortKeyPartsSeparator + link_url.scheme();
+
+  if (form.from_store == autofill::PasswordForm::Store::kAccountStore) {
+    key += kSortKeyPartsSeparator + std::string("account");
+  }
+
+  return key;
 }
 
 void SortEntriesAndHideDuplicates(
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index e4a3bb09..e392082 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -437,7 +437,7 @@
         ->set_user_typed_password_on_chrome_sign_in_page();
   }
 
-  if (!client_->GetPasswordStore()->IsAbleToSavePasswords() ||
+  if (!client_->GetProfilePasswordStore()->IsAbleToSavePasswords() ||
       !client_->IsSavingAndFillingEnabled(password_form.origin) ||
       ShouldBlockPasswordForSameOriginButDifferentScheme(
           password_form.origin) ||
@@ -562,7 +562,8 @@
       client_,
       driver ? driver->AsWeakPtr() : base::WeakPtr<PasswordManagerDriver>(),
       form, nullptr,
-      std::make_unique<FormSaverImpl>(client_->GetPasswordStore()), nullptr));
+      std::make_unique<FormSaverImpl>(client_->GetProfilePasswordStore()),
+      nullptr));
   form_managers_.back()->ProcessServerPredictions(predictions_);
   return form_managers_.back().get();
 }
@@ -845,7 +846,7 @@
     logger->LogSuccessfulSubmissionIndicatorEvent(submission_event);
 
   bool able_to_save_passwords =
-      client_->GetPasswordStore()->IsAbleToSavePasswords();
+      client_->GetProfilePasswordStore()->IsAbleToSavePasswords();
   UMA_HISTOGRAM_BOOLEAN("PasswordManager.AbleToSavePasswordsOnSuccessfulLogin",
                         able_to_save_passwords);
   if (!able_to_save_passwords)
@@ -918,7 +919,7 @@
   if (username.empty())
     return;
 
-  password_manager::PasswordStore* store = client_->GetPasswordStore();
+  password_manager::PasswordStore* store = client_->GetProfilePasswordStore();
   // May be null in tests.
   if (!store)
     return;
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 6415df0..1a7e5a6b 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -67,7 +67,8 @@
 enum SyncState {
   NOT_SYNCING,
   SYNCING_NORMAL_ENCRYPTION,
-  SYNCING_WITH_CUSTOM_PASSPHRASE
+  SYNCING_WITH_CUSTOM_PASSPHRASE,
+  ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION
 };
 
 // An abstraction of operations that depend on the embedders (e.g. Chrome)
@@ -223,8 +224,8 @@
   // Gets prefs associated with this embedder.
   virtual PrefService* GetPrefs() const = 0;
 
-  // Returns the PasswordStore associated with this instance.
-  virtual PasswordStore* GetPasswordStore() const = 0;
+  // Returns the profile PasswordStore associated with this instance.
+  virtual PasswordStore* GetProfilePasswordStore() const = 0;
 
   // Reports whether and how passwords are synced in the embedder. The default
   // implementation always returns NOT_SYNCING.
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 7d10dc2..d17e9d0 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -136,7 +136,7 @@
   MOCK_METHOD2(AutofillHttpAuth,
                void(const autofill::PasswordForm&,
                     const PasswordFormManagerForUI*));
-  MOCK_CONST_METHOD0(GetPasswordStore, PasswordStore*());
+  MOCK_CONST_METHOD0(GetProfilePasswordStore, PasswordStore*());
   // The code inside EXPECT_CALL for PromptUserToSaveOrUpdatePasswordPtr and
   // ShowManualFallbackForSavingPtr owns the PasswordFormManager* argument.
   MOCK_METHOD1(PromptUserToSaveOrUpdatePasswordPtr,
@@ -289,7 +289,8 @@
     EXPECT_CALL(*store_, ReportMetrics(_, _, _)).Times(AnyNumber());
     CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
 
-    ON_CALL(client_, GetPasswordStore()).WillByDefault(Return(store_.get()));
+    ON_CALL(client_, GetProfilePasswordStore())
+        .WillByDefault(Return(store_.get()));
     EXPECT_CALL(*store_, GetSiteStatsImpl(_)).Times(AnyNumber());
     ON_CALL(client_, GetDriver()).WillByDefault(Return(&driver_));
 
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc
index 0be0134a..20fd6d3 100644
--- a/components/password_manager/core/browser/password_manager_util.cc
+++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -62,14 +62,23 @@
 
 password_manager::SyncState GetPasswordSyncState(
     const syncer::SyncService* sync_service) {
-  if (sync_service && sync_service->GetUserSettings()->IsFirstSetupComplete() &&
-      sync_service->IsSyncFeatureActive() &&
-      sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS)) {
+  if (!sync_service ||
+      !sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS)) {
+    return password_manager::NOT_SYNCING;
+  }
+
+  if (sync_service->IsSyncFeatureActive()) {
     return sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()
                ? password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE
                : password_manager::SYNCING_NORMAL_ENCRYPTION;
   }
-  return password_manager::NOT_SYNCING;
+
+  DCHECK(base::FeatureList::IsEnabled(
+      password_manager::features::kEnablePasswordsAccountStorage));
+  // Account passwords are enabled only for users with normal encryption at
+  // the moment. Data types won't become active for non-sync users with custom
+  // passphrase.
+  return password_manager::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION;
 }
 
 bool IsSyncingWithNormalEncryption(const syncer::SyncService* sync_service) {
diff --git a/components/password_manager/core/browser/password_reuse_detection_manager.cc b/components/password_manager/core/browser/password_reuse_detection_manager.cc
index bac59551..9b00f2f4 100644
--- a/components/password_manager/core/browser/password_reuse_detection_manager.cc
+++ b/components/password_manager/core/browser/password_reuse_detection_manager.cc
@@ -64,7 +64,7 @@
     input_characters_.erase(
         0, input_characters_.size() - kMaxNumberOfCharactersToStore);
   }
-  PasswordStore* store = client_->GetPasswordStore();
+  PasswordStore* store = client_->GetProfilePasswordStore();
   if (!store)
     return;
   store->CheckReuse(input_characters_, main_frame_url_.GetOrigin().spec(),
@@ -78,7 +78,7 @@
   base::string16 input = std::move(text);
   if (input.size() > kMaxNumberOfCharactersToStore)
     input = text.substr(input.size() - kMaxNumberOfCharactersToStore);
-  PasswordStore* store = client_->GetPasswordStore();
+  PasswordStore* store = client_->GetProfilePasswordStore();
   if (!store)
     return;
   store->CheckReuse(input, main_frame_url_.GetOrigin().spec(), this);
diff --git a/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc b/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
index 7ab66b78..4ebe2ae 100644
--- a/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
@@ -31,7 +31,7 @@
   MockPasswordManagerClient() = default;
   ~MockPasswordManagerClient() override = default;
 
-  MOCK_CONST_METHOD0(GetPasswordStore, PasswordStore*());
+  MOCK_CONST_METHOD0(GetProfilePasswordStore, PasswordStore*());
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
@@ -69,7 +69,7 @@
           "1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"),
       base::ASCIIToUTF16("?<>:'{}ABCDEF")};
 
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
@@ -93,7 +93,7 @@
 // inactivity.
 TEST_F(PasswordReuseDetectionManagerTest,
        CheckThatBufferClearedAfterInactivity) {
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
@@ -114,7 +114,7 @@
 
 // Verify that the keystroke buffer is cleared after user presses enter.
 TEST_F(PasswordReuseDetectionManagerTest, CheckThatBufferClearedAfterEnter) {
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
@@ -133,7 +133,7 @@
 // Verify that after reuse found, no reuse checking happens till next main frame
 // navigation.
 TEST_F(PasswordReuseDetectionManagerTest, NoReuseCheckingAfterReuseFound) {
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
@@ -152,7 +152,7 @@
 
 // Verify that keystroke buffer is cleared only on cross host navigation.
 TEST_F(PasswordReuseDetectionManagerTest, DidNavigateMainFrame) {
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
@@ -180,7 +180,7 @@
           "1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"),
       base::ASCIIToUTF16("?<>:'{}ABCDEF")};
 
-  EXPECT_CALL(client_, GetPasswordStore())
+  EXPECT_CALL(client_, GetProfilePasswordStore())
       .WillRepeatedly(testing::Return(store_.get()));
   PasswordReuseDetectionManager manager(&client_);
 
diff --git a/components/password_manager/core/browser/store_metrics_reporter.cc b/components/password_manager/core/browser/store_metrics_reporter.cc
index 34eca4d..abb22f6 100644
--- a/components/password_manager/core/browser/store_metrics_reporter.cc
+++ b/components/password_manager/core/browser/store_metrics_reporter.cc
@@ -19,7 +19,7 @@
     const signin::IdentityManager* identity_manager,
     PrefService* prefs) {
   // May be null in tests.
-  if (PasswordStore* store = client->GetPasswordStore()) {
+  if (PasswordStore* store = client->GetProfilePasswordStore()) {
     store->ReportMetrics(
         password_manager::sync_util::GetSyncUsernameIfSyncingPasswords(
             sync_service, identity_manager),
diff --git a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
index 4a151bd4..c6a03b4d 100644
--- a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
+++ b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
@@ -26,7 +26,7 @@
 
 class MockPasswordManagerClient : public StubPasswordManagerClient {
  public:
-  MOCK_CONST_METHOD0(GetPasswordStore, PasswordStore*());
+  MOCK_CONST_METHOD0(GetProfilePasswordStore, PasswordStore*());
   MOCK_CONST_METHOD0(GetPasswordSyncState, SyncState());
   MOCK_CONST_METHOD0(IsUnderAdvancedProtection, bool());
 };
@@ -73,7 +73,7 @@
   prefs_.SetInteger(password_manager::prefs::kPasswordManagerOnboardingState,
                     onboarding_state);
   base::HistogramTester histogram_tester;
-  EXPECT_CALL(client_, GetPasswordStore()).WillOnce(Return(nullptr));
+  EXPECT_CALL(client_, GetProfilePasswordStore()).WillOnce(Return(nullptr));
   StoreMetricsReporter reporter(&client_, sync_service(), identity_manager(),
                                 &prefs_);
 
@@ -96,7 +96,7 @@
                               ? password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE
                               : password_manager::SYNCING_NORMAL_ENCRYPTION;
   EXPECT_CALL(client_, GetPasswordSyncState()).WillOnce(Return(sync_state));
-  EXPECT_CALL(client_, GetPasswordStore()).WillOnce(Return(store.get()));
+  EXPECT_CALL(client_, GetProfilePasswordStore()).WillOnce(Return(store.get()));
   EXPECT_CALL(client_, IsUnderAdvancedProtection())
       .WillOnce(Return(is_under_advanced_protection));
   EXPECT_CALL(*store,
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc
index 46dc90a6..d36a3f1 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -65,7 +65,7 @@
   return nullptr;
 }
 
-PasswordStore* StubPasswordManagerClient::GetPasswordStore() const {
+PasswordStore* StubPasswordManagerClient::GetProfilePasswordStore() const {
   return nullptr;
 }
 
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h
index 82423fce..a6a6824 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -54,7 +54,7 @@
   void AutomaticPasswordSave(
       std::unique_ptr<PasswordFormManagerForUI> saved_manager) override;
   PrefService* GetPrefs() const override;
-  PasswordStore* GetPasswordStore() const override;
+  PasswordStore* GetProfilePasswordStore() const override;
   const GURL& GetLastCommittedEntryURL() const override;
   const CredentialsFilter* GetStoreResultFilter() const override;
   const autofill::LogManager* GetLogManager() const override;
diff --git a/components/password_manager/core/browser/sync_credentials_filter_unittest.cc b/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
index 9603ef7..6f3b5c0 100644
--- a/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
+++ b/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
@@ -70,7 +70,7 @@
   const GURL& GetLastCommittedEntryURL() const override {
     return last_committed_entry_url_;
   }
-  MockPasswordStore* GetPasswordStore() const override {
+  MockPasswordStore* GetProfilePasswordStore() const override {
     return password_store_.get();
   }
   signin::IdentityManager* GetIdentityManager() override {
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index 2a64a60c..4130891b 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -1069,6 +1069,14 @@
 
   // New required platform version from the pending updated kiosk app.
   optional string new_required_platform_version = 3;
+
+  // The timestamp of the last update check.
+  // [timestamp] is milliseconds since Epoch in UTC timezone (Java time).
+  optional int64 last_checked_timestamp = 4;
+
+  // The timestamp of the last reboot.
+  // [timestamp] is milliseconds since Epoch in UTC timezone (Java time).
+  optional int64 last_reboot_timestamp = 5;
 }
 
 // Provides status information for an installed app/extension.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index bae7c15..1dd6288 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -821,6 +821,7 @@
         'ReportDeviceNetworkInterfaces',
         'ReportDeviceHardwareStatus',
         'ReportDeviceSessionStatus',
+        'ReportDeviceOsUpdateStatus',
         'ReportDeviceBoardStatus',
         'ReportDevicePowerStatus',
         'ReportDeviceStorageStatus',
@@ -7270,6 +7271,28 @@
       'arc_support': 'This policy has no effect on the logging done by Android.',
     },
     {
+      'name': 'ReportDeviceOsUpdateStatus',
+      'owners': ['anqing@chromium.org'],
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome_os:79-'],
+      'supported_chrome_os_management': ['google_cloud'],
+      'device_only': True,
+      'features': {
+        'dynamic_refresh': True,
+      },
+      'example_value': False,
+      'id': 602,
+      'caption': '''Report OS update status''',
+      'tags': ['admin-sharing'],
+      'desc': '''Report OS update information such as update status, platform version,
+      last update check and last reboot.
+
+      If the policy is set to false or left unset, the OS update information will not be
+      reported. If set to true, OS update information will be reported.''',
+      'arc_support': 'This policy has no effect on the logging done by Android.',
+    },
+    {
       'name': 'ReportDevicePowerStatus',
       'owners': ['antrim@chromium.org'],
       'type': 'main',
@@ -7286,8 +7309,8 @@
       'tags': ['admin-sharing'],
       'desc': '''Report hardware statistics and identifiers related to power.
 
-      If the policy is set to false, the statistics will not be reported.
-      If set to true or left unset, statistics will be reported.''',
+      If the policy is set to false or left unset, the statistics will not be reported.
+      If set to true, statistics will be reported.''',
       'arc_support': 'This policy has no effect on the logging done by Android.',
     },
     {
@@ -7307,8 +7330,8 @@
       'tags': ['admin-sharing'],
       'desc': '''Report hardware statistics and identifiers for storage devices.
 
-      If the policy is set to false, the statistics will not be reported.
-      If set to true or left unset, statistics will be reported.''',
+      If the policy is set to false or left unset, the statistics will not be reported.
+      If set to true, statistics will be reported.''',
       'arc_support': 'This policy has no effect on the logging done by Android.',
     },
     {
@@ -7328,8 +7351,8 @@
       'tags': ['admin-sharing'],
       'desc': '''Report hardware statistics for SoC components.
 
-      If the policy is set to false, the statistics will not be reported.
-      If set to true or left unset, statistics will be reported.''',
+      If the policy is set to false or left unset, the statistics will not be reported.
+      If set to true, statistics will be reported.''',
       'arc_support': 'This policy has no effect on the logging done by Android.',
     },
     {
@@ -17812,7 +17835,6 @@
     ['DeviceLoginScreenSaverTimeout', ''],
     ['DeviceAppPack', ''],
     # Proto fields with unknown policy.
-    ['', 'device_reporting.report_os_update_status'],
     ['', 'device_reporting.report_running_kiosk_app'],
     ['', 'camera_enabled.camera_enabled'],
     # Not an actual policy.
@@ -17909,6 +17931,7 @@
     'ReportDeviceUsers': 'device_reporting.report_users',
     'ReportDeviceHardwareStatus': 'device_reporting.report_hardware_status',
     'ReportDeviceSessionStatus': 'device_reporting.report_session_status',
+    'ReportDeviceOsUpdateStatus': 'device_reporting.report_os_update_status',
     'ReportDeviceVersionInfo': 'device_reporting.report_version_info',
     'ReportUploadFrequency': 'device_reporting.device_status_frequency',
     'NetworkThrottlingEnabled': 'network_throttling.enabled',
@@ -18329,6 +18352,7 @@
         'ReportDeviceNetworkInterfaces',
         'ReportDeviceHardwareStatus',
         'ReportDeviceSessionStatus',
+        'ReportDeviceOsUpdateStatus',
         'ReportDeviceBoardStatus',
         'ReportDevicePowerStatus',
         'ReportDeviceStorageStatus',
@@ -18394,6 +18418,6 @@
   ],
   'placeholders': [],
   'deleted_policy_ids': [412, 546, 562, 569],
-  'highest_id_currently_used': 601,
+  'highest_id_currently_used': 602,
   'highest_atomic_group_id_currently_used': 37
 }
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn
index df01214e..ffa08b3 100644
--- a/components/signin/core/browser/BUILD.gn
+++ b/components/signin/core/browser/BUILD.gn
@@ -82,6 +82,11 @@
   ]
 
   if (is_chromeos) {
+    sources += [
+      "active_directory_account_reconcilor_delegate.cc",
+      "active_directory_account_reconcilor_delegate.h",
+    ]
+    deps += [ "//chromeos/tpm:tpm" ]
     sources -= [
       "signin_status_metrics_provider.cc",
       "signin_status_metrics_provider_delegate.cc",
@@ -110,7 +115,6 @@
   testonly = true
   sources = [
     "account_investigator_unittest.cc",
-    "account_reconcilor_delegate_unittest.cc",
     "account_reconcilor_unittest.cc",
     "dice_account_reconcilor_delegate_unittest.cc",
     "mice_account_reconcilor_delegate_unittest.cc",
@@ -143,6 +147,7 @@
   ]
 
   if (is_chromeos) {
+    deps += [ "//chromeos/tpm:test_support" ]
     sources -= [
       "account_investigator_unittest.cc",
       "signin_status_metrics_provider_unittest.cc",
diff --git a/components/signin/core/browser/DEPS b/components/signin/core/browser/DEPS
index 534d908..080a1d6 100644
--- a/components/signin/core/browser/DEPS
+++ b/components/signin/core/browser/DEPS
@@ -3,3 +3,13 @@
   "+components/signin/public/base",
   "+components/signin/public/identity_manager",
 ]
+
+specific_include_rules = {
+  "active_directory_account_reconcilor_delegate.cc": [
+    "+chromeos/tpm/install_attributes.h"
+  ],
+  "account_reconcilor_unittest.cc": [
+    "+chromeos/tpm/install_attributes.h",
+    "+chromeos/tpm/stub_install_attributes.h"
+  ]
+}
diff --git a/components/signin/core/browser/account_investigator_unittest.cc b/components/signin/core/browser/account_investigator_unittest.cc
index c1aa866..89ed251e 100644
--- a/components/signin/core/browser/account_investigator_unittest.cc
+++ b/components/signin/core/browser/account_investigator_unittest.cc
@@ -133,7 +133,7 @@
 
  private:
   // Timer needs a message loop.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable prefs_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   signin::IdentityTestEnvironment identity_test_env_;
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index d1e1710..85c6b144 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -790,9 +790,12 @@
 
   if (first_account.empty()) {
     DCHECK(!delegate_->ShouldAbortReconcileIfPrimaryHasError());
+    auto revoke_option =
+        delegate_->ShouldRevokeTokensIfNoPrimaryAccount()
+            ? AccountReconcilorDelegate::RevokeTokenOption::kRevoke
+            : AccountReconcilorDelegate::RevokeTokenOption::kDoNotRevoke;
     reconcile_is_noop_ = !RevokeAllSecondaryTokens(
-        identity_manager_,
-        AccountReconcilorDelegate::RevokeTokenOption::kRevoke, primary_account,
+        identity_manager_, revoke_option, primary_account,
         delegate_->IsAccountConsistencyEnforced(),
         signin_metrics::SourceForRefreshTokenOperation::
             kAccountReconcilor_Reconcile);
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h
index f617f00..00bcf86 100644
--- a/components/signin/core/browser/account_reconcilor.h
+++ b/components/signin/core/browser/account_reconcilor.h
@@ -242,6 +242,10 @@
   FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, MultiloginLogout);
   FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTestForceDiceMigration,
                            TableRowTest);
+  FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTestActiveDirectory,
+                           TableRowTestMergeSession);
+  FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTestActiveDirectory,
+                           TableRowTestMultilogin);
 
   void set_timer_for_testing(std::unique_ptr<base::OneShotTimer> timer);
 
diff --git a/components/signin/core/browser/account_reconcilor_delegate.cc b/components/signin/core/browser/account_reconcilor_delegate.cc
index 46d7d0be..f5c62206 100644
--- a/components/signin/core/browser/account_reconcilor_delegate.cc
+++ b/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -184,6 +184,10 @@
   return false;
 }
 
+bool AccountReconcilorDelegate::ShouldRevokeTokensIfNoPrimaryAccount() const {
+  return true;
+}
+
 base::TimeDelta AccountReconcilorDelegate::GetReconcileTimeout() const {
   return base::TimeDelta::Max();
 }
diff --git a/components/signin/core/browser/account_reconcilor_delegate.h b/components/signin/core/browser/account_reconcilor_delegate.h
index d9edf545..6a26da3 100644
--- a/components/signin/core/browser/account_reconcilor_delegate.h
+++ b/components/signin/core/browser/account_reconcilor_delegate.h
@@ -108,6 +108,9 @@
   // invalidated unless it has to be kept for critical Sync operations.
   virtual bool ShouldRevokeTokensOnCookieDeleted();
 
+  // Returns whether tokens should be revoked when the primary account is empty
+  virtual bool ShouldRevokeTokensIfNoPrimaryAccount() const;
+
   // Called when reconcile is finished.
   // |OnReconcileFinished| is always called at the end of reconciliation,
   // even when there is an error (except in cases where reconciliation times
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc
index 85c57f8f..6afeb66 100644
--- a/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -46,6 +46,11 @@
 #include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
 #endif
 
+#if defined(OS_CHROMEOS)
+#include "chromeos/tpm/stub_install_attributes.h"
+#include "components/signin/core/browser/active_directory_account_reconcilor_delegate.h"
+#endif
+
 using signin::RevokeTokenAction;
 using signin_metrics::AccountReconcilorState;
 
@@ -244,7 +249,9 @@
     return &identity_test_env_;
   }
 
-  base::test::TaskEnvironment* task_environment() { return &task_environment_; }
+  base::test::SingleThreadTaskEnvironment* task_environment() {
+    return &task_environment_;
+  }
 
   TestSigninClient* test_signin_client() { return &test_signin_client_; }
   base::HistogramTester* histogram_tester() { return &histogram_tester_; }
@@ -282,7 +289,7 @@
   network::TestURLLoaderFactory test_url_loader_factory_;
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   signin::AccountConsistencyMethod account_consistency_;
   bool dice_migration_completed_ = false;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
@@ -349,7 +356,8 @@
                              signin::AccountConsistencyMethod::kMirror));
 
 AccountReconcilorTest::AccountReconcilorTest()
-    : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+    : task_environment_(
+          base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
       account_consistency_(signin::AccountConsistencyMethod::kDisabled),
       test_signin_client_(&pref_service_, &test_url_loader_factory_),
       identity_test_env_(/*test_url_loader_factory=*/nullptr,
@@ -1997,6 +2005,194 @@
     AccountReconcilorTestMirrorMultilogin,
     ::testing::ValuesIn(GenerateTestCasesFromParams(kMirrorParams)));
 
+#if defined(OS_CHROMEOS)
+class AccountReconcilorTestActiveDirectory : public AccountReconcilorTestTable {
+ public:
+  AccountReconcilorTestActiveDirectory() = default;
+
+  void SetUp() override {
+    SetAccountConsistency(signin::AccountConsistencyMethod::kMirror);
+  }
+
+ private:
+  chromeos::ScopedStubInstallAttributes install_attributes_{
+      chromeos::StubInstallAttributes::CreateActiveDirectoryManaged(
+          "realm.com",
+          "device_id")};
+
+  DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTestActiveDirectory);
+};
+
+// clang-format off
+const std::vector<AccountReconcilorTestTableParam> kActiveDirectoryParams = {
+// This table encodes the initial state and expectations of a reconcile.
+// See kDiceParams for documentation of the syntax.
+// -------------------------------------------------------------------------
+// Tokens  |Cookies |First Run     |Gaia calls|Tokens aft.|Cookies aft.|M.calls|
+// -------------------------------------------------------------------------
+{  "ABC",   "ABC",   IsFirstReconcile::kBoth,   "",    "ABC",   "ABC",   "" },
+{  "ABC",   "",      IsFirstReconcile::kBoth,   "",    "ABC",   "ABC",   "U"},
+{  "",      "ABC",   IsFirstReconcile::kBoth,   "X",   "",      "",      "X"},
+// Order of Gaia accounts can be different from chrome accounts.
+{  "ABC",   "CBA",   IsFirstReconcile::kBoth,   "",    "ABC",   "CBA",   "" },
+{  "ABC",   "CB",    IsFirstReconcile::kBoth,   "",    "ABC",   "CBA",   "U"},
+// Gaia accounts which are not present in chrome accounts should be removed. In
+// this case Gaia accounts are going to be in the same order as chrome accounts.
+{  "A",     "AB",    IsFirstReconcile::kBoth,   "X",   "A",     "A",     "U"},
+{  "AB",    "CBA",   IsFirstReconcile::kBoth,   "X",   "AB",    "AB",    "U"},
+{  "AB",    "C",     IsFirstReconcile::kBoth,   "X",   "AB",    "AB",    "U"},
+// Cookies can be refreshed in pace, without logout.
+{  "AB",    "xAxB",  IsFirstReconcile::kBoth,   "",    "AB",    "AB",    "U"},
+// Token error on the account - remove it from cookies
+{  "AxB",   "AB",    IsFirstReconcile::kBoth,   "X",   "AxB",   "A",     "U"},
+{  "xAxB",  "AB",    IsFirstReconcile::kBoth,   "X",   "xAxB",  "",      "X"},
+};
+// clang-format on
+
+TEST_P(AccountReconcilorTestActiveDirectory, TableRowTestMergeSession) {
+  // Setup tokens.
+  std::vector<Token> tokens = ParseTokenString(GetParam().tokens);
+  SetupTokens(GetParam().tokens);
+
+  // Setup cookies.
+  std::vector<Cookie> cookies = ParseCookieString(GetParam().cookies);
+  ConfigureCookieManagerService(cookies);
+
+  // Call list accounts now so that the next call completes synchronously.
+  identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+  base::RunLoop().RunUntilIdle();
+
+  testing::InSequence mock_sequence;
+  MockAccountReconcilor* reconcilor = GetMockReconcilor(
+      std::make_unique<signin::ActiveDirectoryAccountReconcilorDelegate>());
+
+  // Setup expectations.
+  bool logout_all_accounts = false;
+  for (int i = 0; GetParam().gaia_api_calls[i] != '\0'; ++i) {
+    if (GetParam().gaia_api_calls[i] == 'X') {
+      logout_all_accounts = true;
+      break;
+    }
+  }
+  if (logout_all_accounts)
+    EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction);
+
+  for (auto& account : tokens) {
+    if (account.has_error)
+      continue;
+    Cookie account_cookie{account.gaia_id, true /*is_valid*/};
+    if (logout_all_accounts || !base::Contains(cookies, account_cookie)) {
+      EXPECT_CALL(*reconcilor,
+                  PerformMergeAction(CoreAccountId(account.email)));
+    }
+  }
+
+  // Reconcile.
+  ASSERT_TRUE(reconcilor);
+  ASSERT_TRUE(reconcilor->first_execution_);
+  reconcilor->first_execution_ =
+      GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
+  reconcilor->StartReconcile();
+
+  SimulateSetAccountsInCookieCompleted(
+      reconcilor, signin::SetAccountsInCookieResult::kSuccess);
+
+  ASSERT_FALSE(reconcilor->is_reconcile_started_);
+  ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
+  VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
+
+  testing::Mock::VerifyAndClearExpectations(reconcilor);
+
+  // Another reconcile is sometimes triggered if Chrome accounts have
+  // changed. Allow it to finish.
+  EXPECT_CALL(*reconcilor, PerformSetCookiesAction(testing::_))
+      .WillRepeatedly(testing::Return());
+  EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction())
+      .WillRepeatedly(testing::Return());
+  ConfigureCookieManagerService({});
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(AccountReconcilorTestActiveDirectory, TableRowTestMultilogin) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kUseMultiloginEndpoint);
+
+  // Setup tokens.
+  std::vector<Token> tokens = ParseTokenString(GetParam().tokens);
+  SetupTokens(GetParam().tokens);
+
+  // Setup cookies.
+  std::vector<Cookie> cookies = ParseCookieString(GetParam().cookies);
+  ConfigureCookieManagerService(cookies);
+
+  // Call list accounts now so that the next call completes synchronously.
+  identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+  base::RunLoop().RunUntilIdle();
+
+  testing::InSequence mock_sequence;
+  MockAccountReconcilor* reconcilor = GetMockReconcilor(
+      std::make_unique<signin::ActiveDirectoryAccountReconcilorDelegate>());
+
+  // Setup expectations.
+  bool logout_action = false;
+  for (int i = 0; GetParam().gaia_api_calls_multilogin[i] != '\0'; ++i) {
+    if (GetParam().gaia_api_calls_multilogin[i] == 'X') {
+      logout_action = true;
+      EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction()).Times(1);
+      cookies.clear();
+      continue;
+    }
+    if (GetParam().gaia_api_calls_multilogin[i] == 'U') {
+      std::vector<CoreAccountId> accounts_to_send;
+      for (int i = 0; GetParam().cookies_after_reconcile[i] != '\0'; ++i) {
+        char cookie = GetParam().cookies_after_reconcile[i];
+        std::string account_to_send = GaiaIdForAccountKey(cookie);
+        accounts_to_send.push_back(PickAccountIdForAccount(
+            account_to_send,
+            accounts_[GetParam().cookies_after_reconcile[i]].email));
+      }
+      const signin::MultiloginParameters params(
+          gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+          accounts_to_send);
+      EXPECT_CALL(*reconcilor, PerformSetCookiesAction(params)).Times(1);
+    }
+  }
+  if (!logout_action) {
+    EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction()).Times(0);
+  }
+
+  // Reconcile.
+  ASSERT_TRUE(reconcilor);
+  ASSERT_TRUE(reconcilor->first_execution_);
+  reconcilor->first_execution_ =
+      GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
+  reconcilor->StartReconcile();
+
+  SimulateSetAccountsInCookieCompleted(
+      reconcilor, signin::SetAccountsInCookieResult::kSuccess);
+
+  ASSERT_FALSE(reconcilor->is_reconcile_started_);
+  ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
+  VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
+
+  testing::Mock::VerifyAndClearExpectations(reconcilor);
+
+  // Another reconcile is sometimes triggered if Chrome accounts have
+  // changed. Allow it to finish.
+  EXPECT_CALL(*reconcilor, PerformSetCookiesAction(testing::_))
+      .WillRepeatedly(testing::Return());
+  EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction())
+      .WillRepeatedly(testing::Return());
+  ConfigureCookieManagerService({});
+  base::RunLoop().RunUntilIdle();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ActiveDirectoryTable,
+    AccountReconcilorTestActiveDirectory,
+    ::testing::ValuesIn(GenerateTestCasesFromParams(kActiveDirectoryParams)));
+#endif  // defined(OS_CHROMEOS)
+
 #if defined(OS_ANDROID)
 // clang-format off
 const std::vector<AccountReconcilorTestTableParam> kMiceParams = {
diff --git a/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc b/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc
new file mode 100644
index 0000000..a848799
--- /dev/null
+++ b/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc
@@ -0,0 +1,88 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/core/browser/active_directory_account_reconcilor_delegate.h"
+
+#include "chromeos/tpm/install_attributes.h"
+#include "google_apis/gaia/core_account_id.h"
+
+namespace signin {
+
+ActiveDirectoryAccountReconcilorDelegate::
+    ActiveDirectoryAccountReconcilorDelegate() {
+  DCHECK(chromeos::InstallAttributes::Get()->IsActiveDirectoryManaged());
+}
+
+ActiveDirectoryAccountReconcilorDelegate::
+    ~ActiveDirectoryAccountReconcilorDelegate() = default;
+
+bool ActiveDirectoryAccountReconcilorDelegate::IsAccountConsistencyEnforced()
+    const {
+  return true;
+}
+
+gaia::GaiaSource ActiveDirectoryAccountReconcilorDelegate::GetGaiaApiSource()
+    const {
+  return gaia::GaiaSource::kAccountReconcilorMirror;
+}
+
+bool ActiveDirectoryAccountReconcilorDelegate::IsReconcileEnabled() const {
+  return true;
+}
+
+CoreAccountId
+ActiveDirectoryAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
+    const std::vector<CoreAccountId>& chrome_accounts,
+    const std::vector<gaia::ListedAccount>& gaia_accounts,
+    const CoreAccountId& primary_account,
+    bool first_execution,
+    bool will_logout) const {
+  return GetFirstAccount(chrome_accounts, gaia_accounts);
+}
+
+std::vector<CoreAccountId>
+ActiveDirectoryAccountReconcilorDelegate::GetChromeAccountsForReconcile(
+    const std::vector<CoreAccountId>& chrome_accounts,
+    const CoreAccountId& primary_account,
+    const std::vector<gaia::ListedAccount>& gaia_accounts,
+    const gaia::MultiloginMode mode) const {
+  DCHECK_EQ(mode,
+            gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
+  if (chrome_accounts.empty())
+    return chrome_accounts;
+  return ReorderChromeAccountsForReconcile(
+      chrome_accounts, GetFirstAccount(chrome_accounts, gaia_accounts),
+      gaia_accounts);
+}
+
+bool ActiveDirectoryAccountReconcilorDelegate::
+    ShouldAbortReconcileIfPrimaryHasError() const {
+  return false;
+}
+
+bool ActiveDirectoryAccountReconcilorDelegate::
+    ShouldRevokeTokensIfNoPrimaryAccount() const {
+  return false;
+}
+
+CoreAccountId ActiveDirectoryAccountReconcilorDelegate::GetFirstAccount(
+    const std::vector<CoreAccountId>& chrome_accounts,
+    const std::vector<gaia::ListedAccount>& gaia_accounts) const {
+  if (chrome_accounts.empty())
+    return CoreAccountId();
+  // Return first gaia account to preserve the account order in the cookie jar.
+  // (Gaia accounts which are NOT in chrome_accounts will be removed.) In case
+  // of first account mismatch, the cookie will be rebuilt and order of accounts
+  // will be changed.
+  if (!gaia_accounts.empty() &&
+      base::Contains(chrome_accounts, gaia_accounts[0].id)) {
+    return gaia_accounts[0].id;
+  }
+  // The cookie jar is empty or first Gaia account in the cookie jar is
+  // not present in Account Manager. Fall back to choosing the first account
+  // present in Account Manager as the first account for reconciliation.
+  return chrome_accounts[0];
+}
+
+}  // namespace signin
diff --git a/components/signin/core/browser/active_directory_account_reconcilor_delegate.h b/components/signin/core/browser/active_directory_account_reconcilor_delegate.h
new file mode 100644
index 0000000..dd1d215f
--- /dev/null
+++ b/components/signin/core/browser/active_directory_account_reconcilor_delegate.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACTIVE_DIRECTORY_ACCOUNT_RECONCILOR_DELEGATE_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_ACTIVE_DIRECTORY_ACCOUNT_RECONCILOR_DELEGATE_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "components/signin/core/browser/account_reconcilor_delegate.h"
+
+namespace signin {
+
+// AccountReconcilorDelegate specialized for Active Directory accounts.
+class ActiveDirectoryAccountReconcilorDelegate
+    : public AccountReconcilorDelegate {
+ public:
+  ActiveDirectoryAccountReconcilorDelegate();
+  ~ActiveDirectoryAccountReconcilorDelegate() override;
+
+  // AccountReconcilorDelegate:
+  bool IsAccountConsistencyEnforced() const override;
+  gaia::GaiaSource GetGaiaApiSource() const override;
+  bool IsReconcileEnabled() const override;
+  CoreAccountId GetFirstGaiaAccountForReconcile(
+      const std::vector<CoreAccountId>& chrome_accounts,
+      const std::vector<gaia::ListedAccount>& gaia_accounts,
+      const CoreAccountId& primary_account,
+      bool first_execution,
+      bool will_logout) const override;
+
+  std::vector<CoreAccountId> GetChromeAccountsForReconcile(
+      const std::vector<CoreAccountId>& chrome_accounts,
+      const CoreAccountId& primary_account,
+      const std::vector<gaia::ListedAccount>& gaia_accounts,
+      const gaia::MultiloginMode mode) const override;
+  bool ShouldAbortReconcileIfPrimaryHasError() const override;
+  bool ShouldRevokeTokensIfNoPrimaryAccount() const override;
+
+ private:
+  // Returns first gaia account if it is present in |chrome_accounts|.
+  // Otherwise, the first chrome account is returned.
+  CoreAccountId GetFirstAccount(
+      const std::vector<CoreAccountId>& chrome_accounts,
+      const std::vector<gaia::ListedAccount>& gaia_accounts) const;
+
+  DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryAccountReconcilorDelegate);
+};
+
+}  // namespace signin
+
+#endif  // COMPONENTS_SIGNIN_CORE_BROWSER_ACTIVE_DIRECTORY_ACCOUNT_RECONCILOR_DELEGATE_H_
diff --git a/components/signin/core/browser/signin_header_helper_unittest.cc b/components/signin/core/browser/signin_header_helper_unittest.cc
index b6f8773..8e7cb76 100644
--- a/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -112,7 +112,7 @@
   }
 #endif
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   bool sync_enabled_ = false;
   std::string device_id_ = kTestDeviceId;
diff --git a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
index d2b158e..f4f8449 100644
--- a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
+++ b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "build/build_config.h"
 #include "components/signin/internal/identity_manager/account_tracker_service.h"
 #include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h"
 #include "google_apis/gaia/core_account_id.h"
@@ -59,6 +60,12 @@
   gaia_cookie_manager_service_->TriggerListAccounts();
 }
 
+#if defined(OS_IOS)
+void AccountsCookieMutatorImpl::ForceTriggerOnCookieChange() {
+  gaia_cookie_manager_service_->ForceOnCookieChangeProcessing();
+}
+#endif
+
 void AccountsCookieMutatorImpl::LogOutAllAccounts(gaia::GaiaSource source) {
   gaia_cookie_manager_service_->LogOutAllAccounts(source);
 }
diff --git a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
index a083bbb..dcbcdcf9 100644
--- a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
+++ b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
 
 class AccountTrackerService;
@@ -47,6 +48,10 @@
 
   void TriggerCookieJarUpdate() override;
 
+#if defined(OS_IOS)
+  void ForceTriggerOnCookieChange() override;
+#endif
+
   void LogOutAllAccounts(gaia::GaiaSource source) override;
 
  private:
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc
index 4213044..73b788e3 100644
--- a/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -59,9 +59,6 @@
   registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
   registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
   registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
-
-  // Deprecated prefs: will be removed in a future release.
-  registry->RegisterStringPref(prefs::kGoogleServicesUsername, std::string());
 }
 
 // static
@@ -81,63 +78,12 @@
   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
   if (cmd_line->HasSwitch(switches::kClearTokenService)) {
     client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId);
-    client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
     client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
   }
 
   std::string pref_account_id =
       client_->GetPrefs()->GetString(prefs::kGoogleServicesAccountId);
 
-  // Handle backward compatibility: if kGoogleServicesAccountId is empty, but
-  // kGoogleServicesUsername is not, then this is an old profile that needs to
-  // be updated.  kGoogleServicesUserAccountId should not be empty, and contains
-  // the gaia_id.  Use both properties to prime the account tracker before
-  // proceeding.
-  if (pref_account_id.empty()) {
-    std::string pref_account_username =
-        client_->GetPrefs()->GetString(prefs::kGoogleServicesUsername);
-    if (!pref_account_username.empty()) {
-      // This is an old profile connected to a google account.  Migrate from
-      // kGoogleServicesUsername to kGoogleServicesAccountId.
-      std::string pref_gaia_id =
-          client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId);
-
-      // If kGoogleServicesUserAccountId is empty, then this is either a cros
-      // machine or a really old profile on one of the other platforms.  However
-      // in this case the account tracker should have the gaia_id so fetch it
-      // from there.
-      if (pref_gaia_id.empty()) {
-        CoreAccountInfo info = account_tracker_service_->FindAccountInfoByEmail(
-            pref_account_username);
-        pref_gaia_id = info.gaia;
-      }
-
-      // If |pref_gaia_id| is still empty, this means the profile has been in
-      // an auth error state for some time (since M39).  It could also mean
-      // a profile that has not been used since M33.  Before migration to gaia
-      // id is complete, the returned value will be the normalized email, which
-      // is correct.  After the migration, the returned value will be empty,
-      // which means the user is essentially signed out.
-      // TODO(rogerta): may want to show a toast or something.
-      pref_account_id =
-          account_tracker_service_
-              ->SeedAccountInfo(pref_gaia_id, pref_account_username)
-              .id;
-
-      // Set account id before removing obsolete user name in case crash in the
-      // middle.
-      client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId,
-                                     pref_account_id);
-
-      // Now remove obsolete preferences.
-      client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
-    }
-
-    // TODO(rogerta): once migration to gaia id is complete, remove
-    // kGoogleServicesUserAccountId and change all uses of that pref to
-    // kGoogleServicesAccountId.
-  }
-
   if (!pref_account_id.empty()) {
     if (account_tracker_service_->GetMigrationState() ==
         AccountTrackerService::MIGRATION_IN_PROGRESS) {
diff --git a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
index 4ed8c5a..8a5d236 100644
--- a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -328,58 +328,6 @@
 }
 #endif
 
-TEST_F(PrimaryAccountManagerTest, UpgradeToNewPrefs) {
-  user_prefs_.SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
-  user_prefs_.SetString(prefs::kGoogleServicesUserAccountId, "account_id");
-  CreatePrimaryAccountManager();
-  EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
-
-  if (account_tracker()->GetMigrationState() ==
-      AccountTrackerService::MIGRATION_NOT_STARTED) {
-    // TODO(rogerta): until the migration to gaia id, the account id will remain
-    // the old username.
-    EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountId());
-    EXPECT_EQ("user@gmail.com",
-              user_prefs_.GetString(prefs::kGoogleServicesAccountId));
-  } else {
-    EXPECT_EQ("account_id", manager_->GetAuthenticatedAccountId());
-    EXPECT_EQ("account_id",
-              user_prefs_.GetString(prefs::kGoogleServicesAccountId));
-  }
-  EXPECT_EQ("", user_prefs_.GetString(prefs::kGoogleServicesUsername));
-
-  // Make sure account tracker was updated.
-  AccountInfo info =
-      account_tracker()->GetAccountInfo(manager_->GetAuthenticatedAccountId());
-  EXPECT_EQ("user@gmail.com", info.email);
-  EXPECT_EQ("account_id", info.gaia);
-}
-
-TEST_F(PrimaryAccountManagerTest, CanonicalizesPrefs) {
-  // This unit test is not needed after migrating to gaia id.
-  if (account_tracker()->GetMigrationState() ==
-      AccountTrackerService::MIGRATION_NOT_STARTED) {
-    user_prefs_.SetString(prefs::kGoogleServicesUsername, "user.C@gmail.com");
-
-    CreatePrimaryAccountManager();
-    EXPECT_EQ("user.C@gmail.com",
-              manager_->GetAuthenticatedAccountInfo().email);
-
-    // TODO(rogerta): until the migration to gaia id, the account id will remain
-    // the old username.
-    EXPECT_EQ("userc@gmail.com", manager_->GetAuthenticatedAccountId());
-    EXPECT_EQ("userc@gmail.com",
-              user_prefs_.GetString(prefs::kGoogleServicesAccountId));
-    EXPECT_EQ("", user_prefs_.GetString(prefs::kGoogleServicesUsername));
-
-    // Make sure account tracker has a canonicalized username.
-    AccountInfo info = account_tracker()->GetAccountInfo(
-        manager_->GetAuthenticatedAccountId());
-    EXPECT_EQ("user.C@gmail.com", info.email);
-    EXPECT_EQ("userc@gmail.com", info.account_id);
-  }
-}
-
 TEST_F(PrimaryAccountManagerTest, GaiaIdMigration) {
   if (account_tracker()->GetMigrationState() !=
       AccountTrackerService::MIGRATION_NOT_STARTED) {
@@ -409,35 +357,6 @@
   }
 }
 
-TEST_F(PrimaryAccountManagerTest, VeryOldProfileGaiaIdMigration) {
-  if (account_tracker()->GetMigrationState() !=
-      AccountTrackerService::MIGRATION_NOT_STARTED) {
-    std::string email = "user@gmail.com";
-    std::string gaia_id = "account_gaia_id";
-
-    PrefService* client_prefs = signin_client()->GetPrefs();
-    client_prefs->SetInteger(prefs::kAccountIdMigrationState,
-                             AccountTrackerService::MIGRATION_NOT_STARTED);
-    ListPrefUpdate update(client_prefs, prefs::kAccountInfo);
-    update->Clear();
-    auto dict = std::make_unique<base::DictionaryValue>();
-    dict->SetString("account_id", email);
-    dict->SetString("email", email);
-    dict->SetString("gaia", gaia_id);
-    update->Append(std::move(dict));
-
-    account_tracker()->Shutdown();
-    account_tracker()->Initialize(prefs(), base::FilePath());
-
-    client_prefs->ClearPref(prefs::kGoogleServicesAccountId);
-    client_prefs->SetString(prefs::kGoogleServicesUsername, email);
-
-    CreatePrimaryAccountManager();
-    EXPECT_EQ(gaia_id, manager_->GetAuthenticatedAccountId());
-    EXPECT_EQ(gaia_id, user_prefs_.GetString(prefs::kGoogleServicesAccountId));
-  }
-}
-
 TEST_F(PrimaryAccountManagerTest, GaiaIdMigrationCrashInTheMiddle) {
   if (account_tracker()->GetMigrationState() !=
       AccountTrackerService::MIGRATION_NOT_STARTED) {
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_unittest.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_unittest.cc
index 6c04923..3142113 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_unittest.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_unittest.cc
@@ -116,9 +116,10 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::MainThreadType::IO};  // net:: stuff needs IO
-                                                         // message loop.
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::SingleThreadTaskEnvironment::MainThreadType::
+          IO};  // net:: stuff needs IO
+                // message loop.
   network::TestURLLoaderFactory* test_url_loader_factory_ = nullptr;
   FakeProfileOAuth2TokenServiceDelegate* delegate_ptr_ = nullptr;  // Not owned.
   std::unique_ptr<ProfileOAuth2TokenService> oauth2_service_;
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm
index 0f8da0c..8ab794a 100644
--- a/components/signin/ios/browser/account_consistency_service.mm
+++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -19,6 +19,7 @@
 #include "components/signin/core/browser/account_reconcilor.h"
 #include "components/signin/core/browser/signin_header_helper.h"
 #include "components/signin/public/base/account_consistency_method.h"
+#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
 #include "ios/web/common/web_view_creation_util.h"
 #include "ios/web/public/browser_state.h"
 #import "ios/web/public/navigation/web_state_policy_decider.h"
@@ -473,7 +474,7 @@
   // APISID cookie has been removed, notify the GCMS.
   // TODO(https://crbug.com/930582) : Remove the need to expose this method
   // or move it to the network::CookieManager.
-  identity_manager_->ForceTriggerOnCookieChange();
+  identity_manager_->GetAccountsCookieMutator()->ForceTriggerOnCookieChange();
 }
 
 void AccountConsistencyService::OnPrimaryAccountSet(
diff --git a/components/signin/ios/browser/account_consistency_service_unittest.mm b/components/signin/ios/browser/account_consistency_service_unittest.mm
index 420def8..3fbf1b3c 100644
--- a/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -441,8 +441,9 @@
   base::RunLoop run_loop;
   identity_test_env_->identity_manager_observer()
       ->SetOnAccountsInCookieUpdatedCallback(run_loop.QuitClosure());
-  // OnBrowsingDataRemoved triggers IdentityManager::ForceTriggerOnCookieChange
-  // and finally IdentityManager::Observer::OnAccountsInCookieUpdated is called.
+  // OnBrowsingDataRemoved triggers
+  // AccountsCookieMutator::ForceTriggerOnCookieChange and finally
+  // IdentityManager::Observer::OnAccountsInCookieUpdated is called.
   account_consistency_service_->OnBrowsingDataRemoved();
   run_loop.Run();
 
@@ -468,8 +469,9 @@
   base::RunLoop run_loop;
   identity_test_env_->identity_manager_observer()
       ->SetOnAccountsInCookieUpdatedCallback(run_loop.QuitClosure());
-  // OnBrowsingDataRemoved triggers IdentityManager::ForceTriggerOnCookieChange
-  // and finally IdentityManager::Observer::OnAccountsInCookieUpdated is called.
+  // OnBrowsingDataRemoved triggers
+  // AccountsCookieMutator::ForceTriggerOnCookieChange and finally
+  // IdentityManager::Observer::OnAccountsInCookieUpdated is called.
   account_consistency_service_->OnBrowsingDataRemoved();
   run_loop.Run();
   EXPECT_TRUE(remove_cookie_callback_called_);
diff --git a/components/signin/public/base/BUILD.gn b/components/signin/public/base/BUILD.gn
index 688252e9..b247d5d 100644
--- a/components/signin/public/base/BUILD.gn
+++ b/components/signin/public/base/BUILD.gn
@@ -52,6 +52,14 @@
   }
 }
 
+if (is_android) {
+  java_cpp_enum("signin_metrics_enum_javagen") {
+    sources = [
+      "signin_metrics.h",
+    ]
+  }
+}
+
 static_library("test_support") {
   testonly = true
   sources = [
diff --git a/components/signin/public/base/signin_metrics.h b/components/signin/public/base/signin_metrics.h
index 239a3f8..ebd3c74 100644
--- a/components/signin/public/base/signin_metrics.h
+++ b/components/signin/public/base/signin_metrics.h
@@ -26,7 +26,7 @@
 };
 
 // Track all the ways a profile can become signed out as a histogram.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.signin
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.metrics
 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SignoutReason
 enum ProfileSignout : int {
   // The value used within unit tests.
@@ -128,7 +128,7 @@
 // "Signin.SigninStartedAccessPoint" and "Signin.SigninCompletedAccessPoint"
 // histograms.
 // A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.signin
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.metrics
 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SigninAccessPoint
 enum class AccessPoint : int {
   ACCESS_POINT_START_PAGE = 0,
@@ -183,7 +183,7 @@
 
 // Enum values which enumerates all reasons to start sign in process.
 // A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.signin
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.metrics
 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SigninReason
 enum class Reason : int {
   REASON_SIGNIN_PRIMARY_ACCOUNT = 0,
@@ -248,6 +248,7 @@
 // When the user is give a choice of deleting their profile or not when signing
 // out, the |DELETED| or |KEEPING| metric should be used. If the user is not
 // given any option, then use the |IGNORE_METRIC| value should be used.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.metrics
 enum class SignoutDelete : int {
   DELETED = 0,
   KEEPING,
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc
index 0fe30da..b2b92c1e 100644
--- a/components/signin/public/base/signin_pref_names.cc
+++ b/components/signin/public/base/signin_pref_names.cc
@@ -56,12 +56,10 @@
 const char kGoogleServicesLastAccountId[] = "google.services.last_account_id";
 
 // String the identifies the last user that logged into sync and other
-// google services. As opposed to kGoogleServicesUsername, this value is not
-// cleared on signout, but while the user is signed in the two values will
-// be the same.  This pref remains in order to pre-fill the sign in page when
-// reconnecting a profile, but programmatic checks to see if a given account
-// is the same as the last account should use kGoogleServicesLastAccountId
-// instead.
+// google services. This value is not cleared on signout.
+// This pref remains in order to pre-fill the sign in page when reconnecting a
+// profile, but programmatic checks to see if a given account is the same as the
+// last account should use kGoogleServicesLastAccountId instead.
 const char kGoogleServicesLastUsername[] = "google.services.last_username";
 
 // Device id scoped to single signin. This device id will be regenerated if user
@@ -74,11 +72,6 @@
 // other google services.
 const char kGoogleServicesUserAccountId[] = "google.services.user_account_id";
 
-// String that identifies the current user logged into sync and other google
-// services.
-// DEPRECATED.
-const char kGoogleServicesUsername[] = "google.services.username";
-
 // Local state pref containing a string regex that restricts which accounts
 // can be used to log in to chrome (e.g. "*@google.com"). If missing or blank,
 // all accounts are allowed (no restrictions).
diff --git a/components/signin/public/base/signin_pref_names.h b/components/signin/public/base/signin_pref_names.h
index 26f1c460d..49584f70 100644
--- a/components/signin/public/base/signin_pref_names.h
+++ b/components/signin/public/base/signin_pref_names.h
@@ -22,7 +22,6 @@
 extern const char kGoogleServicesLastUsername[];
 extern const char kGoogleServicesSigninScopedDeviceId[];
 extern const char kGoogleServicesUserAccountId[];
-extern const char kGoogleServicesUsername[];
 extern const char kGoogleServicesUsernamePattern[];
 extern const char kReverseAutologinRejectedEmailList[];
 extern const char kSignedInWithCredentialProvider[];
diff --git a/components/signin/public/identity_manager/accounts_cookie_mutator.h b/components/signin/public/identity_manager/accounts_cookie_mutator.h
index af5dd83..eda6d87 100644
--- a/components/signin/public/identity_manager/accounts_cookie_mutator.h
+++ b/components/signin/public/identity_manager/accounts_cookie_mutator.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "google_apis/gaia/gaia_auth_fetcher.h"
 
 struct CoreAccountId;
@@ -63,6 +64,16 @@
   // know that the contents of the Gaia cookie might have changed.
   virtual void TriggerCookieJarUpdate() = 0;
 
+#if defined(OS_IOS)
+  // Forces the processing of GaiaCookieManagerService::OnCookieChange. On
+  // iOS, it's necessary to force-trigger the processing of cookie changes
+  // from the client as the normal mechanism for internally observing them
+  // is not wired up.
+  // TODO(https://crbug.com/930582) : Remove the need to expose this method
+  // or move it to the network::CookieManager.
+  virtual void ForceTriggerOnCookieChange() = 0;
+#endif
+
   // Remove all accounts from the Gaia cookie.
   virtual void LogOutAllAccounts(gaia::GaiaSource source) = 0;
 
diff --git a/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc b/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
index 57be5bd..9a1d5f06 100644
--- a/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
+++ b/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/test/bind_test_util.h"
 #include "base/test/gtest_util.h"
 #include "base/test/task_environment.h"
+#include "build/build_config.h"
 #include "components/signin/public/base/list_accounts_test_utils.h"
 #include "components/signin/public/base/test_signin_client.h"
 #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
@@ -53,6 +54,7 @@
   kSetAccountsInCookie,
   kTriggerCookieJarUpdateNoAccounts,
   kTriggerCookieJarUpdateOneAccount,
+  kTriggerOnCookieChangeNoAccounts,
 };
 
 }  // namespace
@@ -119,6 +121,9 @@
         SetListAccountsResponseOneAccount(kTestAccountEmail, kTestAccountGaiaId,
                                           GetTestURLLoaderFactory());
         break;
+      case AccountsCookiesMutatorAction::kTriggerOnCookieChangeNoAccounts:
+        SetListAccountsResponseNoAccounts(GetTestURLLoaderFactory());
+        break;
     }
   }
 
@@ -401,6 +406,22 @@
             GoogleServiceAuthError::NONE);
 }
 
+#if defined(OS_IOS)
+TEST_F(AccountsCookieMutatorTest, ForceTriggerOnCookieChange) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kTriggerOnCookieChangeNoAccounts);
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
+      run_loop.QuitClosure());
+
+  // Forces the processing of OnCookieChange and it calls
+  // OnGaiaAccountsInCookieUpdated.
+  accounts_cookie_mutator()->ForceTriggerOnCookieChange();
+  run_loop.Run();
+}
+#endif
+
 // Test that trying to log out all sessions generates the right network request.
 TEST_F(AccountsCookieMutatorTest, LogOutAllAccounts) {
   base::RunLoop run_loop;
diff --git a/components/signin/public/identity_manager/android/BUILD.gn b/components/signin/public/identity_manager/android/BUILD.gn
index 6d96dc4..2c422f4 100644
--- a/components/signin/public/identity_manager/android/BUILD.gn
+++ b/components/signin/public/identity_manager/android/BUILD.gn
@@ -9,6 +9,9 @@
     "//third_party/android_deps:com_android_support_support_annotations_java",
   ]
 
+  srcjar_deps =
+      [ "//components/signin/public/base:signin_metrics_enum_javagen" ]
+
   java_files = [
     "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
     "java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java",
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc
index 29fa0a9d..4e42032 100644
--- a/components/signin/public/identity_manager/identity_manager.cc
+++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -402,12 +402,6 @@
   return diagnostics_provider_.get();
 }
 
-#if defined(OS_IOS)
-void IdentityManager::ForceTriggerOnCookieChange() {
-  gaia_cookie_manager_service_->ForceOnCookieChangeProcessing();
-}
-#endif
-
 #if defined(OS_ANDROID)
 void IdentityManager::LegacyReloadAccountsFromSystem() {
   token_service_->GetDelegate()->ReloadAccountsFromSystem(
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h
index b00ffb4..c8a09931 100644
--- a/components/signin/public/identity_manager/identity_manager.h
+++ b/components/signin/public/identity_manager/identity_manager.h
@@ -425,16 +425,6 @@
   // state of IdentityManager.
   DiagnosticsProvider* GetDiagnosticsProvider();
 
-#if defined(OS_IOS)
-  // Forces the processing of GaiaCookieManagerService::OnCookieChange. On
-  // iOS, it's necessary to force-trigger the processing of cookie changes
-  // from the client as the normal mechanism for internally observing them
-  // is not wired up.
-  // TODO(https://crbug.com/930582) : Remove the need to expose this method
-  // or move it to the network::CookieManager.
-  void ForceTriggerOnCookieChange();
-#endif
-
 #if defined(OS_ANDROID)
   // Reloads the accounts in the token service from the system accounts. This
   // API calls ProfileOAuth2TokenServiceDelegate::ReloadAccountsFromSystem and
@@ -458,8 +448,7 @@
   base::android::ScopedJavaLocalRef<jobject>
   LegacyGetOAuth2TokenServiceJavaObject();
 
-  // Get the reference on the java IdentityManager, InitializeJavaObject must
-  // be called before hand.
+  // Get the reference on the java IdentityManager.
   base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
 
   // This method has the contractual assumption that the account is a known
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc
index ebfdf2b..5847b58 100644
--- a/components/signin/public/identity_manager/identity_manager_unittest.cc
+++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -1334,20 +1334,6 @@
   EXPECT_TRUE(mutator);
 }
 
-#if defined(OS_IOS)
-TEST_F(IdentityManagerTest, ForceTriggerOnCookieChange) {
-  base::RunLoop run_loop;
-  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
-      run_loop.QuitClosure());
-
-  SetListAccountsResponseNoAccounts(test_url_loader_factory());
-  // Forces the processing of OnCookieChange and it calls
-  // OnGaiaAccountsInCookieUpdated.
-  identity_manager()->ForceTriggerOnCookieChange();
-  run_loop.Run();
-}
-#endif
-
 #if defined(OS_CHROMEOS)
 // On ChromeOS, AccountTrackerService first receives the normalized email
 // address from GAIA and then later has it updated with the user's
diff --git a/components/sync/base/bind_to_task_runner_unittest.cc b/components/sync/base/bind_to_task_runner_unittest.cc
index 5c1ca4ecc..a548957 100644
--- a/components/sync/base/bind_to_task_runner_unittest.cc
+++ b/components/sync/base/bind_to_task_runner_unittest.cc
@@ -47,7 +47,7 @@
 // on the message loop, not during the original Run.
 class BindToTaskRunnerTest : public ::testing::Test {
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(BindToTaskRunnerTest, Closure) {
diff --git a/components/sync/base/cancelation_signal_unittest.cc b/components/sync/base/cancelation_signal_unittest.cc
index 94e9bee..b41e364 100644
--- a/components/sync/base/cancelation_signal_unittest.cc
+++ b/components/sync/base/cancelation_signal_unittest.cc
@@ -112,7 +112,7 @@
   bool VerifyTaskNotStarted();
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   CancelationSignal signal_;
   base::WaitableEvent task_start_event_;
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc
index 3b6bb1c..573c971d 100644
--- a/components/sync/base/sync_prefs_unittest.cc
+++ b/components/sync/base/sync_prefs_unittest.cc
@@ -48,7 +48,7 @@
     pref_service_.Set(prefs::kSyncDemographics, dict);
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   std::unique_ptr<SyncPrefs> sync_prefs_;
 };
@@ -292,7 +292,7 @@
     SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
 };
 
diff --git a/components/sync/base/weak_handle_unittest.cc b/components/sync/base/weak_handle_unittest.cc
index 8d9b545..5e46dc3 100644
--- a/components/sync/base/weak_handle_unittest.cc
+++ b/components/sync/base/weak_handle_unittest.cc
@@ -63,7 +63,7 @@
     h.Call(from_here, &Base::Test);
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(WeakHandleTest, Uninitialized) {
diff --git a/components/sync/driver/async_directory_type_controller_unittest.cc b/components/sync/driver/async_directory_type_controller_unittest.cc
index 5d31d6e5..016a237 100644
--- a/components/sync/driver/async_directory_type_controller_unittest.cc
+++ b/components/sync/driver/async_directory_type_controller_unittest.cc
@@ -175,7 +175,8 @@
 class SyncAsyncDirectoryTypeControllerTest : public testing::Test {
  public:
   SyncAsyncDirectoryTypeControllerTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI),
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI),
         backend_thread_("dbthread") {}
 
   void SetUp() override {
@@ -249,7 +250,7 @@
 
   static void SignalDone(WaitableEvent* done) { done->Signal(); }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::Thread backend_thread_;
 
   StartCallbackMock start_callback_;
diff --git a/components/sync/driver/backend_migrator_unittest.cc b/components/sync/driver/backend_migrator_unittest.cc
index 31cbf06..393050bf 100644
--- a/components/sync/driver/backend_migrator_unittest.cc
+++ b/components/sync/driver/backend_migrator_unittest.cc
@@ -87,7 +87,7 @@
   BackendMigrator* migrator() { return migrator_.get(); }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   ModelTypeSet preferred_types_;
   NiceMock<DataTypeManagerMock> manager_;
   NiceMock<base::MockCallback<base::RepeatingClosure>> reconfigure_callback_;
diff --git a/components/sync/driver/data_type_manager_impl_unittest.cc b/components/sync/driver/data_type_manager_impl_unittest.cc
index fa33a6e3..9f521fec 100644
--- a/components/sync/driver/data_type_manager_impl_unittest.cc
+++ b/components/sync/driver/data_type_manager_impl_unittest.cc
@@ -331,8 +331,8 @@
     return configurer_.last_params();
   }
 
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::MainThreadType::UI};
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
   DataTypeController::TypeMap controllers_;
   FakeModelTypeConfigurer configurer_;
   FakeDataTypeManagerObserver observer_;
diff --git a/components/sync/driver/frontend_data_type_controller_unittest.cc b/components/sync/driver/frontend_data_type_controller_unittest.cc
index 32af354..6c67311 100644
--- a/components/sync/driver/frontend_data_type_controller_unittest.cc
+++ b/components/sync/driver/frontend_data_type_controller_unittest.cc
@@ -138,7 +138,7 @@
 
   void PumpLoop() { base::RunLoop().RunUntilIdle(); }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   ModelAssociatorMock* model_associator_;
   ChangeProcessorMock* change_processor_;
   std::unique_ptr<ModelAssociatorMock> model_associator_deleter_;
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc
index 4803e29..fc397ea 100644
--- a/components/sync/driver/generic_change_processor_unittest.cc
+++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -39,7 +39,8 @@
   static const ModelType kType = PREFERENCES;
 
   SyncGenericChangeProcessorTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI),
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI),
         syncable_service_ptr_factory_(&fake_syncable_service_) {}
 
   void SetUp() override {
@@ -100,7 +101,7 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   std::unique_ptr<SyncMergeResult> sync_merge_result_;
   std::unique_ptr<base::WeakPtrFactory<SyncMergeResult>>
diff --git a/components/sync/driver/model_association_manager_unittest.cc b/components/sync/driver/model_association_manager_unittest.cc
index 74a790a..f845304 100644
--- a/components/sync/driver/model_association_manager_unittest.cc
+++ b/components/sync/driver/model_association_manager_unittest.cc
@@ -54,8 +54,8 @@
   SyncModelAssociationManagerTest() {}
 
  protected:
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::MainThreadType::UI};
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
   MockModelAssociationManagerDelegate delegate_;
   DataTypeController::TypeMap controllers_;
 };
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc
index e32f5c3..53c6f96 100644
--- a/components/sync/driver/model_type_controller_unittest.cc
+++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -224,7 +224,7 @@
   TestModelTypeController* controller() { return &controller_; }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   NiceMock<MockDelegate> mock_delegate_;
   TestModelTypeConfigurer configurer_;
   TestModelTypeProcessor processor_;
@@ -558,7 +558,7 @@
 // Tests that StorageOption is honored when the controller has been constructed
 // with two delegates.
 TEST(ModelTypeControllerWithMultiDelegateTest, ToggleStorageOption) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   NiceMock<MockDelegate> delegate_on_disk;
   NiceMock<MockDelegate> delegate_in_memory;
 
diff --git a/components/sync/driver/shared_change_processor_unittest.cc b/components/sync/driver/shared_change_processor_unittest.cc
index 859a3d5..c50acf4e 100644
--- a/components/sync/driver/shared_change_processor_unittest.cc
+++ b/components/sync/driver/shared_change_processor_unittest.cc
@@ -119,7 +119,7 @@
     did_connect_ = true;
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::Thread model_thread_;
   TestUserShare test_user_share_;
 
diff --git a/components/sync/driver/startup_controller_unittest.cc b/components/sync/driver/startup_controller_unittest.cc
index 4e8cc3e..44d698b4 100644
--- a/components/sync/driver/startup_controller_unittest.cc
+++ b/components/sync/driver/startup_controller_unittest.cc
@@ -68,7 +68,7 @@
   ModelTypeSet preferred_types_;
   bool should_start_;
   bool started_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<StartupController> controller_;
 };
 
diff --git a/components/sync/driver/sync_stopped_reporter_unittest.cc b/components/sync/driver/sync_stopped_reporter_unittest.cc
index 675d3b43..22dfc69 100644
--- a/components/sync/driver/sync_stopped_reporter_unittest.cc
+++ b/components/sync/driver/sync_stopped_reporter_unittest.cc
@@ -75,7 +75,7 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   SyncStoppedReporter::Result request_result_;
diff --git a/components/sync/engine/sync_backend_registrar_unittest.cc b/components/sync/engine/sync_backend_registrar_unittest.cc
index 8276971d..c1c1083c 100644
--- a/components/sync/engine/sync_backend_registrar_unittest.cc
+++ b/components/sync/engine/sync_backend_registrar_unittest.cc
@@ -93,7 +93,7 @@
     }
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::Thread db_thread_;
   base::Thread sync_thread_;
 
diff --git a/components/sync/engine/ui_model_worker_unittest.cc b/components/sync/engine/ui_model_worker_unittest.cc
index 8dd7c50..12860b41 100644
--- a/components/sync/engine/ui_model_worker_unittest.cc
+++ b/components/sync/engine/ui_model_worker_unittest.cc
@@ -56,8 +56,8 @@
   }
 
  protected:
-  std::unique_ptr<base::test::TaskEnvironment> task_environment_ =
-      std::make_unique<base::test::TaskEnvironment>();
+  std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_ =
+      std::make_unique<base::test::SingleThreadTaskEnvironment>();
   base::Thread sync_thread_;
   scoped_refptr<UIModelWorker> worker_;
 };
diff --git a/components/sync/engine_impl/apply_control_data_updates_unittest.cc b/components/sync/engine_impl/apply_control_data_updates_unittest.cc
index 7a848f7..98e738ad 100644
--- a/components/sync/engine_impl/apply_control_data_updates_unittest.cc
+++ b/components/sync/engine_impl/apply_control_data_updates_unittest.cc
@@ -64,7 +64,7 @@
 
  private:
   // Needed for directory init.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
 
   DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest);
diff --git a/components/sync/engine_impl/directory_commit_contribution_unittest.cc b/components/sync/engine_impl/directory_commit_contribution_unittest.cc
index b7a9e41c..4b94217 100644
--- a/components/sync/engine_impl/directory_commit_contribution_unittest.cc
+++ b/components/sync/engine_impl/directory_commit_contribution_unittest.cc
@@ -93,7 +93,7 @@
 
  private:
   // Neeed to initialize the directory.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
 };
 
diff --git a/components/sync/engine_impl/directory_update_handler_unittest.cc b/components/sync/engine_impl/directory_update_handler_unittest.cc
index c5e9e86..6e5f1f4 100644
--- a/components/sync/engine_impl/directory_update_handler_unittest.cc
+++ b/components/sync/engine_impl/directory_update_handler_unittest.cc
@@ -89,7 +89,7 @@
 
  private:
   // Needed to initialize the directory.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
   scoped_refptr<FakeModelWorker> ui_worker_;
 };
@@ -547,7 +547,7 @@
 
  private:
   // Needed to initialize the directory.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
   std::unique_ptr<TestEntryFactory> entry_factory_;
 
diff --git a/components/sync/engine_impl/js_mutation_event_observer_unittest.cc b/components/sync/engine_impl/js_mutation_event_observer_unittest.cc
index bcadc33..d4be3d31 100644
--- a/components/sync/engine_impl/js_mutation_event_observer_unittest.cc
+++ b/components/sync/engine_impl/js_mutation_event_observer_unittest.cc
@@ -31,7 +31,7 @@
  private:
   // This must be destroyed after the member variables below in order
   // for WeakHandles to be destroyed properly.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  protected:
   StrictMock<MockJsEventHandler> mock_js_event_handler_;
diff --git a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
index be3fd1e..9afa1cfc 100644
--- a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
+++ b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
@@ -36,7 +36,7 @@
  private:
   // This must be destroyed after the member variables below in order
   // for WeakHandles to be destroyed properly.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  protected:
   StrictMock<MockJsEventHandler> mock_js_event_handler_;
diff --git a/components/sync/engine_impl/js_sync_manager_observer_unittest.cc b/components/sync/engine_impl/js_sync_manager_observer_unittest.cc
index 9b73eb32..a952c2c8 100644
--- a/components/sync/engine_impl/js_sync_manager_observer_unittest.cc
+++ b/components/sync/engine_impl/js_sync_manager_observer_unittest.cc
@@ -34,7 +34,7 @@
  private:
   // This must be destroyed after the member variables below in order
   // for WeakHandles to be destroyed properly.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  protected:
   StrictMock<MockJsEventHandler> mock_js_event_handler_;
diff --git a/components/sync/engine_impl/model_type_registry_unittest.cc b/components/sync/engine_impl/model_type_registry_unittest.cc
index 5ea3dbc..cae3201 100644
--- a/components/sync/engine_impl/model_type_registry_unittest.cc
+++ b/components/sync/engine_impl/model_type_registry_unittest.cc
@@ -101,7 +101,7 @@
     return test_user_share_.user_share()->directory.get();
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   TestUserShare test_user_share_;
   CancelationSignal cancelation_signal_;
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
index 3ee9eea..7ac4101 100644
--- a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
+++ b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
@@ -582,7 +582,7 @@
   std::unique_ptr<SyncEncryptionHandlerImpl> encryption_handler_;
   StrictMock<SyncEncryptionHandlerObserverMock> observer_;
   TestIdFactory ids_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::test::ScopedFeatureList feature_list_;
   base::RepeatingCallback<std::string()> fake_random_salt_generator_;
 };
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc
index f37be33..4e7efe4e 100644
--- a/components/sync/engine_impl/sync_manager_impl_unittest.cc
+++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -253,7 +253,7 @@
   Cryptographer* GetCryptographer(BaseTransaction* trans);
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestUserShare test_user_share_;
 };
 
@@ -1171,7 +1171,7 @@
 
  private:
   // Needed by |sync_manager_|.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   // Needed by |sync_manager_|.
   base::ScopedTempDir temp_dir_;
   // Sync Id's for the roots of the enabled datatypes.
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
index cef94549..f6cf843 100644
--- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
+++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -96,8 +96,9 @@
  public:
   SyncSchedulerImplTest()
       : task_environment_(
-            base::test::TaskEnvironment::ThreadPoolExecutionMode::ASYNC,
-            base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+            base::test::SingleThreadTaskEnvironment::ThreadPoolExecutionMode::
+                ASYNC,
+            base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
         syncer_(nullptr),
         delay_(nullptr) {}
 
@@ -303,7 +304,7 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
  private:
   static const base::TickClock* tick_clock_;
diff --git a/components/sync/engine_impl/syncer_proto_util_unittest.cc b/components/sync/engine_impl/syncer_proto_util_unittest.cc
index b526a23..98aa230 100644
--- a/components/sync/engine_impl/syncer_proto_util_unittest.cc
+++ b/components/sync/engine_impl/syncer_proto_util_unittest.cc
@@ -140,7 +140,7 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
   std::unique_ptr<SyncCycleContext> context_;
 };
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc
index 390659f4..bc688cf 100644
--- a/components/sync/engine_impl/syncer_unittest.cc
+++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -519,7 +519,7 @@
     ASSERT_FALSE(nudge_tracker_.IsGetUpdatesRequired(ProtocolTypes()));
   }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   // Some ids to aid tests. Only the root one's value is specific. The rest
   // are named for test clarity.
diff --git a/components/sync/engine_impl/syncer_util_unittest.cc b/components/sync/engine_impl/syncer_util_unittest.cc
index a7766be..97204bd 100644
--- a/components/sync/engine_impl/syncer_util_unittest.cc
+++ b/components/sync/engine_impl/syncer_util_unittest.cc
@@ -66,7 +66,7 @@
 
   sync_pb::SyncEntity update;
   UniquePosition test_position;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestDirectorySetterUpper dir_maker_;
   std::unique_ptr<TestEntryFactory> entry_factory_;
 };
diff --git a/components/sync/engine_impl/uss_migrator_unittest.cc b/components/sync/engine_impl/uss_migrator_unittest.cc
index 97e046e2..c22a177 100644
--- a/components/sync/engine_impl/uss_migrator_unittest.cc
+++ b/components/sync/engine_impl/uss_migrator_unittest.cc
@@ -103,7 +103,7 @@
  private:
   syncable::Directory* directory() { return user_share()->directory.get(); }
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   TestUserShare test_user_share_;
   CancelationSignal cancelation_signal_;
   std::unique_ptr<TestEntryFactory> entry_factory_;
diff --git a/components/sync/js/sync_js_controller_unittest.cc b/components/sync/js/sync_js_controller_unittest.cc
index e75739e2..995fc57 100644
--- a/components/sync/js/sync_js_controller_unittest.cc
+++ b/components/sync/js/sync_js_controller_unittest.cc
@@ -25,7 +25,7 @@
   void PumpLoop() { base::RunLoop().RunUntilIdle(); }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(SyncJsControllerTest, Events) {
diff --git a/components/sync/model/sync_change_unittest.cc b/components/sync/model/sync_change_unittest.cc
index e0e34ca8c..bfeddb6 100644
--- a/components/sync/model/sync_change_unittest.cc
+++ b/components/sync/model/sync_change_unittest.cc
@@ -23,7 +23,7 @@
 
 class SyncChangeTest : public testing::Test {
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(SyncChangeTest, LocalDelete) {
diff --git a/components/sync/model/sync_data_unittest.cc b/components/sync/model/sync_data_unittest.cc
index 9608fe3..91d1712 100644
--- a/components/sync/model/sync_data_unittest.cc
+++ b/components/sync/model/sync_data_unittest.cc
@@ -27,7 +27,7 @@
 class SyncDataTest : public testing::Test {
  protected:
   SyncDataTest() = default;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   sync_pb::EntitySpecifics specifics;
 };
 
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
index 8e15c68..830df01 100644
--- a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
+++ b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
@@ -373,7 +373,7 @@
 
   // This sets SequencedTaskRunnerHandle on the current thread, which the type
   // processor will pick up as the sync task runner.
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   // The current mock queue, which is owned by |type_processor()|.
   MockModelTypeWorker* worker_;
diff --git a/components/sync/model_impl/model_type_store_impl_unittest.cc b/components/sync/model_impl/model_type_store_impl_unittest.cc
index fbfdcee..588f3dbf 100644
--- a/components/sync/model_impl/model_type_store_impl_unittest.cc
+++ b/components/sync/model_impl/model_type_store_impl_unittest.cc
@@ -176,7 +176,7 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<ModelTypeStore> store_;
 };
 
@@ -322,7 +322,7 @@
 // Test that stores for different types that share the same backend don't
 // interfere with each other's records.
 TEST(ModelTypeStoreImplWithTwoStoreTest, TwoStoresWithSharedBackend) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
 
   std::unique_ptr<ModelTypeStore> store_1 =
       ModelTypeStoreTestUtil::CreateInMemoryStoreForTest(AUTOFILL);
@@ -361,7 +361,7 @@
 // Test that records that DeleteAllDataAndMetadata() does not delete data from
 // another store when the backend is shared.
 TEST(ModelTypeStoreImplWithTwoStoreTest, DeleteAllWithSharedBackend) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
 
   std::unique_ptr<ModelTypeStore> store_1 =
       ModelTypeStoreTestUtil::CreateInMemoryStoreForTest(AUTOFILL);
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
index dc371274..8f8b087 100644
--- a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
+++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -159,7 +159,7 @@
   const std::string kClientTagHash =
       GenerateSyncableHash(kModelType, kClientTag);
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockSyncableService> syncable_service_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
   base::MockCallback<ModelErrorHandler> mock_error_handler_;
@@ -526,7 +526,7 @@
      ShouldDropIfCommitted) {
   const std::string kClientTagHash = "clienttaghash1";
 
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   std::unique_ptr<ModelTypeStore> store =
       ModelTypeStoreTestUtil::CreateInMemoryStoreForTest();
   SyncableServiceBasedBridge::InMemoryStore in_memory_store;
@@ -561,7 +561,7 @@
      ShouldNotDropIfUnsynced) {
   const std::string kClientTagHash = "clienttaghash1";
 
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   std::unique_ptr<ModelTypeStore> store =
       ModelTypeStoreTestUtil::CreateInMemoryStoreForTest();
   SyncableServiceBasedBridge::InMemoryStore in_memory_store;
diff --git a/components/sync/syncable/directory_backing_store_unittest.cc b/components/sync/syncable/directory_backing_store_unittest.cc
index 0d181fb7..10850b5 100644
--- a/components/sync/syncable/directory_backing_store_unittest.cc
+++ b/components/sync/syncable/directory_backing_store_unittest.cc
@@ -115,7 +115,7 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::ScopedTempDir temp_dir_;
 };
 
diff --git a/components/sync/syncable/directory_unittest.h b/components/sync/syncable/directory_unittest.h
index baae1ca..e98d75cb 100644
--- a/components/sync/syncable/directory_unittest.h
+++ b/components/sync/syncable/directory_unittest.h
@@ -94,7 +94,7 @@
                      int64_t server_version,
                      bool is_del);
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<Directory> dir_;
   NullDirectoryChangeDelegate delegate_;
   FakeEncryptor encryptor_;
diff --git a/components/sync/syncable/syncable_unittest.cc b/components/sync/syncable/syncable_unittest.cc
index f4dfafcb..5f0fcb4e 100644
--- a/components/sync/syncable/syncable_unittest.cc
+++ b/components/sync/syncable/syncable_unittest.cc
@@ -135,7 +135,7 @@
 #define MAYBE_FailInitialWrite FailInitialWrite
 #endif
 TEST(OnDiskSyncableDirectory, MAYBE_FailInitialWrite) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   FakeEncryptor encryptor;
   TestUnrecoverableErrorHandler handler;
   base::ScopedTempDir temp_dir;
@@ -525,7 +525,7 @@
   void TearDown() override {}
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::ScopedTempDir temp_dir_;
   FakeEncryptor encryptor_;
   TestUnrecoverableErrorHandler handler_;
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc
index b4252dde..bde2bc72 100644
--- a/components/unified_consent/unified_consent_service_unittest.cc
+++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -89,7 +89,7 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   signin::IdentityTestEnvironment identity_test_environment_;
   TestSyncService sync_service_;
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
index e692286b..dc48d36 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -10,6 +10,7 @@
 #include "base/debug/crash_logging.h"
 #import "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
+#include "base/numerics/ranges.h"
 #include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #import "content/browser/accessibility/browser_accessibility_cocoa.h"
@@ -110,13 +111,13 @@
   CGFloat r, g, b, a;
   [color getRed:&r green:&g blue:&b alpha:&a];
 
-  return std::max(0, std::min(static_cast<int>(lroundf(255.0f * a)), 255))
+  return base::ClampToRange(static_cast<int>(lroundf(255.0f * a)), 0, 255)
              << 24 |
-         std::max(0, std::min(static_cast<int>(lroundf(255.0f * r)), 255))
+         base::ClampToRange(static_cast<int>(lroundf(255.0f * r)), 0, 255)
              << 16 |
-         std::max(0, std::min(static_cast<int>(lroundf(255.0f * g)), 255))
+         base::ClampToRange(static_cast<int>(lroundf(255.0f * g)), 0, 255)
              << 8 |
-         std::max(0, std::min(static_cast<int>(lroundf(255.0f * b)), 255));
+         base::ClampToRange(static_cast<int>(lroundf(255.0f * b)), 0, 255);
 }
 
 // Extract underline information from an attributed string. Mostly copied from
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index ff2a153..aaf91c5 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -6,6 +6,7 @@
 
 #include "base/i18n/break_iterator.h"
 #include "base/lazy_instance.h"
+#include "base/numerics/ranges.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -1243,22 +1244,22 @@
     case UP:
       if (y_initial == y_min)
         return false;
-      y = std::min(std::max(y_initial - page_y, y_min), y_max);
+      y = base::ClampToRange(y_initial - page_y, y_min, y_max);
       break;
     case DOWN:
       if (y_initial == y_max)
         return false;
-      y = std::min(std::max(y_initial + page_y, y_min), y_max);
+      y = base::ClampToRange(y_initial + page_y, y_min, y_max);
       break;
     case LEFT:
       if (x_initial == x_min)
         return false;
-      x = std::min(std::max(x_initial - page_x, x_min), x_max);
+      x = base::ClampToRange(x_initial - page_x, x_min, x_max);
       break;
     case RIGHT:
       if (x_initial == x_max)
         return false;
-      x = std::min(std::max(x_initial + page_x, x_min), x_max);
+      x = base::ClampToRange(x_initial + page_x, x_min, x_max);
       break;
     default:
       NOTREACHED();
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index 17277079..83ea3c4e 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -11,6 +11,7 @@
 #include "base/feature_list.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/numerics/ranges.h"
 #include "content/browser/accessibility/browser_accessibility_android.h"
 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
@@ -932,7 +933,7 @@
   // Slider does not move if the delta value is less than 1.
   delta = ((delta < 1) ? 1 : delta);
   value += (increment ? delta : -delta);
-  value = std::max(std::min(value, max), min);
+  value = base::ClampToRange(value, min, max);
   if (value != original_value) {
     node->manager()->SetValue(*node, base::NumberToString(value));
     return true;
diff --git a/content/browser/android/selection/composited_touch_handle_drawable.cc b/content/browser/android/selection/composited_touch_handle_drawable.cc
index 2fa5bb8..79d2ced 100644
--- a/content/browser/android/selection/composited_touch_handle_drawable.cc
+++ b/content/browser/android/selection/composited_touch_handle_drawable.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/numerics/ranges.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "content/public/browser/android/compositor.h"
 #include "ui/android/handle_view_resources.h"
@@ -84,10 +85,9 @@
 
 void CompositedTouchHandleDrawable::SetAlpha(float alpha) {
   DCHECK(layer_->parent());
-  alpha = std::max(0.f, std::min(1.f, alpha));
-  bool hidden = alpha <= 0;
+  alpha = base::ClampToRange(alpha, 0.0f, 1.0f);
   layer_->SetOpacity(alpha);
-  layer_->SetHideLayerAndSubtree(hidden);
+  layer_->SetHideLayerAndSubtree(!alpha);
 }
 
 gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index b6969d18..ff3b8270 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -432,6 +432,39 @@
   // deleted code in: https://crrev.com/c/1782902.
 }
 
+// Test documents are evicted from the BackForwardCache at some point.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
+                       CacheEvictionWithIncreasedCacheSize) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // The number of document the BackForwardCache can hold per tab.
+  static constexpr size_t kBackForwardCacheLimit = 5;
+  web_contents()
+      ->GetController()
+      .back_forward_cache()
+      .set_cache_size_limit_for_testing(kBackForwardCacheLimit);
+
+  const GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  const GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  EXPECT_TRUE(NavigateToURL(shell(), url_a));  // BackForwardCache size is 0.
+  RenderFrameHostImpl* rfh_a = current_frame_host();
+  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
+
+  EXPECT_TRUE(NavigateToURL(shell(), url_b));  // BackForwardCache size is 1.
+  RenderFrameHostImpl* rfh_b = current_frame_host();
+  RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
+
+  for (size_t i = 2; i < kBackForwardCacheLimit; ++i) {
+    EXPECT_TRUE(NavigateToURL(shell(), i % 2 ? url_b : url_a));
+    // After |i+1| navigations, |i| documents went into the BackForwardCache.
+    // When |i| is greater than the BackForwardCache size limit, they are
+    // evicted:
+    EXPECT_EQ(i >= kBackForwardCacheLimit + 1, delete_observer_rfh_a.deleted());
+    EXPECT_EQ(i >= kBackForwardCacheLimit + 2, delete_observer_rfh_b.deleted());
+  }
+}
+
 // Similar to BackForwardCacheBrowserTest.SubframeSurviveCache*
 // Test case: a1(b2) -> c3 -> a1(b2)
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, SubframeSurviveCache1) {
@@ -566,6 +599,70 @@
   EXPECT_FALSE(a4_observer.deleted());
 }
 
+// Similar to BackForwardCacheBrowserTest.SubframeSurviveCache*
+// Test case: a1(b2) -> b3 -> a4 -> b5 -> a1(b2).
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, SubframeSurviveCache4) {
+  // Increase the cache size so that a1(b2) is still in the cache when we
+  // reach b5.
+  web_contents()
+      ->GetController()
+      .back_forward_cache()
+      .set_cache_size_limit_for_testing(3);
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url_ab(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(b)"));
+  const GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  const GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  std::vector<RenderFrameDeletedObserver*> rfh_observer;
+
+  // 1) Navigate to a1(b2).
+  EXPECT_TRUE(NavigateToURL(shell(), url_ab));
+  RenderFrameHostImpl* a1 = current_frame_host();
+  RenderFrameHostImpl* b2 = a1->child_at(0)->current_frame_host();
+  RenderFrameDeletedObserver a1_observer(a1), b2_observer(b2);
+  rfh_observer.insert(rfh_observer.end(), {&a1_observer, &b2_observer});
+  EXPECT_TRUE(ExecJs(b2, "window.alive = 'I am alive';"));
+
+  // 2) Navigate to b3.
+  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+  RenderFrameHostImpl* b3 = current_frame_host();
+  RenderFrameDeletedObserver b3_observer(b3);
+  rfh_observer.push_back(&b3_observer);
+  ASSERT_THAT(rfh_observer, Each(Not(Deleted())));
+  EXPECT_THAT(Elements({a1, b2}), Each(InBackForwardCache()));
+  EXPECT_THAT(b3, Not(InBackForwardCache()));
+
+  // 3) Navigate to a4.
+  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  RenderFrameHostImpl* a4 = current_frame_host();
+  RenderFrameDeletedObserver a4_observer(a4);
+  rfh_observer.push_back(&a4_observer);
+  ASSERT_THAT(rfh_observer, Each(Not(Deleted())));
+
+  // 4) Navigate to b5
+  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+  RenderFrameHostImpl* b5 = current_frame_host();
+  RenderFrameDeletedObserver b5_observer(b5);
+  rfh_observer.push_back(&b5_observer);
+  ASSERT_THAT(rfh_observer, Each(Not(Deleted())));
+  EXPECT_THAT(Elements({a1, b2, b3, a4}), Each(InBackForwardCache()));
+  EXPECT_THAT(b5, Not(InBackForwardCache()));
+
+  // 3) Go back to a1(b2).
+  web_contents()->GetController().GoToOffset(-3);
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  EXPECT_EQ(a1, current_frame_host());
+  ASSERT_THAT(rfh_observer, Each(Not(Deleted())));
+  EXPECT_THAT(Elements({b3, a4, b5}), Each(InBackForwardCache()));
+  EXPECT_THAT(Elements({a1, b2}), Each(Not(InBackForwardCache())));
+
+  // Even after a new IPC round trip with the renderer, b2 must still be alive.
+  EXPECT_EQ("I am alive", EvalJs(b2, "window.alive"));
+  EXPECT_FALSE(b2_observer.deleted());
+}
+
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                        NavigationsAreFullyCommitted) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index 9a66036..74b9007 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -13,6 +13,11 @@
 #include "content/browser/worker_host/shared_worker_host.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/shared_worker_instance.h"
+#include "third_party/blink/public/mojom/appcache/appcache.mojom.h"
+#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
+#include "third_party/blink/public/mojom/idle/idle_manager.mojom.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom.h"
 #include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h"
 #include "third_party/blink/public/mojom/webaudio/audio_context_manager.mojom.h"
 
@@ -34,6 +39,9 @@
   map->Add<blink::mojom::IdleManager>(base::BindRepeating(
       &RenderFrameHostImpl::GetIdleManager, base::Unretained(host)));
 
+  map->Add<blink::mojom::PresentationService>(base::BindRepeating(
+      &RenderFrameHostImpl::GetPresentationService, base::Unretained(host)));
+
   map->Add<blink::mojom::SpeechSynthesis>(base::BindRepeating(
       &RenderFrameHostImpl::GetSpeechSynthesis, base::Unretained(host)));
 
diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc
index 74d2dff..c1a2731 100644
--- a/content/browser/fileapi/file_system_browsertest.cc
+++ b/content/browser/fileapi/file_system_browsertest.cc
@@ -23,7 +23,6 @@
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/quota/quota_manager.h"
 
 using storage::QuotaManager;
@@ -37,8 +36,6 @@
  public:
   FileSystemBrowserTest() {
     is_incognito_ = GetParam();
-    feature_list_.InitAndEnableFeature(
-        storage::features::kEnableFilesystemInIncognito);
   }
 
   void SimpleTest(const GURL& test_url) {
diff --git a/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc b/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
index 5ab183bb..c7eb48d 100644
--- a/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
+++ b/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
@@ -16,7 +16,6 @@
 #include "base/rand_util.h"
 #include "base/task/post_task.h"
 #include "base/test/bind_test_util.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "content/browser/fileapi/file_system_url_loader_factory.h"
 #include "content/browser/web_contents/web_contents_impl.h"
@@ -34,7 +33,6 @@
 #include "services/network/test/test_url_loader_client.h"
 #include "storage/browser/fileapi/external_mount_points.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_file_util.h"
 #include "storage/browser/fileapi/file_system_operation_context.h"
 #include "storage/browser/fileapi/file_system_operation_runner.h"
@@ -58,7 +56,7 @@
 namespace content {
 namespace {
 
-enum class TestMode { kRegular, kIncognito, kRegularWithIncognitoEnabled };
+enum class TestMode { kRegular, kIncognito };
 
 // We always use the TEMPORARY FileSystem in these tests.
 const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/";
@@ -161,21 +159,9 @@
     : public ContentBrowserTest,
       public ::testing::WithParamInterface<TestMode> {
  protected:
-  FileSystemURLLoaderFactoryTest() : file_util_(nullptr) {
-    std::vector<base::Feature> features;
-    if (GetParam() == TestMode::kIncognito ||
-        GetParam() == TestMode::kRegularWithIncognitoEnabled) {
-      features.push_back(storage::features::kEnableFilesystemInIncognito);
-    }
-    feature_list_.InitWithFeatures(features, std::vector<base::Feature>());
-  }
+  FileSystemURLLoaderFactoryTest() : file_util_(nullptr) {}
   ~FileSystemURLLoaderFactoryTest() override = default;
 
-  bool IsInMemoryFileSystemEnabled() {
-    return base::FeatureList::IsEnabled(
-        storage::features::kEnableFilesystemInIncognito);
-  }
-
   bool IsIncognito() { return GetParam() == TestMode::kIncognito; }
 
   void SetUpOnMainThread() override {
@@ -483,7 +469,6 @@
     return client;
   }
 
-  base::test::ScopedFeatureList feature_list_;
   scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
@@ -494,12 +479,10 @@
   DISALLOW_COPY_AND_ASSIGN(FileSystemURLLoaderFactoryTest);
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    ,
-    FileSystemURLLoaderFactoryTest,
-    testing::Values(TestMode::kRegular,
-                    TestMode::kIncognito,
-                    TestMode::kRegularWithIncognitoEnabled));
+INSTANTIATE_TEST_SUITE_P(,
+                         FileSystemURLLoaderFactoryTest,
+                         testing::Values(TestMode::kRegular,
+                                         TestMode::kIncognito));
 
 IN_PROC_BROWSER_TEST_P(FileSystemURLLoaderFactoryTest, DirectoryListing) {
   base::ScopedAllowBlockingForTesting allow_blocking;
@@ -592,30 +575,11 @@
 
   auto client =
       TestLoadWithContext(CreateFileSystemURL("/"), file_system_context.get());
-  if (IsInMemoryFileSystemEnabled()) {
-    // When in-memory file system is enabled, the request fails as the requested
-    // directory does not exist in in-memory obfuscated file system.
-    ASSERT_FALSE(client->has_received_response());
-    ASSERT_TRUE(client->has_received_completion());
-    EXPECT_EQ(net::ERR_FILE_NOT_FOUND, client->completion_status().error_code);
-  } else {
-    ASSERT_TRUE(client->has_received_response());
-    ASSERT_TRUE(client->has_received_completion());
-
-    std::string response_text = ReadDataPipe(client->response_body_release());
-    EXPECT_GT(response_text.size(), 0ul);
-
-    std::istringstream in(response_text);
-
-    int num_entries = 0;
-    std::string line;
-    while (!!std::getline(in, line)) {
-      if (IsDirectoryListingLine(line))
-        num_entries++;
-    }
-
-    EXPECT_EQ(0, num_entries);
-  }
+  // The request fails as the requested directory does not exist in in-memory
+  // obfuscated file system.
+  ASSERT_FALSE(client->has_received_response());
+  ASSERT_TRUE(client->has_received_completion());
+  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, client->completion_status().error_code);
 
   client = TestLoadWithContext(CreateFileSystemURL("foo"),
                                file_system_context.get());
diff --git a/content/browser/frame_host/back_forward_cache.cc b/content/browser/frame_host/back_forward_cache.cc
index b9974fa..78bbfb6 100644
--- a/content/browser/frame_host/back_forward_cache.cc
+++ b/content/browser/frame_host/back_forward_cache.cc
@@ -174,9 +174,13 @@
   rfh->EnterBackForwardCache();
   render_frame_hosts_.push_front(std::move(rfh));
 
+  size_t size_limit = cache_size_limit_for_testing_
+                          ? cache_size_limit_for_testing_
+                          : kBackForwardCacheLimit;
+
   // Remove the last recently used document if the BackForwardCache list is
   // full.
-  if (render_frame_hosts_.size() > kBackForwardCacheLimit) {
+  if (render_frame_hosts_.size() > size_limit) {
     // TODO(arthursonzogni): Handle RenderFrame deletion appropriately.
     render_frame_hosts_.pop_back();
   }
diff --git a/content/browser/frame_host/back_forward_cache.h b/content/browser/frame_host/back_forward_cache.h
index 5ce3d407..22b7452 100644
--- a/content/browser/frame_host/back_forward_cache.h
+++ b/content/browser/frame_host/back_forward_cache.h
@@ -114,6 +114,14 @@
   // (BackForwardCache enabled), and one without.
   void DisableForTesting(DisableForTestingReason reason);
 
+  // Sets the number of documents that can be stored in the cache. This is meant
+  // for use from within tests only.
+  // If |cache_size_limit_for_testing| is 0 (the default), the normal cache
+  // size limit will be used.
+  void set_cache_size_limit_for_testing(size_t cache_size_limit_for_testing) {
+    cache_size_limit_for_testing_ = cache_size_limit_for_testing;
+  }
+
  private:
   // Contains the set of stored RenderFrameHost.
   // Invariant:
@@ -121,9 +129,14 @@
   // - Once the list is full, the least recently used document is evicted.
   std::list<std::unique_ptr<RenderFrameHostImpl>> render_frame_hosts_;
 
-  // Whether the BackforwardCached has been disabled for testing.
+  // Only used in tests. Whether the BackforwardCached has been disabled for
+  // testing.
   bool is_disabled_for_testing_ = false;
 
+  // Only used in tests. If non-zero, this value will be used as the cache size
+  // limit.
+  size_t cache_size_limit_for_testing_ = 0;
+
   DISALLOW_COPY_AND_ASSIGN(BackForwardCache);
 };
 
diff --git a/content/browser/frame_host/frame_service_base_unittest.cc b/content/browser/frame_host/frame_service_base_unittest.cc
index dc1dcac8..49829e0 100644
--- a/content/browser/frame_host/frame_service_base_unittest.cc
+++ b/content/browser/frame_host/frame_service_base_unittest.cc
@@ -12,6 +12,8 @@
 #include "content/public/test/test_renderer_host.h"
 #include "content/test/echo.mojom.h"
 #include "content/test/test_render_frame_host.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "url/gurl.h"
 
 // Unit test for FrameServiceBase in content/public/browser.
@@ -27,9 +29,9 @@
 class EchoImpl final : public FrameServiceBase<mojom::Echo> {
  public:
   EchoImpl(RenderFrameHost* render_frame_host,
-           mojo::InterfaceRequest<mojom::Echo> request,
+           mojo::PendingReceiver<mojom::Echo> receiver,
            base::OnceClosure destruction_cb)
-      : FrameServiceBase(render_frame_host, std::move(request)),
+      : FrameServiceBase(render_frame_host, std::move(receiver)),
         destruction_cb_(std::move(destruction_cb)) {}
   ~EchoImpl() final { std::move(destruction_cb_).Run(); }
 
@@ -79,7 +81,7 @@
 
   void CreateEchoImpl(RenderFrameHost* rfh) {
     DCHECK(!is_echo_impl_alive_);
-    new EchoImpl(rfh, mojo::MakeRequest(&echo_ptr_),
+    new EchoImpl(rfh, echo_remote_.BindNewPipeAndPassReceiver(),
                  base::BindOnce(&FrameServiceBaseTest::OnEchoImplDestructed,
                                 base::Unretained(this)));
     is_echo_impl_alive_ = true;
@@ -91,12 +93,12 @@
   }
 
   void ResetConnection() {
-    echo_ptr_.reset();
+    echo_remote_.reset();
     base::RunLoop().RunUntilIdle();
   }
 
   RenderFrameHost* main_rfh_ = nullptr;
-  mojom::EchoPtr echo_ptr_;
+  mojo::Remote<mojom::Echo> echo_remote_;
   bool is_echo_impl_alive_ = false;
 };
 
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index d6e241a..656561d 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -4077,7 +4077,7 @@
   process()->sink().ClearMessages();
 
   // Simulate the page calling history.back(). It should create a pending entry.
-  contents()->OnGoToEntryAtOffset(main_test_rfh(), -1, false, true);
+  contents()->OnGoToEntryAtOffset(main_test_rfh(), -1, false);
   EXPECT_EQ(0, controller.GetPendingEntryIndex());
 
   // Also make sure we told the page to navigate.
@@ -4087,7 +4087,7 @@
   process()->sink().ClearMessages();
 
   // Now test history.forward()
-  contents()->OnGoToEntryAtOffset(main_test_rfh(), 2, false, true);
+  contents()->OnGoToEntryAtOffset(main_test_rfh(), 2, false);
   EXPECT_EQ(2, controller.GetPendingEntryIndex());
 
   nav_url = GetLastNavigationURL();
@@ -4098,8 +4098,8 @@
   controller.DiscardNonCommittedEntries();
 
   // Make sure an extravagant history.go() doesn't break.
-  contents()->OnGoToEntryAtOffset(main_test_rfh(), 120, false,
-                                  true);  // Out of bounds.
+  contents()->OnGoToEntryAtOffset(main_test_rfh(), 120,
+                                  false);  // Out of bounds.
   EXPECT_EQ(-1, controller.GetPendingEntryIndex());
   EXPECT_FALSE(HasNavigationRequest());
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 8d9bb40..4d1c3fd 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4312,16 +4312,6 @@
       base::BindRepeating(&PermissionServiceContext::CreateService,
                           base::Unretained(permission_service_context_.get())));
 
-  registry_->AddInterface(base::BindRepeating(
-      [](RenderFrameHostImpl* frame,
-         mojo::PendingReceiver<blink::mojom::PresentationService> receiver) {
-        if (!frame->presentation_service_)
-          frame->presentation_service_ = PresentationServiceImpl::Create(frame);
-
-        frame->presentation_service_->Bind(std::move(receiver));
-      },
-      base::Unretained(this)));
-
   registry_->AddInterface(
       base::Bind(&MediaSessionServiceImpl::Create, base::Unretained(this)));
 
@@ -6345,6 +6335,13 @@
       ->CreateService(std::move(receiver));
 }
 
+void RenderFrameHostImpl::GetPresentationService(
+    mojo::PendingReceiver<blink::mojom::PresentationService> receiver) {
+  if (!presentation_service_)
+    presentation_service_ = PresentationServiceImpl::Create(this);
+  presentation_service_->Bind(std::move(receiver));
+}
+
 void RenderFrameHostImpl::GetSpeechSynthesis(
     mojo::PendingReceiver<blink::mojom::SpeechSynthesis> receiver) {
   if (!speech_synthesis_impl_) {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index fb5221a6..adbdb61 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1031,6 +1031,9 @@
   void GetIdleManager(
       mojo::PendingReceiver<blink::mojom::IdleManager> receiver);
 
+  void GetPresentationService(
+      mojo::PendingReceiver<blink::mojom::PresentationService> receiver);
+
   void GetSpeechSynthesis(
       mojo::PendingReceiver<blink::mojom::SpeechSynthesis> receiver);
 
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 8ecb551..d38084e3 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -23,6 +23,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
+#include "base/numerics/ranges.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
@@ -746,7 +747,7 @@
         // Windows always returns PROCESS_CRASHED on abnormal termination, as it
         // doesn't have a way to distinguish the two.
         base::UmaHistogramSparse("GPU.GPUProcessExitCode",
-                                 std::max(0, std::min(100, info.exit_code)));
+                                 base::ClampToRange(info.exit_code, 0, 100));
       }
 
       message = "The GPU process ";
diff --git a/content/browser/media/capture/lame_capture_overlay_chromeos.cc b/content/browser/media/capture/lame_capture_overlay_chromeos.cc
index d15ff3a..a9058787 100644
--- a/content/browser/media/capture/lame_capture_overlay_chromeos.cc
+++ b/content/browser/media/capture/lame_capture_overlay_chromeos.cc
@@ -8,6 +8,7 @@
 #include <cmath>
 
 #include "base/bind.h"
+#include "base/numerics/ranges.h"
 #include "base/numerics/safe_conversions.h"
 #include "content/browser/media/capture/lame_window_capturer_chromeos.h"
 #include "media/base/video_frame.h"
@@ -81,12 +82,9 @@
                    std::max(0, snapped_bottom - snapped_top));
 }
 
-inline int clip_byte(int x) {
-  return std::max(0, std::min(x, 255));
-}
-
 inline int alpha_blend(int alpha, int src, int dst) {
-  return (src * alpha + dst * (255 - alpha)) / 255;
+  alpha = (src * alpha + dst * (255 - alpha)) / 255;
+  return base::ClampToRange(alpha, 0, 255);
 }
 
 }  // namespace
@@ -155,7 +153,7 @@
             const int color_b = SkColorGetB(color);
             const int color_y =
                 ((color_r * 66 + color_g * 129 + color_b * 25 + 128) >> 8) + 16;
-            yplane[x] = clip_byte(alpha_blend(alpha, color_y, yplane[x]));
+            yplane[x] = alpha_blend(alpha, color_y, yplane[x]);
 
             // Only sample U and V at even coordinates.
             if ((x % 2 == 0) && (y % 2 == 0)) {
@@ -165,10 +163,8 @@
               const int color_v =
                   ((color_r * 112 + color_g * -94 + color_b * -18 + 128) >> 8) +
                   128;
-              uplane[x / 2] =
-                  clip_byte(alpha_blend(alpha, color_u, uplane[x / 2]));
-              vplane[x / 2] =
-                  clip_byte(alpha_blend(alpha, color_v, vplane[x / 2]));
+              uplane[x / 2] = alpha_blend(alpha, color_u, uplane[x / 2]);
+              vplane[x / 2] = alpha_blend(alpha, color_v, vplane[x / 2]);
             }
           }
         }
diff --git a/content/browser/renderer_host/overscroll_controller.cc b/content/browser/renderer_host/overscroll_controller.cc
index f8b5aae..95a0dd7a 100644
--- a/content/browser/renderer_host/overscroll_controller.cc
+++ b/content/browser/renderer_host/overscroll_controller.cc
@@ -8,6 +8,7 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/numerics/ranges.h"
 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
 #include "content/public/browser/overscroll_configuration.h"
 #include "content/public/common/content_features.h"
@@ -45,7 +46,7 @@
 
 float ClampAbsoluteValue(float value, float max_abs) {
   DCHECK_LT(0.f, max_abs);
-  return std::max(-max_abs, std::min(value, max_abs));
+  return base::ClampToRange(value, -max_abs, max_abs);
 }
 
 }  // namespace
diff --git a/content/browser/speech/speech_recognizer_impl.cc b/content/browser/speech/speech_recognizer_impl.cc
index ac501d6..a364a382 100644
--- a/content/browser/speech/speech_recognizer_impl.cc
+++ b/content/browser/speech/speech_recognizer_impl.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
+#include "base/numerics/ranges.h"
 #include "base/task/post_task.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -847,15 +848,15 @@
   // Perhaps it might be quite expensive on mobile.
   float level = (rms - kAudioMeterMinDb) /
       (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped);
-  level = std::min(std::max(0.0f, level), kAudioMeterRangeMaxUnclipped);
+  level = base::ClampToRange(level, 0.0f, kAudioMeterRangeMaxUnclipped);
   const float smoothing_factor = (level > audio_level_) ? kUpSmoothingFactor :
                                                           kDownSmoothingFactor;
   audio_level_ += (level - audio_level_) * smoothing_factor;
 
   float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) /
       (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped);
-  noise_level = std::min(std::max(0.0f, noise_level),
-                         kAudioMeterRangeMaxUnclipped);
+  noise_level =
+      base::ClampToRange(noise_level, 0.0f, kAudioMeterRangeMaxUnclipped);
 
   listener()->OnAudioLevelsChange(
       session_id(), clip_detected ? 1.0f : audio_level_, noise_level);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 6ab3420..f921389 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4837,8 +4837,7 @@
 
 void WebContentsImpl::OnGoToEntryAtOffset(RenderFrameHostImpl* source,
                                           int offset,
-                                          bool has_user_gesture,
-                                          bool from_script) {
+                                          bool has_user_gesture) {
   // Non-user initiated navigations coming from the renderer should be ignored
   // if there is an ongoing browser-initiated navigation.
   // See https://crbug.com/879965.
@@ -4856,11 +4855,7 @@
 
   // All frames are allowed to navigate the global history.
   if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) {
-    // We only check sandboxed navigation permissions on navigations originating
-    // from scripts, and not mouse back buttons (from_script == false), which
-    // also use this path.
-    if (from_script &&
-        source->IsSandboxed(blink::WebSandboxFlags::kTopNavigation)) {
+    if (source->IsSandboxed(blink::WebSandboxFlags::kTopNavigation)) {
       // Keep track of whether this is a session history from a sandboxed iframe
       // with top level navigation disallowed.
       controller_.GoToOffsetInSandboxedFrame(offset,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 3121f105..a304b7e 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1290,8 +1290,7 @@
   void OnDidFinishLoad(RenderFrameHostImpl* source, const GURL& url);
   void OnGoToEntryAtOffset(RenderFrameHostImpl* source,
                            int offset,
-                           bool has_user_gesture,
-                           bool from_script);
+                           bool has_user_gesture);
   void OnUpdateZoomLimits(RenderViewHostImpl* source,
                           int minimum_percent,
                           int maximum_percent);
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index 5897b6a..51fab5f 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -327,10 +327,11 @@
 
 std::vector<device::CableDiscoveryData> GetTestCableExtension() {
   device::CableDiscoveryData cable;
-  cable.version = 1;
-  cable.client_eid.fill(0x01);
-  cable.authenticator_eid.fill(0x02);
-  cable.session_pre_key.fill(0x03);
+  cable.version = device::CableDiscoveryData::Version::V1;
+  cable.v1.emplace();
+  cable.v1->client_eid.fill(0x01);
+  cable.v1->authenticator_eid.fill(0x02);
+  cable.v1->session_pre_key.fill(0x03);
 
   std::vector<device::CableDiscoveryData> ret;
   ret.emplace_back(std::move(cable));
diff --git a/content/browser/webauth/authenticator_mojom_traits.cc b/content/browser/webauth/authenticator_mojom_traits.cc
index 34d3eb2..2478eb0 100644
--- a/content/browser/webauth/authenticator_mojom_traits.cc
+++ b/content/browser/webauth/authenticator_mojom_traits.cc
@@ -236,10 +236,14 @@
                   device::CableDiscoveryData>::
     Read(blink::mojom::CableAuthenticationDataView data,
          device::CableDiscoveryData* out) {
-  out->version = data.version();
-  if (!data.ReadClientEid(&out->client_eid) ||
-      !data.ReadAuthenticatorEid(&out->authenticator_eid) ||
-      !data.ReadSessionPreKey(&out->session_pre_key)) {
+  if (data.version() != 1) {
+    return false;
+  }
+  out->version = device::CableDiscoveryData::Version::V1;
+  out->v1.emplace();
+  if (!data.ReadClientEid(&out->v1->client_eid) ||
+      !data.ReadAuthenticatorEid(&out->v1->authenticator_eid) ||
+      !data.ReadSessionPreKey(&out->v1->session_pre_key)) {
     return false;
   }
   return true;
diff --git a/content/browser/webauth/authenticator_mojom_traits.h b/content/browser/webauth/authenticator_mojom_traits.h
index 659a7d2..836793f 100644
--- a/content/browser/webauth/authenticator_mojom_traits.h
+++ b/content/browser/webauth/authenticator_mojom_traits.h
@@ -186,22 +186,26 @@
     StructTraits<blink::mojom::CableAuthenticationDataView,
                  device::CableDiscoveryData> {
   static uint8_t version(const device::CableDiscoveryData& in) {
-    return in.version;
+    CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version);
+    return 1;
   }
 
   static const device::CableEidArray& client_eid(
       const device::CableDiscoveryData& in) {
-    return in.client_eid;
+    CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version);
+    return in.v1->client_eid;
   }
 
   static const device::CableEidArray& authenticator_eid(
       const device::CableDiscoveryData& in) {
-    return in.authenticator_eid;
+    CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version);
+    return in.v1->authenticator_eid;
   }
 
   static const device::CableSessionPreKeyArray& session_pre_key(
       const device::CableDiscoveryData& in) {
-    return in.session_pre_key;
+    CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version);
+    return in.v1->session_pre_key;
   }
 
   static bool Read(blink::mojom::CableAuthenticationDataView data,
diff --git a/content/browser/webauth/authenticator_mojom_traits_unittest.cc b/content/browser/webauth/authenticator_mojom_traits_unittest.cc
index 5e1fd973..53ffaf0 100644
--- a/content/browser/webauth/authenticator_mojom_traits_unittest.cc
+++ b/content/browser/webauth/authenticator_mojom_traits_unittest.cc
@@ -159,7 +159,8 @@
 // Verify serialization and deserialization of CableDiscoveryData.
 TEST(AuthenticatorMojomTraitsTest, SerializeCableDiscoveryData) {
   std::vector<CableDiscoveryData> success_cases = {
-      CableDiscoveryData(0, kClientEid, kAuthenticatorEid, kSessionPreKey)};
+      CableDiscoveryData(CableDiscoveryData::Version::V1, kClientEid,
+                         kAuthenticatorEid, kSessionPreKey)};
 
   AssertSerializeAndDeserializeSucceeds<blink::mojom::CableAuthentication,
                                         CableDiscoveryData>(success_cases);
diff --git a/content/browser/webauth/webauth_browsertest.cc b/content/browser/webauth/webauth_browsertest.cc
index db63dfb..1eb181d 100644
--- a/content/browser/webauth/webauth_browsertest.cc
+++ b/content/browser/webauth/webauth_browsertest.cc
@@ -1264,6 +1264,42 @@
   }
 }
 
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+                       BadCableExtensionVersions) {
+  // The caBLE extension should only contain v1 data. Test that nothing crashes
+  // if a site tries to set other versions.
+
+  InjectVirtualFidoDeviceFactory();
+  GetParameters parameters;
+  parameters.allow_credentials =
+      "allowCredentials: [{ type: 'public-key',"
+      "  id: new TextEncoder().encode('allowedCredential'),"
+      "  transports: ['cable']}],"
+      "extensions: {"
+      "  cableAuthentication: [{"
+      "    version: 1,"
+      "    clientEid: new Uint8Array(Array(16).fill(1)),"
+      "    authenticatorEid: new Uint8Array(Array(16).fill(2)),"
+      "    sessionPreKey: new Uint8Array(Array(32).fill(3)),"
+      "  },{"
+      "    version: 2,"
+      "    clientEid: new Uint8Array(Array(16).fill(1)),"
+      "    authenticatorEid: new Uint8Array(Array(16).fill(2)),"
+      "    sessionPreKey: new Uint8Array(Array(32).fill(3)),"
+      "  },{"
+      "    version: 3,"
+      "    clientEid: new Uint8Array(Array(16).fill(1)),"
+      "    authenticatorEid: new Uint8Array(Array(16).fill(2)),"
+      "    sessionPreKey: new Uint8Array(Array(32).fill(3)),"
+      "  }]"
+      "}";
+  std::string result;
+  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+      shell()->web_contents()->GetMainFrame(),
+      BuildGetCallWithParameters(parameters), &result));
+  ASSERT_EQ(kNotAllowedErrorMessage, result);
+}
+
 #if defined(OS_WIN)
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest, WinMakeCredential) {
   NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
diff --git a/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
index 091f3f3..5bb6772 100644
--- a/content/browser/webrtc/webrtc_image_capture_browsertest.cc
+++ b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -34,10 +34,16 @@
 // the bug is understood and fixed.
 #define MAYBE_ManipulatePan DISABLED_ManipulatePan
 #define MAYBE_ManipulateZoom DISABLED_ManipulateZoom
-#define MAYBE_ManipulateExposureTime DISABLED_ManipulateExposureTime
 #else
 #define MAYBE_ManipulatePan ManipulatePan
 #define MAYBE_ManipulateZoom ManipulateZoom
+#endif
+
+// TODO(crbug.com/793859, crbug.com/986602): This test is broken on Android
+// (see above) and flaky on Linux.
+#if defined(OS_ANDROID) || defined(OS_LINUX)
+#define MAYBE_ManipulateExposureTime DISABLED_ManipulateExposureTime
+#else
 #define MAYBE_ManipulateExposureTime ManipulateExposureTime
 #endif
 
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index c67d0cc..081be97 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -1504,10 +1504,9 @@
 // Used to go to the session history entry at the given offset (ie, -1 will
 // return the "back" item). This message affects a view and not just a frame,
 // but is sent on the frame channel for attribution purposes.
-IPC_MESSAGE_ROUTED3(FrameHostMsg_GoToEntryAtOffset,
+IPC_MESSAGE_ROUTED2(FrameHostMsg_GoToEntryAtOffset,
                     int /* offset (from current) of history item to get */,
-                    bool /* has_user_gesture */,
-                    bool /* from_script */)
+                    bool /* has_user_gesture */)
 
 #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
 
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc
index 9002c33..57f83798 100644
--- a/content/public/app/content_browser_manifest.cc
+++ b/content/public/app/content_browser_manifest.cc
@@ -244,7 +244,6 @@
                   "blink.mojom.PictureInPictureService",
                   "blink.mojom.Portal",
                   "blink.mojom.PrefetchURLLoaderService",
-                  "blink.mojom.PresentationService",
                   "blink.mojom.QuotaDispatcherHost",
                   "blink.mojom.SerialService",
                   "blink.mojom.SharedWorkerConnector",
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 9d1f9b1e..c1d6196 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -216,8 +216,6 @@
     "media/webrtc/rtc_rtp_sender.h",
     "media/webrtc/rtc_rtp_transceiver.cc",
     "media/webrtc/rtc_rtp_transceiver.h",
-    "media/webrtc/stun_field_trial.cc",
-    "media/webrtc/stun_field_trial.h",
     "media/webrtc/transceiver_state_surfacer.cc",
     "media/webrtc/transceiver_state_surfacer.h",
     "media/webrtc/webrtc_media_stream_track_adapter.cc",
@@ -240,24 +238,14 @@
     "navigation_state.h",
     "net_info_helper.cc",
     "net_info_helper.h",
-    "p2p/empty_network_manager.cc",
-    "p2p/empty_network_manager.h",
-    "p2p/filtering_network_manager.cc",
-    "p2p/filtering_network_manager.h",
     "p2p/host_address_request.cc",
     "p2p/host_address_request.h",
-    "p2p/ipc_network_manager.cc",
-    "p2p/ipc_network_manager.h",
     "p2p/ipc_socket_factory.cc",
     "p2p/ipc_socket_factory.h",
     "p2p/mdns_responder_adapter.cc",
     "p2p/mdns_responder_adapter.h",
-    "p2p/network_list_manager.h",
-    "p2p/network_list_observer.h",
     "p2p/port_allocator.cc",
     "p2p/port_allocator.h",
-    "p2p/socket_client.h",
-    "p2p/socket_client_delegate.h",
     "p2p/socket_client_impl.cc",
     "p2p/socket_client_impl.h",
     "p2p/socket_dispatcher.cc",
@@ -500,8 +488,6 @@
     "//third_party/webrtc/rtc_base:socket_address",
     "//third_party/webrtc/rtc_base:threading",
     "//third_party/webrtc/rtc_base:timeutils",
-
-    # TODO(titovartem) remove dependency on WebRTC internals.
     "//third_party/webrtc/rtc_base/third_party/sigslot:sigslot",
     "//third_party/webrtc/stats",
     "//third_party/webrtc/system_wrappers",
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index 08adf073..904bedf 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -28,10 +28,6 @@
 #include "content/public/common/webrtc_ip_handling_policy.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
-#include "content/renderer/media/webrtc/stun_field_trial.h"
-#include "content/renderer/p2p/empty_network_manager.h"
-#include "content/renderer/p2p/filtering_network_manager.h"
-#include "content/renderer/p2p/ipc_network_manager.h"
 #include "content/renderer/p2p/ipc_socket_factory.h"
 #include "content/renderer/p2p/mdns_responder_adapter.h"
 #include "content/renderer/p2p/port_allocator.h"
@@ -45,7 +41,11 @@
 #include "media/video/gpu_video_accelerator_factories.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
+#include "third_party/blink/public/platform/modules/p2p/empty_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/filtering_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/ipc_network_manager.h"
 #include "third_party/blink/public/platform/modules/peerconnection/audio_codec_factory.h"
+#include "third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h"
 #include "third_party/blink/public/platform/modules/peerconnection/video_codec_factory.h"
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
@@ -471,11 +471,11 @@
 
   std::unique_ptr<rtc::NetworkManager> network_manager;
   if (port_config.enable_multiple_routes) {
-    network_manager = std::make_unique<FilteringNetworkManager>(
+    network_manager = std::make_unique<blink::FilteringNetworkManager>(
         network_manager_.get(), requesting_origin, media_permission);
   } else {
     network_manager =
-        std::make_unique<EmptyNetworkManager>(network_manager_.get());
+        std::make_unique<blink::EmptyNetworkManager>(network_manager_.get());
   }
   auto port_allocator = std::make_unique<P2PPortAllocator>(
       p2p_socket_dispatcher_, std::move(network_manager), socket_factory_.get(),
@@ -565,22 +565,22 @@
       base::BindOnce(
           &PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread,
           base::Unretained(this), params),
-      base::TimeDelta::FromMilliseconds(kExperimentStartDelayMs));
+      base::TimeDelta::FromMilliseconds(blink::kExperimentStartDelayMs));
 }
 
 void PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread(
     const std::string& params) {
   DCHECK(network_manager_);
   DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
-  stun_trial_.reset(new StunProberTrial(network_manager_.get(), params,
-                                        socket_factory_.get()));
+  stun_trial_.reset(new blink::StunProberTrial(network_manager_.get(), params,
+                                               socket_factory_.get()));
 }
 
 void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread(
     base::WaitableEvent* event,
     std::unique_ptr<MdnsResponderAdapter> mdns_responder) {
   DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
-  network_manager_ = std::make_unique<IpcNetworkManager>(
+  network_manager_ = std::make_unique<blink::IpcNetworkManager>(
       p2p_socket_dispatcher_.get(), std::move(mdns_responder));
   event->Signal();
 }
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 75a3b73..0fb57f9 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -14,9 +14,9 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread.h"
 #include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/stun_field_trial.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "ipc/ipc_platform_file.h"
+#include "third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/p2p/stunprober/stun_prober.h"
 
@@ -33,6 +33,7 @@
 }
 
 namespace blink {
+class IpcNetworkManager;
 class WebLocalFrame;
 class WebRTCPeerConnectionHandler;
 class WebRTCPeerConnectionHandlerClient;
@@ -41,7 +42,6 @@
 
 namespace content {
 
-class IpcNetworkManager;
 class IpcPacketSocketFactory;
 class MdnsResponderAdapter;
 class P2PPortAllocator;
@@ -158,7 +158,7 @@
 
   // network_manager_ must be deleted on the worker thread. The network manager
   // uses |p2p_socket_dispatcher_|.
-  std::unique_ptr<IpcNetworkManager> network_manager_;
+  std::unique_ptr<blink::IpcNetworkManager> network_manager_;
   std::unique_ptr<IpcPacketSocketFactory> socket_factory_;
 
   scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
@@ -166,7 +166,7 @@
   scoped_refptr<P2PSocketDispatcher> p2p_socket_dispatcher_;
   scoped_refptr<blink::WebRtcAudioDeviceImpl> audio_device_;
 
-  std::unique_ptr<StunProberTrial> stun_trial_;
+  std::unique_ptr<blink::StunProberTrial> stun_trial_;
 
   // PeerConnection threads. signaling_thread_ is created from the
   // "current" chrome thread.
diff --git a/content/renderer/p2p/ipc_socket_factory.cc b/content/renderer/p2p/ipc_socket_factory.cc
index ed126ab..31f7618 100644
--- a/content/renderer/p2p/ipc_socket_factory.cc
+++ b/content/renderer/p2p/ipc_socket_factory.cc
@@ -19,11 +19,11 @@
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/trace_event.h"
 #include "content/renderer/p2p/host_address_request.h"
-#include "content/renderer/p2p/socket_client_delegate.h"
 #include "content/renderer/p2p/socket_client_impl.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "jingle/glue/utils.h"
 #include "net/base/ip_address.h"
+#include "third_party/blink/public/platform/modules/p2p/socket_client_delegate.h"
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
 #include "third_party/webrtc/rtc_base/async_packet_socket.h"
 
@@ -72,7 +72,7 @@
 // using P2PSocketClient that works over IPC-channel. It must be used
 // on the thread it was created.
 class IpcPacketSocket : public rtc::AsyncPacketSocket,
-                        public P2PSocketClientDelegate {
+                        public blink::P2PSocketClientDelegate {
  public:
   IpcPacketSocket();
   ~IpcPacketSocket() override;
@@ -120,7 +120,7 @@
               const net::IPEndPoint& remote_address) override;
   void OnIncomingTcpConnection(
       const net::IPEndPoint& address,
-      std::unique_ptr<P2PSocketClient> client) override;
+      std::unique_ptr<blink::P2PSocketClient> client) override;
   void OnSendComplete(
       const network::P2PSendPacketMetrics& send_metrics) override;
   void OnError() override;
@@ -146,7 +146,7 @@
   // |in_flight_packet_records_|.
   void TraceSendThrottlingState() const;
 
-  void InitAcceptedTcp(std::unique_ptr<P2PSocketClient> client,
+  void InitAcceptedTcp(std::unique_ptr<blink::P2PSocketClient> client,
                        const rtc::SocketAddress& local_address,
                        const rtc::SocketAddress& remote_address);
 
@@ -158,7 +158,7 @@
   base::ThreadChecker thread_checker_;
 
   // Corresponding P2P socket client.
-  std::unique_ptr<P2PSocketClient> client_;
+  std::unique_ptr<blink::P2PSocketClient> client_;
 
   // Local address is allocated by the browser process, and the
   // renderer side doesn't know the address until it receives OnOpen()
@@ -325,7 +325,7 @@
 }
 
 void IpcPacketSocket::InitAcceptedTcp(
-    std::unique_ptr<P2PSocketClient> client,
+    std::unique_ptr<blink::P2PSocketClient> client,
     const rtc::SocketAddress& local_address,
     const rtc::SocketAddress& remote_address) {
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -567,7 +567,7 @@
 
 void IpcPacketSocket::OnIncomingTcpConnection(
     const net::IPEndPoint& address,
-    std::unique_ptr<P2PSocketClient> client) {
+    std::unique_ptr<blink::P2PSocketClient> client) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   std::unique_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
diff --git a/content/renderer/p2p/network_list_observer.h b/content/renderer/p2p/network_list_observer.h
deleted file mode 100644
index 309f0ce..0000000
--- a/content/renderer/p2p/network_list_observer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_P2P_NETWORK_LIST_OBSERVER_H_
-#define CONTENT_RENDERER_P2P_NETWORK_LIST_OBSERVER_H_
-
-#include <vector>
-
-namespace net {
-class IPAddress;
-struct NetworkInterface;
-typedef std::vector<NetworkInterface> NetworkInterfaceList;
-}  // namespace net
-
-namespace content {
-
-class NetworkListObserver {
- public:
-  virtual ~NetworkListObserver() {}
-
-  virtual void OnNetworkListChanged(
-      const net::NetworkInterfaceList& list,
-      const net::IPAddress& default_ipv4_local_address,
-      const net::IPAddress& default_ipv6_local_address) = 0;
-
- protected:
-  NetworkListObserver() {}
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_P2P_NETWORK_LIST_OBSERVER_H_
diff --git a/content/renderer/p2p/socket_client_impl.cc b/content/renderer/p2p/socket_client_impl.cc
index d9222de..7ae6dc7 100644
--- a/content/renderer/p2p/socket_client_impl.cc
+++ b/content/renderer/p2p/socket_client_impl.cc
@@ -9,11 +9,11 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "content/renderer/p2p/socket_client_delegate.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "content/renderer/render_thread_impl.h"
 #include "crypto/random.h"
 #include "services/network/public/cpp/p2p_param_traits.h"
+#include "third_party/blink/public/platform/modules/p2p/socket_client_delegate.h"
 
 namespace {
 
@@ -52,7 +52,7 @@
     uint16_t min_port,
     uint16_t max_port,
     const network::P2PHostAndIPEndPoint& remote_address,
-    P2PSocketClientDelegate* delegate) {
+    blink::P2PSocketClientDelegate* delegate) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(delegate);
   // |delegate_| is only accessesed on |delegate_message_loop_|.
@@ -114,7 +114,8 @@
   return socket_id_;
 }
 
-void P2PSocketClientImpl::SetDelegate(P2PSocketClientDelegate* delegate) {
+void P2PSocketClientImpl::SetDelegate(
+    blink::P2PSocketClientDelegate* delegate) {
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_ = delegate;
 }
diff --git a/content/renderer/p2p/socket_client_impl.h b/content/renderer/p2p/socket_client_impl.h
index cb9bb37..8354f6d 100644
--- a/content/renderer/p2p/socket_client_impl.h
+++ b/content/renderer/p2p/socket_client_impl.h
@@ -12,12 +12,12 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
-#include "content/renderer/p2p/socket_client.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/base/ip_endpoint.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/p2p_socket_type.h"
 #include "services/network/public/mojom/p2p.mojom.h"
+#include "third_party/blink/public/platform/modules/p2p/socket_client.h"
 
 namespace base {
 class TimeTicks;
@@ -30,7 +30,7 @@
 // P2P socket that routes all calls over Mojo.
 //
 // The object runs on the WebRTC worker thread.
-class P2PSocketClientImpl : public P2PSocketClient,
+class P2PSocketClientImpl : public blink::P2PSocketClient,
                             public network::mojom::P2PSocketClient {
  public:
   P2PSocketClientImpl(
@@ -46,7 +46,7 @@
                     uint16_t min_port,
                     uint16_t max_port,
                     const network::P2PHostAndIPEndPoint& remote_address,
-                    P2PSocketClientDelegate* delegate);
+                    blink::P2PSocketClientDelegate* delegate);
 
   // Send the |data| to the |address| using Differentiated Services Code Point
   // |dscp|. Return value is the unique packet_id for this packet.
@@ -63,7 +63,7 @@
 
   int GetSocketID() const override;
 
-  void SetDelegate(P2PSocketClientDelegate* delegate) override;
+  void SetDelegate(blink::P2PSocketClientDelegate* delegate) override;
 
  private:
   enum State {
@@ -100,7 +100,7 @@
   P2PSocketDispatcher* dispatcher_;
   base::ThreadChecker thread_checker_;
   int socket_id_;
-  P2PSocketClientDelegate* delegate_;
+  blink::P2PSocketClientDelegate* delegate_;
   State state_;
   const net::NetworkTrafficAnnotationTag traffic_annotation_;
 
diff --git a/content/renderer/p2p/socket_dispatcher.cc b/content/renderer/p2p/socket_dispatcher.cc
index b40944b7..96bd65cf 100644
--- a/content/renderer/p2p/socket_dispatcher.cc
+++ b/content/renderer/p2p/socket_dispatcher.cc
@@ -9,23 +9,23 @@
 #include "content/child/child_process.h"
 #include "content/child/child_thread_impl.h"
 #include "content/public/common/service_names.mojom.h"
-#include "content/renderer/p2p/network_list_observer.h"
 #include "content/renderer/p2p/socket_client_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "services/network/public/cpp/p2p_param_traits.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_observer.h"
 
 namespace content {
 
 P2PSocketDispatcher::P2PSocketDispatcher()
     : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       network_list_observers_(
-          new base::ObserverListThreadSafe<NetworkListObserver>()) {}
+          new base::ObserverListThreadSafe<blink::NetworkListObserver>()) {}
 
 P2PSocketDispatcher::~P2PSocketDispatcher() {
 }
 
 void P2PSocketDispatcher::AddNetworkListObserver(
-    NetworkListObserver* network_list_observer) {
+    blink::NetworkListObserver* network_list_observer) {
   network_list_observers_->AddObserver(network_list_observer);
   main_task_runner_->PostTask(
       FROM_HERE,
@@ -34,7 +34,7 @@
 }
 
 void P2PSocketDispatcher::RemoveNetworkListObserver(
-    NetworkListObserver* network_list_observer) {
+    blink::NetworkListObserver* network_list_observer) {
   network_list_observers_->RemoveObserver(network_list_observer);
 }
 
@@ -65,7 +65,7 @@
   default_ipv4_local_address_ = default_ipv4_local_address;
   default_ipv6_local_address_ = default_ipv6_local_address;
   network_list_observers_->Notify(
-      FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks,
+      FROM_HERE, &blink::NetworkListObserver::OnNetworkListChanged, networks,
       default_ipv4_local_address, default_ipv6_local_address);
 }
 
@@ -80,7 +80,7 @@
 void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
   if (network_notification_client_receiver_.is_bound()) {
     network_list_observers_->Notify(
-        FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks_,
+        FROM_HERE, &blink::NetworkListObserver::OnNetworkListChanged, networks_,
         default_ipv4_local_address_, default_ipv6_local_address_);
   } else {
     GetP2PSocketManager()->get()->StartNetworkNotifications(
diff --git a/content/renderer/p2p/socket_dispatcher.h b/content/renderer/p2p/socket_dispatcher.h
index fcaee68..1d05550a 100644
--- a/content/renderer/p2p/socket_dispatcher.h
+++ b/content/renderer/p2p/socket_dispatcher.h
@@ -32,36 +32,38 @@
 #include "base/observer_list_threadsafe.h"
 #include "base/synchronization/lock.h"
 #include "content/common/content_export.h"
-#include "content/renderer/p2p/network_list_manager.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
 #include "net/base/ip_address.h"
 #include "net/base/network_interfaces.h"
 #include "services/network/public/cpp/p2p_socket_type.h"
 #include "services/network/public/mojom/p2p.mojom.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_manager.h"
 
 namespace base {
 class SingleThreadTaskRunner;
 }  // namespace base
 
-namespace content {
-
+namespace blink {
 class NetworkListObserver;
+}
+
+namespace content {
 
 // This class is created on the main thread, but is used primarily on the
 // WebRTC worker threads.
 class CONTENT_EXPORT P2PSocketDispatcher
     : public base::RefCountedThreadSafe<P2PSocketDispatcher>,
-      public NetworkListManager,
+      public blink::NetworkListManager,
       public network::mojom::P2PNetworkNotificationClient {
  public:
   P2PSocketDispatcher();
 
-  // NetworkListManager interface:
+  // blink::NetworkListManager interface:
   void AddNetworkListObserver(
-      NetworkListObserver* network_list_observer) override;
+      blink::NetworkListObserver* network_list_observer) override;
   void RemoveNetworkListObserver(
-      NetworkListObserver* network_list_observer) override;
+      blink::NetworkListObserver* network_list_observer) override;
 
   scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
   GetP2PSocketManager();
@@ -84,7 +86,7 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
 
-  scoped_refptr<base::ObserverListThreadSafe<NetworkListObserver>>
+  scoped_refptr<base::ObserverListThreadSafe<blink::NetworkListObserver>>
       network_list_observers_;
 
   network::mojom::P2PSocketManagerRequest p2p_socket_manager_request_;
diff --git a/content/renderer/pepper/pepper_video_capture_host.cc b/content/renderer/pepper/pepper_video_capture_host.cc
index e85a337..6fbea83 100644
--- a/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/content/renderer/pepper/pepper_video_capture_host.cc
@@ -4,6 +4,7 @@
 
 #include "content/renderer/pepper/pepper_video_capture_host.h"
 
+#include "base/numerics/ranges.h"
 #include "content/renderer/pepper/host_globals.h"
 #include "content/renderer/pepper/pepper_media_device_manager.h"
 #include "content/renderer/pepper/pepper_platform_video_capture.h"
@@ -339,11 +340,11 @@
     const PP_VideoCaptureDeviceInfo_Dev& device_info,
     uint32_t buffer_count) {
   // Clamp the buffer count to between 1 and |kMaxBuffers|.
-  buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers);
+  buffer_count_hint_ = base::ClampToRange(buffer_count, 1U, kMaxBuffers);
   // Clamp the frame rate to between 1 and |kMaxFramesPerSecond - 1|.
   int frames_per_second =
-      std::min(std::max(device_info.frames_per_second, 1U),
-               static_cast<uint32_t>(media::limits::kMaxFramesPerSecond - 1));
+      base::ClampToRange(device_info.frames_per_second, 1U,
+                         uint32_t{media::limits::kMaxFramesPerSecond - 1});
 
   video_capture_params_.requested_format = media::VideoCaptureFormat(
       gfx::Size(device_info.width, device_info.height), frames_per_second,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 16938bb3..fde26fc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5221,11 +5221,10 @@
 }
 
 void RenderFrameImpl::NavigateBackForwardSoon(int offset,
-                                              bool has_user_gesture,
-                                              bool from_script) {
+                                              bool has_user_gesture) {
   render_view()->NavigateBackForwardSoon(offset, has_user_gesture);
   Send(new FrameHostMsg_GoToEntryAtOffset(GetRoutingID(), offset,
-                                          has_user_gesture, from_script));
+                                          has_user_gesture));
 }
 
 base::UnguessableToken RenderFrameImpl::GetDevToolsFrameToken() {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 6b95cb5e..7c64101 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -786,9 +786,7 @@
   void DidBlockNavigation(const blink::WebURL& blocked_url,
                           const blink::WebURL& initiator_url,
                           blink::NavigationBlockedReason reason) override;
-  void NavigateBackForwardSoon(int offset,
-                               bool has_user_gesture,
-                               bool from_script) override;
+  void NavigateBackForwardSoon(int offset, bool has_user_gesture) override;
   base::UnguessableToken GetDevToolsFrameToken() override;
   void RenderFallbackContentInParentProcess() override;
   void AbortClientNavigation() override;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 2a4eca9..d50f19e 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -720,6 +720,11 @@
       switches::kDisableWebRtcHWDecoding);
 }
 
+bool RendererBlinkPlatformImpl::AllowsLoopbackInPeerConnection() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kAllowLoopbackInPeerConnection);
+}
+
 blink::WebVideoCaptureImplManager*
 RendererBlinkPlatformImpl::GetVideoCaptureImplManager() {
   RenderThreadImpl* thread = RenderThreadImpl::current();
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 1005227..130d123c 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -161,6 +161,7 @@
       webrtc::VideoCodecType video_coded_type) override;
   bool IsWebRtcHWEncodingEnabled() override;
   bool IsWebRtcHWDecodingEnabled() override;
+  bool AllowsLoopbackInPeerConnection() override;
 
   blink::WebVideoCaptureImplManager* GetVideoCaptureImplManager() override;
 
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index e6eff17..4d80608b 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1950,15 +1950,12 @@
     "../renderer/media/webrtc/rtc_rtp_receiver_unittest.cc",
     "../renderer/media/webrtc/rtc_rtp_sender_unittest.cc",
     "../renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc",
-    "../renderer/media/webrtc/stun_field_trial_unittest.cc",
     "../renderer/media/webrtc/task_queue_factory_unittest.cc",
     "../renderer/media/webrtc/transceiver_state_surfacer_unittest.cc",
     "../renderer/media/webrtc/webrtc_audio_renderer_unittest.cc",
     "../renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc",
     "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc",
     "../renderer/media/webrtc/webrtc_set_description_observer_unittest.cc",
-    "../renderer/p2p/filtering_network_manager_unittest.cc",
-    "../renderer/p2p/ipc_network_manager_unittest.cc",
     "../renderer/peripheral_content_heuristic_unittest.cc",
     "../renderer/queue_message_swap_promise_unittest.cc",
     "../renderer/render_frame_metadata_observer_impl_unittest.cc",
diff --git a/device/bluetooth/adapter.cc b/device/bluetooth/adapter.cc
index 1235997..5393ecc1 100644
--- a/device/bluetooth/adapter.cc
+++ b/device/bluetooth/adapter.cc
@@ -12,6 +12,7 @@
 #include "device/bluetooth/device.h"
 #include "device/bluetooth/discovery_session.h"
 #include "device/bluetooth/public/mojom/connect_result_type_converter.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
 namespace bluetooth {
@@ -32,7 +33,7 @@
 
   if (!device) {
     std::move(callback).Run(mojom::ConnectResult::DEVICE_NO_LONGER_IN_RANGE,
-                            nullptr /* device */);
+                            /* device */ mojo::NullRemote());
     return;
   }
 
@@ -132,17 +133,17 @@
 void Adapter::OnGattConnected(
     ConnectToDeviceCallback callback,
     std::unique_ptr<device::BluetoothGattConnection> connection) {
-  mojom::DevicePtr device_ptr;
+  mojo::PendingRemote<mojom::Device> device;
   Device::Create(adapter_, std::move(connection),
-                 mojo::MakeRequest(&device_ptr));
-  std::move(callback).Run(mojom::ConnectResult::SUCCESS, std::move(device_ptr));
+                 device.InitWithNewPipeAndPassReceiver());
+  std::move(callback).Run(mojom::ConnectResult::SUCCESS, std::move(device));
 }
 
 void Adapter::OnConnectError(
     ConnectToDeviceCallback callback,
     device::BluetoothDevice::ConnectErrorCode error_code) {
   std::move(callback).Run(mojo::ConvertTo<mojom::ConnectResult>(error_code),
-                          nullptr /* Device */);
+                          /* device */ mojo::NullRemote());
 }
 
 void Adapter::OnStartDiscoverySession(
diff --git a/device/bluetooth/device.cc b/device/bluetooth/device.cc
index 75c276e..41ef648 100644
--- a/device/bluetooth/device.cc
+++ b/device/bluetooth/device.cc
@@ -10,7 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "device/bluetooth/device.h"
 #include "device/bluetooth/public/mojom/gatt_result_type_converter.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
 namespace bluetooth {
 Device::~Device() {
@@ -20,12 +20,12 @@
 // static
 void Device::Create(scoped_refptr<device::BluetoothAdapter> adapter,
                     std::unique_ptr<device::BluetoothGattConnection> connection,
-                    mojom::DeviceRequest request) {
+                    mojo::PendingReceiver<mojom::Device> receiver) {
   auto device_impl =
       base::WrapUnique(new Device(adapter, std::move(connection)));
   auto* device_ptr = device_impl.get();
-  device_ptr->binding_ =
-      mojo::MakeStrongBinding(std::move(device_impl), std::move(request));
+  device_ptr->receiver_ =
+      mojo::MakeSelfOwnedReceiver(std::move(device_impl), std::move(receiver));
 }
 
 // static
@@ -54,7 +54,7 @@
   }
 
   if (!device->IsGattConnected()) {
-    binding_->Close();
+    receiver_->Close();
   }
 }
 
@@ -72,7 +72,7 @@
 }
 
 void Device::Disconnect() {
-  binding_->Close();
+  receiver_->Close();
 }
 
 void Device::GetInfo(GetInfoCallback callback) {
diff --git a/device/bluetooth/device.h b/device/bluetooth/device.h
index b74276b5..953fb9bf 100644
--- a/device/bluetooth/device.h
+++ b/device/bluetooth/device.h
@@ -19,7 +19,7 @@
 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service.h"
 #include "device/bluetooth/public/mojom/device.mojom.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
 namespace bluetooth {
 
@@ -37,7 +37,7 @@
   static void Create(
       scoped_refptr<device::BluetoothAdapter> adapter,
       std::unique_ptr<device::BluetoothGattConnection> connection,
-      mojom::DeviceRequest request);
+      mojo::PendingReceiver<mojom::Device> receiver);
 
   // Creates a mojom::DeviceInfo using info from the given |device|.
   static mojom::DeviceInfoPtr ConstructDeviceInfoStruct(
@@ -122,7 +122,7 @@
   // The GATT connection to this device.
   std::unique_ptr<device::BluetoothGattConnection> connection_;
 
-  mojo::StrongBindingPtr<mojom::Device> binding_;
+  mojo::SelfOwnedReceiverRef<mojom::Device> receiver_;
 
   // The services request queue which holds callbacks that are waiting for
   // services to be discovered for this device.
diff --git a/device/bluetooth/device_unittest.cc b/device/bluetooth/device_unittest.cc
index b87b5df4..18336a4 100644
--- a/device/bluetooth/device_unittest.cc
+++ b/device/bluetooth/device_unittest.cc
@@ -19,6 +19,7 @@
 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using ::testing::Return;
@@ -121,9 +122,10 @@
     auto connection = std::make_unique<NiceMockBluetoothGattConnection>(
         adapter_, device_.GetAddress());
 
-    Device::Create(adapter_, std::move(connection), mojo::MakeRequest(&proxy_));
+    Device::Create(adapter_, std::move(connection),
+                   proxy_.BindNewPipeAndPassReceiver());
 
-    proxy_.set_connection_error_handler(
+    proxy_.set_disconnect_handler(
         base::BindOnce(&BluetoothInterfaceDeviceTest::OnConnectionError,
                        weak_factory_.GetWeakPtr()));
   }
@@ -174,8 +176,7 @@
   scoped_refptr<NiceMockBluetoothAdapter> adapter_;
   NiceMockBluetoothDevice device_;
   base::test::SingleThreadTaskEnvironment task_environment_;
-  mojom::DevicePtr proxy_;
-  mojo::StrongBindingPtr<mojom::Device> binding_ptr_;
+  mojo::Remote<mojom::Device> proxy_;
 
   bool message_pipe_closed_ = false;
   bool expect_device_service_deleted_ = false;
diff --git a/device/bluetooth/public/mojom/adapter.mojom b/device/bluetooth/public/mojom/adapter.mojom
index 3259431..cd79f59 100644
--- a/device/bluetooth/public/mojom/adapter.mojom
+++ b/device/bluetooth/public/mojom/adapter.mojom
@@ -55,7 +55,8 @@
   // Creates a GATT connection to the device with |address| and returns a
   // Device if the connection was succesful. The GATT connection is tied to the
   // the lifetime of the Device message pipe.
-  ConnectToDevice(string address) => (ConnectResult result, Device? device);
+  ConnectToDevice(string address) =>
+      (ConnectResult result, pending_remote<Device>? device);
 
   // Retrieves the list of the devices known by the adapter including Connected
   // Devices, GATT Connected Devices, Paired Devices and Devices discovered
diff --git a/device/fido/cable/cable_discovery_data.h b/device/fido/cable/cable_discovery_data.h
index 0ba7dc4..8031025 100644
--- a/device/fido/cable/cable_discovery_data.h
+++ b/device/fido/cable/cable_discovery_data.h
@@ -32,7 +32,13 @@
 // TODO(hongjunchoi): Add discovery data required for MakeCredential request.
 // See: https://crbug.com/837088
 struct COMPONENT_EXPORT(DEVICE_FIDO) CableDiscoveryData {
-  CableDiscoveryData(uint8_t version,
+  enum class Version {
+    INVALID,
+    V1,
+    V2,
+  };
+
+  CableDiscoveryData(Version version,
                      const CableEidArray& client_eid,
                      const CableEidArray& authenticator_eid,
                      const CableSessionPreKeyArray& session_pre_key);
@@ -61,10 +67,17 @@
       base::span<const uint8_t, 32> qr_generator_key,
       const int64_t tick);
 
-  uint8_t version;
-  CableEidArray client_eid;
-  CableEidArray authenticator_eid;
-  CableSessionPreKeyArray session_pre_key;
+  // version indicates whether v1 or v2 data is contained in this object.
+  // |INVALID| is not a valid version but is set as the default to catch any
+  // cases where the version hasn't been set explicitly.
+  Version version = Version::INVALID;
+
+  struct V1Data {
+    CableEidArray client_eid;
+    CableEidArray authenticator_eid;
+    CableSessionPreKeyArray session_pre_key;
+  };
+  base::Optional<V1Data> v1;
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_cable_discovery.cc b/device/fido/cable/fido_cable_discovery.cc
index 56d9506f..171b33c 100644
--- a/device/fido/cable/fido_cable_discovery.cc
+++ b/device/fido/cable/fido_cable_discovery.cc
@@ -40,7 +40,6 @@
 // instead, and on Mac our only option is to advertise an additional service
 // with the EID as its UUID.
 std::unique_ptr<BluetoothAdvertisement::Data> ConstructAdvertisementData(
-    uint8_t version_number,
     base::span<const uint8_t, kCableEphemeralIdSize> client_eid) {
   auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
       BluetoothAdvertisement::AdvertisementType::ADVERTISEMENT_TYPE_BROADCAST);
@@ -66,7 +65,7 @@
       3u + kCableEphemeralIdSize;
   std::array<uint8_t, 4> kCableGoogleManufacturerDataHeader = {
       kCableGoogleManufacturerDataLength, kCableGoogleManufacturerDataType,
-      kCableFlags, version_number};
+      kCableFlags, /*version=*/1};
 
   auto manufacturer_data =
       std::make_unique<BluetoothAdvertisement::ManufacturerData>();
@@ -91,7 +90,7 @@
   // Since the remainder of this service data field is a Cable EID, set the 5th
   // bit of the flag byte.
   service_data_value[0] = kCableFlags;
-  service_data_value[1] = version_number;
+  service_data_value[1] = 1 /* version */;
   std::copy(client_eid.begin(), client_eid.end(),
             service_data_value.begin() + 2);
   service_data->emplace(kCableAdvertisementUUID128,
@@ -109,14 +108,17 @@
 CableDiscoveryData::CableDiscoveryData() = default;
 
 CableDiscoveryData::CableDiscoveryData(
-    uint8_t version,
+    CableDiscoveryData::Version version,
     const CableEidArray& client_eid,
     const CableEidArray& authenticator_eid,
     const CableSessionPreKeyArray& session_pre_key)
-    : version(version),
-      client_eid(client_eid),
-      authenticator_eid(authenticator_eid),
-      session_pre_key(session_pre_key) {}
+    : version(version) {
+  CHECK_EQ(Version::V1, version);
+  v1.emplace();
+  v1->client_eid = client_eid;
+  v1->authenticator_eid = authenticator_eid;
+  v1->session_pre_key = session_pre_key;
+}
 
 CableDiscoveryData::CableDiscoveryData(const CableDiscoveryData& data) =
     default;
@@ -127,9 +129,21 @@
 CableDiscoveryData::~CableDiscoveryData() = default;
 
 bool CableDiscoveryData::operator==(const CableDiscoveryData& other) const {
-  return version == other.version && client_eid == other.client_eid &&
-         authenticator_eid == other.authenticator_eid &&
-         session_pre_key == other.session_pre_key;
+  if (version != other.version) {
+    return false;
+  }
+
+  switch (version) {
+    case CableDiscoveryData::Version::V1:
+      return v1->client_eid == other.v1->client_eid &&
+             v1->authenticator_eid == other.v1->authenticator_eid &&
+             v1->session_pre_key == other.v1->session_pre_key;
+
+    case CableDiscoveryData::Version::V2:
+    case CableDiscoveryData::Version::INVALID:
+      CHECK(false);
+      return false;
+  }
 }
 
 // static
@@ -207,29 +221,30 @@
     const CableDiscoveryData* discovery_data) {
   std::unique_ptr<FidoCableHandshakeHandler> handler;
   switch (discovery_data->version) {
-    case 1: {
+    case CableDiscoveryData::Version::V1: {
       // Nonce is embedded as first 8 bytes of client EID.
       std::array<uint8_t, 8> nonce;
       const bool ok = fido_parsing_utils::ExtractArray(
-          discovery_data->client_eid, 0, &nonce);
+          discovery_data->v1->client_eid, 0, &nonce);
       DCHECK(ok);
 
       handler.reset(new FidoCableV1HandshakeHandler(
-          device, nonce, discovery_data->session_pre_key));
+          device, nonce, discovery_data->v1->session_pre_key));
       break;
     }
 
-    case 2:
+    case CableDiscoveryData::Version::V2: {
+      // Nonce is embedded as first 8 bytes of client EID.
       if (!base::FeatureList::IsEnabled(device::kWebAuthPhoneSupport)) {
         return base::nullopt;
       }
       handler.reset(new FidoCableV2HandshakeHandler(
-          device, discovery_data->session_pre_key));
+          device, discovery_data->v1->session_pre_key));
       break;
+    }
 
-    default:
-      FIDO_LOG(DEBUG) << "Dropping caBLE handshake request for unknown version "
-                      << discovery_data->version;
+    case CableDiscoveryData::Version::INVALID:
+      CHECK(false);
       return base::nullopt;
   }
 
@@ -326,11 +341,14 @@
 
   FIDO_LOG(DEBUG) << "Starting to advertise clientEID.";
   for (const auto& data : discovery_data_) {
+    if (data.version != CableDiscoveryData::Version::V1) {
+      continue;
+    }
     adapter()->RegisterAdvertisement(
-        ConstructAdvertisementData(data.version, data.client_eid),
+        ConstructAdvertisementData(data.v1->client_eid),
         base::AdaptCallbackForRepeating(
             base::BindOnce(&FidoCableDiscovery::OnAdvertisementRegistered,
-                           weak_factory_.GetWeakPtr(), data.client_eid)),
+                           weak_factory_.GetWeakPtr(), data.v1->client_eid)),
         base::AdaptCallbackForRepeating(
             base::BindOnce(&FidoCableDiscovery::OnAdvertisementRegisterError,
                            weak_factory_.GetWeakPtr())));
@@ -387,13 +405,14 @@
   const std::string device_address = device->GetAddress();
   if (!found_cable_device_data ||
       base::Contains(active_authenticator_eids_,
-                     found_cable_device_data->authenticator_eid) ||
+                     found_cable_device_data->v1->authenticator_eid) ||
       base::Contains(active_devices_, device_address)) {
     return;
   }
 
   FIDO_LOG(EVENT) << "Found new caBLE device.";
-  active_authenticator_eids_.insert(found_cable_device_data->authenticator_eid);
+  active_authenticator_eids_.insert(
+      found_cable_device_data->v1->authenticator_eid);
   active_devices_.insert(device_address);
 
   auto cable_device =
@@ -523,7 +542,7 @@
   auto discovery_data_iterator =
       std::find_if(discovery_data_.begin(), discovery_data_.end(),
                    [&authenticator_eid](const auto& data) {
-                     return authenticator_eid == data.authenticator_eid;
+                     return authenticator_eid == data.v1->authenticator_eid;
                    });
 
   if (discovery_data_iterator != discovery_data_.end()) {
@@ -547,8 +566,8 @@
           *qr_generator_key_, current_tick - i);
       if (expected_authenticator_eid == authenticator_eid) {
         CableEidArray zero_eid{};
-        return CableDiscoveryData(/*version=*/2, zero_eid, authenticator_eid,
-                                  session_pre_key);
+        return CableDiscoveryData(CableDiscoveryData::Version::V2, zero_eid,
+                                  authenticator_eid, session_pre_key);
       }
     }
   }
diff --git a/device/fido/cable/fido_cable_discovery_unittest.cc b/device/fido/cable/fido_cable_discovery_unittest.cc
index 3c0d7b2..0ce9c496f 100644
--- a/device/fido/cable/fido_cable_discovery_unittest.cc
+++ b/device/fido/cable/fido_cable_discovery_unittest.cc
@@ -32,7 +32,10 @@
 
 namespace {
 
-constexpr uint8_t kTestCableVersionNumber = 0x01;
+constexpr auto kTestCableVersion = CableDiscoveryData::Version::V1;
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+constexpr auto kTestCableVersionNumber = 1;
+#endif
 
 // Constants required for discovering and constructing a Cable device that
 // are given by the relying party via an extension.
@@ -300,11 +303,11 @@
                          const CableDiscoveryData* discovery_data) override {
     // Nonce is embedded as first 8 bytes of client EID.
     std::array<uint8_t, 8> nonce;
-    const bool ok =
-        fido_parsing_utils::ExtractArray(discovery_data->client_eid, 0, &nonce);
+    const bool ok = fido_parsing_utils::ExtractArray(
+        discovery_data->v1->client_eid, 0, &nonce);
     DCHECK(ok);
     return std::make_unique<FakeHandshakeHandler>(
-        device, nonce, discovery_data->session_pre_key);
+        device, nonce, discovery_data->v1->session_pre_key);
   }
 
   static std::array<uint8_t, 32> BogusQRGeneratorKey() {
@@ -320,7 +323,7 @@
  public:
   std::unique_ptr<FidoCableDiscovery> CreateDiscovery() {
     std::vector<CableDiscoveryData> discovery_data;
-    discovery_data.emplace_back(kTestCableVersionNumber, kClientEid,
+    discovery_data.emplace_back(kTestCableVersion, kClientEid,
                                 kAuthenticatorEid, kTestSessionPreKey);
     return std::make_unique<FakeFidoCableDiscovery>(std::move(discovery_data));
   }
@@ -398,9 +401,9 @@
 // BluetoothAdapter::RegisterAdvertisement().
 TEST_F(FidoCableDiscoveryTest, TestDiscoveryWithMultipleEids) {
   std::vector<CableDiscoveryData> discovery_data;
-  discovery_data.emplace_back(kTestCableVersionNumber, kClientEid,
-                              kAuthenticatorEid, kTestSessionPreKey);
-  discovery_data.emplace_back(kTestCableVersionNumber, kSecondaryClientEid,
+  discovery_data.emplace_back(kTestCableVersion, kClientEid, kAuthenticatorEid,
+                              kTestSessionPreKey);
+  discovery_data.emplace_back(kTestCableVersion, kSecondaryClientEid,
                               kSecondaryAuthenticatorEid,
                               kSecondarySessionPreKey);
   auto cable_discovery =
@@ -432,9 +435,9 @@
 // scanning process should be invoked.
 TEST_F(FidoCableDiscoveryTest, TestDiscoveryWithPartialAdvertisementSuccess) {
   std::vector<CableDiscoveryData> discovery_data;
-  discovery_data.emplace_back(kTestCableVersionNumber, kClientEid,
-                              kAuthenticatorEid, kTestSessionPreKey);
-  discovery_data.emplace_back(kTestCableVersionNumber, kSecondaryClientEid,
+  discovery_data.emplace_back(kTestCableVersion, kClientEid, kAuthenticatorEid,
+                              kTestSessionPreKey);
+  discovery_data.emplace_back(kTestCableVersion, kSecondaryClientEid,
                               kSecondaryAuthenticatorEid,
                               kSecondarySessionPreKey);
   auto cable_discovery =
@@ -463,9 +466,9 @@
 // Test the scenario when all advertisement for client EID's fails.
 TEST_F(FidoCableDiscoveryTest, TestDiscoveryWithAdvertisementFailures) {
   std::vector<CableDiscoveryData> discovery_data;
-  discovery_data.emplace_back(kTestCableVersionNumber, kClientEid,
-                              kAuthenticatorEid, kTestSessionPreKey);
-  discovery_data.emplace_back(kTestCableVersionNumber, kSecondaryClientEid,
+  discovery_data.emplace_back(kTestCableVersion, kClientEid, kAuthenticatorEid,
+                              kTestSessionPreKey);
+  discovery_data.emplace_back(kTestCableVersion, kSecondaryClientEid,
                               kSecondaryAuthenticatorEid,
                               kSecondarySessionPreKey);
   auto cable_discovery =
diff --git a/device/gamepad/public/cpp/gamepad_mojom_traits_unittest.cc b/device/gamepad/public/cpp/gamepad_mojom_traits_unittest.cc
index 13ab0e9..daf77d4 100644
--- a/device/gamepad/public/cpp/gamepad_mojom_traits_unittest.cc
+++ b/device/gamepad/public/cpp/gamepad_mojom_traits_unittest.cc
@@ -164,7 +164,7 @@
   GamepadStructTraitsTest() {}
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   DISALLOW_COPY_AND_ASSIGN(GamepadStructTraitsTest);
 };
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 636e47a..8bebff79 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -11,27 +11,42 @@
 
 config("gpu_implementation") {
   defines = [ "GPU_IMPLEMENTATION" ]
-  configs = [ "//build/config/compiler:wexit_time_destructors" ]
+  configs = [
+    "//build/config/compiler:noshadowing",
+    "//build/config/compiler:wexit_time_destructors",
+  ]
 }
 
 config("gpu_gles2_implementation") {
   defines = [ "GPU_GLES2_IMPLEMENTATION" ]
-  configs = [ "//build/config/compiler:wexit_time_destructors" ]
+  configs = [
+    "//build/config/compiler:noshadowing",
+    "//build/config/compiler:wexit_time_destructors",
+  ]
 }
 
 config("gpu_util_implementation") {
   defines = [ "GPU_UTIL_IMPLEMENTATION" ]
-  configs = [ "//build/config/compiler:wexit_time_destructors" ]
+  configs = [
+    "//build/config/compiler:noshadowing",
+    "//build/config/compiler:wexit_time_destructors",
+  ]
 }
 
 config("raster_implementation") {
   defines = [ "RASTER_IMPLEMENTATION" ]
-  configs = [ "//build/config/compiler:wexit_time_destructors" ]
+  configs = [
+    "//build/config/compiler:noshadowing",
+    "//build/config/compiler:wexit_time_destructors",
+  ]
 }
 
 config("webgpu_implementation") {
   defines = [ "WEBGPU_IMPLEMENTATION" ]
-  configs = [ "//build/config/compiler:wexit_time_destructors" ]
+  configs = [
+    "//build/config/compiler:noshadowing",
+    "//build/config/compiler:wexit_time_destructors",
+  ]
 }
 
 component("gpu") {
diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc
index 979ed2d..ab4c9c7 100644
--- a/gpu/command_buffer/service/buffer_manager.cc
+++ b/gpu/command_buffer/service/buffer_manager.cc
@@ -294,7 +294,7 @@
   // from scratch.
   if (primitive_restart_enabled) {
     Range disabled_range(offset, count, type, false);
-    RangeToMaxValueMap::iterator it = range_set_.find(disabled_range);
+    it = range_set_.find(disabled_range);
     if (it != range_set_.end() && it->second < primitive_restart_index) {
       // This reuses the max value for the case where primitive
       // restart is enabled.
diff --git a/gpu/command_buffer/service/external_vk_image_backing.cc b/gpu/command_buffer/service/external_vk_image_backing.cc
index 01681ce..737c8739 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -303,13 +303,10 @@
       return nullptr;
     }
 
-    viz::ResourceFormat resource_format = viz::GetResourceFormat(buffer_format);
-
     return base::WrapUnique(new ExternalVkImageBacking(
-        mailbox, viz::GetResourceFormat(buffer_format), size, color_space,
-        usage, context_state, vk_image, vk_device_memory, memory_size,
-        vk_image_info.format, command_pool, ycbcr_info,
-        GetDawnFormat(resource_format), {}));
+        mailbox, resource_format, size, color_space, usage, context_state,
+        vk_image, vk_device_memory, memory_size, vk_image_info.format,
+        command_pool, ycbcr_info, GetDawnFormat(resource_format), {}));
   }
 
   if (gfx::NumberOfPlanesForLinearBufferFormat(buffer_format) != 1) {
@@ -788,8 +785,8 @@
   {
     ScopedSingleUseCommandBufferRecorder recorder(*command_buffer);
     GrVkImageInfo image_info;
-    bool result = backend_texture_.getVkImageInfo(&image_info);
-    DCHECK(result);
+    bool success = backend_texture_.getVkImageInfo(&image_info);
+    DCHECK(success);
     if (image_info.fImageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
       command_buffer->TransitionImageLayout(
           image_info.fImage, image_info.fImageLayout,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e0f77fd..1381e62 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -818,7 +818,7 @@
     kFramebufferInvalidateSub
   };
 
-  enum BindIndexedBufferFunctionType {
+  enum class BindIndexedBufferFunctionType {
     kBindBufferBase,
     kBindBufferRange
   };
@@ -1555,7 +1555,7 @@
   // error. Returns true if |api_type| is valid for the uniform
   bool CheckUniformForApiType(const Program::UniformInfo* info,
                               const char* function_name,
-                              Program::UniformApiType api_type);
+                              UniformApiType api_type);
 
   // Gets the type of a uniform for a location in the current program. Sets GL
   // errors if the current program is not valid. Returns true if the current
@@ -1563,7 +1563,7 @@
   // does not overflow the uniform.
   bool PrepForSetUniformByLocation(GLint fake_location,
                                    const char* function_name,
-                                   Program::UniformApiType api_type,
+                                   UniformApiType api_type,
                                    GLint* real_location,
                                    GLenum* type,
                                    GLsizei* count);
@@ -3285,7 +3285,7 @@
     GLuint fbo;
     api()->glGenFramebuffersEXTFn(1, &fbo);
     {
-      ScopedFramebufferBinder binder(decoder_, fbo);
+      ScopedFramebufferBinder frame_binder(decoder_, fbo);
       api()->glFramebufferRenderbufferEXTFn(
           GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, id_);
       api()->glClearColorFn(0, 0, 0, decoder_->BackBufferAlphaClearColor());
@@ -6080,7 +6080,7 @@
       break;
   }
 
-  if (function_type == kBindBufferRange) {
+  if (function_type == BindIndexedBufferFunctionType::kBindBufferRange) {
     switch (target) {
       case GL_TRANSFORM_FEEDBACK_BUFFER:
         if ((size % 4 != 0) || (offset % 4 != 0)) {
@@ -6154,10 +6154,10 @@
   }
   DCHECK(bindings);
   switch (function_type) {
-    case kBindBufferBase:
+    case BindIndexedBufferFunctionType::kBindBufferBase:
       bindings->DoBindBufferBase(index, buffer);
       break;
-    case kBindBufferRange:
+    case BindIndexedBufferFunctionType::kBindBufferRange:
       bindings->DoBindBufferRange(index, buffer, offset, size);
       break;
     default:
@@ -6170,7 +6170,8 @@
 void GLES2DecoderImpl::DoBindBufferBase(GLenum target, GLuint index,
                                         GLuint client_id) {
   BindIndexedBufferImpl(target, index, client_id, 0, 0,
-                        kBindBufferBase, "glBindBufferBase");
+                        BindIndexedBufferFunctionType::kBindBufferBase,
+                        "glBindBufferBase");
 }
 
 void GLES2DecoderImpl::DoBindBufferRange(GLenum target, GLuint index,
@@ -6178,7 +6179,8 @@
                                          GLintptr offset,
                                          GLsizeiptr size) {
   BindIndexedBufferImpl(target, index, client_id, offset, size,
-                        kBindBufferRange, "glBindBufferRange");
+                        BindIndexedBufferFunctionType::kBindBufferRange,
+                        "glBindBufferRange");
 }
 
 bool GLES2DecoderImpl::BoundFramebufferAllowsChangesToAlphaChannel() {
@@ -10043,12 +10045,11 @@
       uniform_block_sizes, 1, func_name, "uniform buffers");
 }
 
-bool GLES2DecoderImpl::CheckUniformForApiType(
-    const Program::UniformInfo* info,
-    const char* function_name,
-    Program::UniformApiType api_type) {
+bool GLES2DecoderImpl::CheckUniformForApiType(const Program::UniformInfo* info,
+                                              const char* function_name,
+                                              UniformApiType api_type) {
   DCHECK(info);
-  if ((api_type & info->accepts_api_type) == 0) {
+  if ((api_type & info->accepts_api_type) == UniformApiType::kUniformNone) {
     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
                        "wrong uniform function for type");
     return false;
@@ -10056,13 +10057,12 @@
   return true;
 }
 
-bool GLES2DecoderImpl::PrepForSetUniformByLocation(
-    GLint fake_location,
-    const char* function_name,
-    Program::UniformApiType api_type,
-    GLint* real_location,
-    GLenum* type,
-    GLsizei* count) {
+bool GLES2DecoderImpl::PrepForSetUniformByLocation(GLint fake_location,
+                                                   const char* function_name,
+                                                   UniformApiType api_type,
+                                                   GLint* real_location,
+                                                   GLenum* type,
+                                                   GLsizei* count) {
   DCHECK(type);
   DCHECK(count);
   DCHECK(real_location);
@@ -10099,12 +10099,9 @@
   GLenum type = 0;
   GLsizei count = 1;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform1i",
-                                   Program::kUniform1i,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform1i",
+                                   UniformApiType::kUniform1i, &real_location,
+                                   &type, &count)) {
     return;
   }
   if (!state_.current_program->SetSamplers(
@@ -10121,12 +10118,9 @@
                                     const volatile GLint* values) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform1iv",
-                                   Program::kUniform1i,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform1iv",
+                                   UniformApiType::kUniform1i, &real_location,
+                                   &type, &count)) {
     return;
   }
   auto values_copy = std::make_unique<GLint[]>(count);
@@ -10149,12 +10143,9 @@
                                      const volatile GLuint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform1uiv",
-                                   Program::kUniform1ui,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform1uiv",
+                                   UniformApiType::kUniform1ui, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform1uivFn(real_location, count,
@@ -10166,12 +10157,9 @@
                                     const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform1fv",
-                                   Program::kUniform1f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform1fv",
+                                   UniformApiType::kUniform1f, &real_location,
+                                   &type, &count)) {
     return;
   }
   if (type == GL_BOOL) {
@@ -10191,12 +10179,9 @@
                                     const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform2fv",
-                                   Program::kUniform2f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform2fv",
+                                   UniformApiType::kUniform2f, &real_location,
+                                   &type, &count)) {
     return;
   }
   if (type == GL_BOOL_VEC2) {
@@ -10217,12 +10202,9 @@
                                     const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform3fv",
-                                   Program::kUniform3f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform3fv",
+                                   UniformApiType::kUniform3f, &real_location,
+                                   &type, &count)) {
     return;
   }
   if (type == GL_BOOL_VEC3) {
@@ -10243,12 +10225,9 @@
                                     const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform4fv",
-                                   Program::kUniform4f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform4fv",
+                                   UniformApiType::kUniform4f, &real_location,
+                                   &type, &count)) {
     return;
   }
   if (type == GL_BOOL_VEC4) {
@@ -10269,12 +10248,9 @@
                                     const volatile GLint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform2iv",
-                                   Program::kUniform2i,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform2iv",
+                                   UniformApiType::kUniform2i, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform2ivFn(real_location, count, const_cast<const GLint*>(value));
@@ -10285,12 +10261,9 @@
                                      const volatile GLuint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform2uiv",
-                                   Program::kUniform2ui,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform2uiv",
+                                   UniformApiType::kUniform2ui, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform2uivFn(real_location, count,
@@ -10302,12 +10275,9 @@
                                     const volatile GLint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform3iv",
-                                   Program::kUniform3i,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform3iv",
+                                   UniformApiType::kUniform3i, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform3ivFn(real_location, count, const_cast<const GLint*>(value));
@@ -10318,12 +10288,9 @@
                                      const volatile GLuint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform3uiv",
-                                   Program::kUniform3ui,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform3uiv",
+                                   UniformApiType::kUniform3ui, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform3uivFn(real_location, count,
@@ -10335,12 +10302,9 @@
                                     const volatile GLint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform4iv",
-                                   Program::kUniform4i,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform4iv",
+                                   UniformApiType::kUniform4i, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform4ivFn(real_location, count, const_cast<const GLint*>(value));
@@ -10351,12 +10315,9 @@
                                      const volatile GLuint* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniform4uiv",
-                                   Program::kUniform4ui,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniform4uiv",
+                                   UniformApiType::kUniform4ui, &real_location,
+                                   &type, &count)) {
     return;
   }
   api()->glUniform4uivFn(real_location, count,
@@ -10374,12 +10335,9 @@
         GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose not FALSE");
     return;
   }
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix2fv",
-                                   Program::kUniformMatrix2f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2fv",
+                                   UniformApiType::kUniformMatrix2f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix2fvFn(real_location, count, transpose,
@@ -10397,12 +10355,9 @@
         GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose not FALSE");
     return;
   }
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix3fv",
-                                   Program::kUniformMatrix3f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3fv",
+                                   UniformApiType::kUniformMatrix3f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix3fvFn(real_location, count, transpose,
@@ -10420,12 +10375,9 @@
         GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose not FALSE");
     return;
   }
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix4fv",
-                                   Program::kUniformMatrix4f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4fv",
+                                   UniformApiType::kUniformMatrix4f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix4fvFn(real_location, count, transpose,
@@ -10472,8 +10424,8 @@
   GLint real_location = -1;
   GLsizei count = 1;
   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4fv",
-                                   Program::kUniformMatrix4f, &real_location,
-                                   &type, &count)) {
+                                   UniformApiType::kUniformMatrix4f,
+                                   &real_location, &type, &count)) {
     return;
   }
 
@@ -10486,12 +10438,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix2x3fv",
-                                   Program::kUniformMatrix2x3f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2x3fv",
+                                   UniformApiType::kUniformMatrix2x3f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix2x3fvFn(real_location, count, transpose,
@@ -10504,12 +10453,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix2x4fv",
-                                   Program::kUniformMatrix2x4f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2x4fv",
+                                   UniformApiType::kUniformMatrix2x4f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix2x4fvFn(real_location, count, transpose,
@@ -10522,12 +10468,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix3x2fv",
-                                   Program::kUniformMatrix3x2f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3x2fv",
+                                   UniformApiType::kUniformMatrix3x2f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix3x2fvFn(real_location, count, transpose,
@@ -10540,12 +10483,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix3x4fv",
-                                   Program::kUniformMatrix3x4f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3x4fv",
+                                   UniformApiType::kUniformMatrix3x4f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix3x4fvFn(real_location, count, transpose,
@@ -10558,12 +10498,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix4x2fv",
-                                   Program::kUniformMatrix4x2f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4x2fv",
+                                   UniformApiType::kUniformMatrix4x2f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix4x2fvFn(real_location, count, transpose,
@@ -10576,12 +10513,9 @@
                                             const volatile GLfloat* value) {
   GLenum type = 0;
   GLint real_location = -1;
-  if (!PrepForSetUniformByLocation(fake_location,
-                                   "glUniformMatrix4x3fv",
-                                   Program::kUniformMatrix4x3f,
-                                   &real_location,
-                                   &type,
-                                   &count)) {
+  if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4x3fv",
+                                   UniformApiType::kUniformMatrix4x3f,
+                                   &real_location, &type, &count)) {
     return;
   }
   api()->glUniformMatrix4x3fvFn(real_location, count, transpose,
@@ -13118,13 +13052,13 @@
   if (!max_rect.Contains(rect)) {
     rect.Intersect(max_rect);
     if (!rect.IsEmpty()) {
-      std::unique_ptr<ScopedFramebufferCopyBinder> binder;
+      std::unique_ptr<ScopedFramebufferCopyBinder> copy_binder;
       if (workarounds()
               .use_copyteximage2d_instead_of_readpixels_on_multisampled_textures &&
           framebuffer_state_.bound_read_framebuffer.get() &&
           framebuffer_state_.bound_read_framebuffer.get()
               ->GetReadBufferIsMultisampledTexture()) {
-        binder = std::make_unique<ScopedFramebufferCopyBinder>(this);
+        copy_binder = std::make_unique<ScopedFramebufferCopyBinder>(this);
       }
       if (y < 0) {
         pixels += static_cast<uint32_t>(-y) * padded_row_size;;
@@ -13167,9 +13101,9 @@
       // a PIXEL_PACK_BUFFER is bound (in which case the client can
       // implement something similar on their own - all necessary functions
       // should be exposed).
-      GLuint buffer = 0;
-      api()->glGenBuffersARBFn(1, &buffer);
-      api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, buffer);
+      GLuint buffer_handle = 0;
+      api()->glGenBuffersARBFn(1, &buffer_handle);
+      api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, buffer_handle);
       // For ANGLE client version 2, GL_STREAM_READ is not available.
       const GLenum usage_hint =
           gl_version_info().is_angle ? GL_STATIC_DRAW : GL_STREAM_READ;
@@ -13186,13 +13120,13 @@
             &GLES2DecoderImpl::FinishReadPixels, weak_ptr_factory_.GetWeakPtr(),
             width, height, format, type, pixels_shm_id, pixels_shm_offset,
             result_shm_id, result_shm_offset, state_.pack_alignment,
-            read_format, buffer));
+            read_format, buffer_handle));
         api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, 0);
         return error::kNoError;
       } else {
         // On error, unbind pack buffer and fall through to sync readpixels
         api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, 0);
-        api()->glDeleteBuffersARBFn(1, &buffer);
+        api()->glDeleteBuffersARBFn(1, &buffer_handle);
       }
     }
     if (pixels_shm_id == 0 &&
@@ -13235,7 +13169,7 @@
         framebuffer_state_.bound_read_framebuffer.get() &&
         framebuffer_state_.bound_read_framebuffer.get()
             ->GetReadBufferIsMultisampledTexture()) {
-      ScopedFramebufferCopyBinder binder(this, x, y, width, height);
+      ScopedFramebufferCopyBinder copy_binder(this, x, y, width, height);
       api()->glReadPixelsFn(0, 0, width, height, format, type, pixels);
     } else {
       api()->glReadPixelsFn(x, y, width, height, format, type, pixels);
@@ -14917,9 +14851,19 @@
   }
 
   TextureManager::DoTexImageArguments args = {
-    target, level, internal_format, width, height, 1, border, format, type,
-    pixels, pixels_size, padding,
-    TextureManager::DoTexImageArguments::kTexImage2D };
+      target,
+      level,
+      internal_format,
+      width,
+      height,
+      1,
+      border,
+      format,
+      type,
+      pixels,
+      pixels_size,
+      padding,
+      TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
   texture_manager()->ValidateAndDoTexImage(
       &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
       func_name, args);
@@ -15015,9 +14959,19 @@
   }
 
   TextureManager::DoTexImageArguments args = {
-    target, level, internal_format, width, height, depth, border, format, type,
-    pixels, pixels_size, padding,
-    TextureManager::DoTexImageArguments::kTexImage3D };
+      target,
+      level,
+      internal_format,
+      width,
+      height,
+      depth,
+      border,
+      format,
+      type,
+      pixels,
+      pixels_size,
+      padding,
+      TextureManager::DoTexImageArguments::CommandType::kTexImage3D};
   texture_manager()->ValidateAndDoTexImage(
       &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
       func_name, args);
@@ -15398,7 +15352,7 @@
         nullptr,
         pixels_size,
         0,
-        TextureManager::DoTexImageArguments::kTexImage2D};
+        TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
     texture_manager()->WorkaroundCopyTexImageCubeMap(
         &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
         texture_ref, func_name, args);
@@ -15442,9 +15396,19 @@
         target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) {
       for (int i = 0; i < 2; ++i) {
         TextureManager::DoTexImageArguments args = {
-          target, i, final_internal_format, width, height, 1, border,
-          format, type, nullptr, pixels_size, 0,
-          TextureManager::DoTexImageArguments::kTexImage2D };
+            target,
+            i,
+            final_internal_format,
+            width,
+            height,
+            1,
+            border,
+            format,
+            type,
+            nullptr,
+            pixels_size,
+            0,
+            TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
         texture_manager()->WorkaroundCopyTexImageCubeMap(
             &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
             texture_ref, func_name, args);
@@ -15483,8 +15447,8 @@
       {
         // Copy from the read framebuffer into |temp_texture|.
         api()->glGenTexturesFn(1, &temp_texture);
-        ScopedTextureBinder binder(&state_, error_state_.get(), temp_texture,
-                                   source_texture_target);
+        ScopedTextureBinder texture_binder(&state_, error_state_.get(),
+                                           temp_texture, source_texture_target);
         api()->glCopyTexImage2DFn(source_texture_target, 0,
                                   temp_internal_format, x, y, width, height,
                                   border);
@@ -15513,9 +15477,19 @@
           texture->target() == GL_TEXTURE_CUBE_MAP &&
           target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) {
         TextureManager::DoTexImageArguments args = {
-          target, level, final_internal_format, width, height, 1, border,
-          format, type, nullptr, pixels_size, 0,
-          TextureManager::DoTexImageArguments::kTexImage2D };
+            target,
+            level,
+            final_internal_format,
+            width,
+            height,
+            1,
+            border,
+            format,
+            type,
+            nullptr,
+            pixels_size,
+            0,
+            TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
         texture_manager()->WorkaroundCopyTexImageCubeMap(
             &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
             texture_ref, func_name, args);
@@ -15831,9 +15805,20 @@
   }
 
   TextureManager::DoTexSubImageArguments args = {
-      target, level, xoffset, yoffset, 0, width, height, 1,
-      format, type, pixels, pixels_size, padding,
-      TextureManager::DoTexSubImageArguments::kTexSubImage2D};
+      target,
+      level,
+      xoffset,
+      yoffset,
+      0,
+      width,
+      height,
+      1,
+      format,
+      type,
+      pixels,
+      pixels_size,
+      padding,
+      TextureManager::DoTexSubImageArguments::CommandType::kTexSubImage2D};
   texture_manager()->ValidateAndDoTexSubImage(
       this, &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
       func_name, args);
@@ -15925,9 +15910,20 @@
   }
 
   TextureManager::DoTexSubImageArguments args = {
-      target, level, xoffset, yoffset, zoffset, width, height, depth,
-      format, type, pixels, pixels_size, padding,
-      TextureManager::DoTexSubImageArguments::kTexSubImage3D};
+      target,
+      level,
+      xoffset,
+      yoffset,
+      zoffset,
+      width,
+      height,
+      depth,
+      format,
+      type,
+      pixels,
+      pixels_size,
+      padding,
+      TextureManager::DoTexSubImageArguments::CommandType::kTexSubImage3D};
   texture_manager()->ValidateAndDoTexSubImage(
       this, &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
       func_name, args);
@@ -17824,11 +17820,11 @@
   // GL_TEXTURE_EXTERNAL_OES texture requires that we apply a transform matrix
   // before presenting.
   if (source_target == GL_TEXTURE_EXTERNAL_OES) {
-    if (GLStreamTextureImage* image =
+    if (GLStreamTextureImage* texture_image =
             source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
                                                        source_level)) {
       GLfloat transform_matrix[16];
-      image->GetTextureMatrix(transform_matrix);
+      texture_image->GetTextureMatrix(transform_matrix);
       copy_texture_chromium_->DoCopyTextureWithTransform(
           this, source_target, source_texture->service_id(), source_level,
           source_internal_format, dest_target, dest_texture->service_id(),
@@ -18036,11 +18032,11 @@
   // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
   // before presenting.
   if (source_target == GL_TEXTURE_EXTERNAL_OES) {
-    if (GLStreamTextureImage* image =
+    if (GLStreamTextureImage* texture_image =
             source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
                                                        source_level)) {
       GLfloat transform_matrix[16];
-      image->GetTextureMatrix(transform_matrix);
+      texture_image->GetTextureMatrix(transform_matrix);
       copy_texture_chromium_->DoCopySubTextureWithTransform(
           this, source_target, source_texture->service_id(), source_level,
           source_internal_format, dest_target, dest_texture->service_id(),
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 4243533..fac3406 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -125,7 +125,7 @@
   }
 
   if (create_if_missing) {
-    GLuint service_id = 0;
+    service_id = 0;
     api->glGenTexturesFn(1, &service_id);
     resources->texture_id_map.SetIDMapping(client_id, service_id);
     return service_id;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
index 4c5b2ff..248497a4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -36,7 +36,7 @@
   GLES2DecoderTest2() = default;
 
   void TestAcceptedUniform(GLenum uniform_type,
-                           uint32_t accepts_apis,
+                           UniformApiType accepts_apis,
                            bool es3_enabled) {
     SetupShaderForUniform(uniform_type);
     bool valid_uniform = false;
@@ -71,7 +71,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform1i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform1i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform1i cmd;
       cmd.Init(1, 2);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -80,7 +81,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform1i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform1i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform1ivImmediate& cmd =
           *GetImmediateAs<cmds::Uniform1ivImmediate>();
       GLint data[2][1] = {{0}};
@@ -91,7 +93,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform2i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform2i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform2i cmd;
       cmd.Init(1, 2, 3);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -100,7 +103,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform2i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform2i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform2ivImmediate& cmd =
           *GetImmediateAs<cmds::Uniform2ivImmediate>();
       GLint data[2][2] = {{0}};
@@ -111,7 +115,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform3i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform3i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform3i cmd;
       cmd.Init(1, 2, 3, 4);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -120,7 +125,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform3i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform3i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform3ivImmediate& cmd =
           *GetImmediateAs<cmds::Uniform3ivImmediate>();
       GLint data[2][3] = {{0}};
@@ -131,7 +137,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform4i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform4i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform4i cmd;
       cmd.Init(1, 2, 3, 4, 5);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -140,7 +147,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform4i;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform4i) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform4ivImmediate& cmd =
           *GetImmediateAs<cmds::Uniform4ivImmediate>();
       GLint data[2][4] = {{0}};
@@ -153,7 +161,8 @@
     ////////////////////
 
     {
-      valid_uniform = accepts_apis & Program::kUniform1f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform1f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform1f cmd;
       cmd.Init(1, 2);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -162,7 +171,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform1f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform1f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform1fvImmediate& cmd =
           *GetImmediateAs<cmds::Uniform1fvImmediate>();
       GLfloat data[2][1] = {{0.0f}};
@@ -173,7 +183,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform2f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform2f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform2f cmd;
       cmd.Init(1, 2, 3);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -182,7 +193,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform2f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform2f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform2fvImmediate& cmd =
           *GetImmediateAs<cmds::Uniform2fvImmediate>();
       GLfloat data[2][2] = {{0.0f}};
@@ -193,7 +205,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform3f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform3f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform3f cmd;
       cmd.Init(1, 2, 3, 4);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -202,7 +215,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform3f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform3f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform3fvImmediate& cmd =
           *GetImmediateAs<cmds::Uniform3fvImmediate>();
       GLfloat data[2][3] = {{0.0f}};
@@ -213,7 +227,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform4f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform4f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform4f cmd;
       cmd.Init(1, 2, 3, 4, 5);
       EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -222,7 +237,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniform4f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniform4f) !=
+                      UniformApiType::kUniformNone;
       cmds::Uniform4fvImmediate& cmd =
           *GetImmediateAs<cmds::Uniform4fvImmediate>();
       GLfloat data[2][4] = {{0.0f}};
@@ -233,7 +249,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniformMatrix2f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2f) !=
+                      UniformApiType::kUniformNone;
       cmds::UniformMatrix2fvImmediate& cmd =
           *GetImmediateAs<cmds::UniformMatrix2fvImmediate>();
       GLfloat data[2][2 * 2] = {{0.0f}};
@@ -245,7 +262,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniformMatrix3f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3f) !=
+                      UniformApiType::kUniformNone;
       cmds::UniformMatrix3fvImmediate& cmd =
           *GetImmediateAs<cmds::UniformMatrix3fvImmediate>();
       GLfloat data[2][3 * 3] = {{0.0f}};
@@ -256,7 +274,8 @@
     }
 
     {
-      valid_uniform = accepts_apis & Program::kUniformMatrix4f;
+      valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4f) !=
+                      UniformApiType::kUniformNone;
       cmds::UniformMatrix4fvImmediate& cmd =
           *GetImmediateAs<cmds::UniformMatrix4fvImmediate>();
       GLfloat data[2][4 * 4] = {{0.0f}};
@@ -268,7 +287,8 @@
 
     if (!es3_enabled) {
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2fvImmediate>();
         GLfloat data[2][2 * 2] = {{0.0f}};
@@ -279,7 +299,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3fvImmediate>();
         GLfloat data[2][3 * 3] = {{0.0f}};
@@ -289,7 +310,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4fvImmediate>();
         GLfloat data[2][4 * 4] = {{0.0f}};
@@ -301,7 +323,8 @@
 
     if (es3_enabled) {
       {
-        valid_uniform = accepts_apis & Program::kUniform1ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform1ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform1ui cmd;
         cmd.Init(1, 2);
         EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -310,7 +333,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform1ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform1ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform1uivImmediate& cmd =
             *GetImmediateAs<cmds::Uniform1uivImmediate>();
         GLuint data[2][1] = {{0}};
@@ -321,7 +345,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform2ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform2ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform2ui cmd;
         cmd.Init(1, 2, 3);
         EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -330,7 +355,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform2ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform2ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform2uivImmediate& cmd =
             *GetImmediateAs<cmds::Uniform2uivImmediate>();
         GLuint data[2][2] = {{0}};
@@ -341,7 +367,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform3ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform3ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform3ui cmd;
         cmd.Init(1, 2, 3, 4);
         EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -350,7 +377,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform3ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform3ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform3uivImmediate& cmd =
             *GetImmediateAs<cmds::Uniform3uivImmediate>();
         GLuint data[2][3] = {{0}};
@@ -361,7 +389,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform4ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform4ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform4ui cmd;
         cmd.Init(1, 2, 3, 4, 5);
         EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -370,7 +399,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniform4ui;
+        valid_uniform = (accepts_apis & UniformApiType::kUniform4ui) !=
+                        UniformApiType::kUniformNone;
         cmds::Uniform4uivImmediate& cmd =
             *GetImmediateAs<cmds::Uniform4uivImmediate>();
         GLuint data[2][4] = {{0}};
@@ -381,7 +411,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2x3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2x3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2x3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2x3fvImmediate>();
         GLfloat data[2][2 * 3] = {{0.0f}};
@@ -393,7 +424,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2x4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2x4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2x4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2x4fvImmediate>();
         GLfloat data[2][2 * 4] = {{0.0f}};
@@ -405,7 +437,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3x2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3x2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3x2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3x2fvImmediate>();
         GLfloat data[2][3 * 2] = {{0.0f}};
@@ -417,7 +450,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3x4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3x4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3x4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3x4fvImmediate>();
         GLfloat data[2][3 * 4] = {{0.0f}};
@@ -429,7 +463,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4x2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4x2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4x2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4x2fvImmediate>();
         GLfloat data[2][4 * 2] = {{0.0f}};
@@ -441,7 +476,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4x3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4x3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4x3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4x3fvImmediate>();
         GLfloat data[2][4 * 3] = {{0.0f}};
@@ -453,7 +489,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2fvImmediate>();
         GLfloat data[2][2 * 2] = {{0.0f}};
@@ -465,7 +502,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3fvImmediate>();
         GLfloat data[2][3 * 3] = {{0.0f}};
@@ -476,7 +514,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4fvImmediate>();
         GLfloat data[2][4 * 4] = {{0.0f}};
@@ -487,7 +526,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2x3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2x3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2x3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2x3fvImmediate>();
         GLfloat data[2][2 * 3] = {{0.0f}};
@@ -499,7 +539,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix2x4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix2x4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix2x4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix2x4fvImmediate>();
         GLfloat data[2][2 * 4] = {{0.0f}};
@@ -511,7 +552,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3x2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3x2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3x2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3x2fvImmediate>();
         GLfloat data[2][3 * 2] = {{0.0f}};
@@ -523,7 +565,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix3x4f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix3x4f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix3x4fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix3x4fvImmediate>();
         GLfloat data[2][3 * 4] = {{0.0f}};
@@ -535,7 +578,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4x2f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4x2f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4x2fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4x2fvImmediate>();
         GLfloat data[2][4 * 2] = {{0.0f}};
@@ -547,7 +591,8 @@
       }
 
       {
-        valid_uniform = accepts_apis & Program::kUniformMatrix4x3f;
+        valid_uniform = (accepts_apis & UniformApiType::kUniformMatrix4x3f) !=
+                        UniformApiType::kUniformNone;
         cmds::UniformMatrix4x3fvImmediate& cmd =
             *GetImmediateAs<cmds::UniformMatrix4x3fvImmediate>();
         GLfloat data[2][4 * 3] = {{0.0f}};
@@ -908,137 +953,145 @@
 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h"
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT) {
-  TestAcceptedUniform(GL_INT, Program::kUniform1i, false);
+  TestAcceptedUniform(GL_INT, UniformApiType::kUniform1i, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC2) {
-  TestAcceptedUniform(GL_INT_VEC2, Program::kUniform2i, false);
+  TestAcceptedUniform(GL_INT_VEC2, UniformApiType::kUniform2i, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC3) {
-  TestAcceptedUniform(GL_INT_VEC3, Program::kUniform3i, false);
+  TestAcceptedUniform(GL_INT_VEC3, UniformApiType::kUniform3i, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC4) {
-  TestAcceptedUniform(GL_INT_VEC4, Program::kUniform4i, false);
+  TestAcceptedUniform(GL_INT_VEC4, UniformApiType::kUniform4i, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL) {
   TestAcceptedUniform(
-      GL_BOOL, Program::kUniform1i | Program::kUniform1f, false);
+      GL_BOOL, UniformApiType::kUniform1i | UniformApiType::kUniform1f, false);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniformES3_GL_BOOL) {
-  TestAcceptedUniform(
-      GL_BOOL,
-      Program::kUniform1i | Program::kUniform1f | Program::kUniform1ui,
-      true);
+  TestAcceptedUniform(GL_BOOL,
+                      UniformApiType::kUniform1i | UniformApiType::kUniform1f |
+                          UniformApiType::kUniform1ui,
+                      true);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC2) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC2, Program::kUniform2i | Program::kUniform2f, false);
+  TestAcceptedUniform(GL_BOOL_VEC2,
+                      UniformApiType::kUniform2i | UniformApiType::kUniform2f,
+                      false);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniformES3_GL_BOOL_VEC2) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC2,
-      Program::kUniform2i | Program::kUniform2f | Program::kUniform2ui,
-      true);
+  TestAcceptedUniform(GL_BOOL_VEC2,
+                      UniformApiType::kUniform2i | UniformApiType::kUniform2f |
+                          UniformApiType::kUniform2ui,
+                      true);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC3) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC3, Program::kUniform3i | Program::kUniform3f, false);
+  TestAcceptedUniform(GL_BOOL_VEC3,
+                      UniformApiType::kUniform3i | UniformApiType::kUniform3f,
+                      false);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniformES3_GL_BOOL_VEC3) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC3,
-      Program::kUniform3i | Program::kUniform3f | Program::kUniform3ui,
-      true);
+  TestAcceptedUniform(GL_BOOL_VEC3,
+                      UniformApiType::kUniform3i | UniformApiType::kUniform3f |
+                          UniformApiType::kUniform3ui,
+                      true);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC4) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC4, Program::kUniform4i | Program::kUniform4f, false);
+  TestAcceptedUniform(GL_BOOL_VEC4,
+                      UniformApiType::kUniform4i | UniformApiType::kUniform4f,
+                      false);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniformES3_GL_BOOL_VEC4) {
-  TestAcceptedUniform(
-      GL_BOOL_VEC4,
-      Program::kUniform4i | Program::kUniform4f | Program::kUniform4ui,
-      true);
+  TestAcceptedUniform(GL_BOOL_VEC4,
+                      UniformApiType::kUniform4i | UniformApiType::kUniform4f |
+                          UniformApiType::kUniform4ui,
+                      true);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniformTypeFLOAT) {
-  TestAcceptedUniform(GL_FLOAT, Program::kUniform1f, false);
+  TestAcceptedUniform(GL_FLOAT, UniformApiType::kUniform1f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC2) {
-  TestAcceptedUniform(GL_FLOAT_VEC2, Program::kUniform2f, false);
+  TestAcceptedUniform(GL_FLOAT_VEC2, UniformApiType::kUniform2f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC3) {
-  TestAcceptedUniform(GL_FLOAT_VEC3, Program::kUniform3f, false);
+  TestAcceptedUniform(GL_FLOAT_VEC3, UniformApiType::kUniform3f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC4) {
-  TestAcceptedUniform(GL_FLOAT_VEC4, Program::kUniform4f, false);
+  TestAcceptedUniform(GL_FLOAT_VEC4, UniformApiType::kUniform4f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT2) {
-  TestAcceptedUniform(GL_FLOAT_MAT2, Program::kUniformMatrix2f, false);
+  TestAcceptedUniform(GL_FLOAT_MAT2, UniformApiType::kUniformMatrix2f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT3) {
-  TestAcceptedUniform(GL_FLOAT_MAT3, Program::kUniformMatrix3f, false);
+  TestAcceptedUniform(GL_FLOAT_MAT3, UniformApiType::kUniformMatrix3f, false);
 }
 
 TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT4) {
-  TestAcceptedUniform(GL_FLOAT_MAT4, Program::kUniformMatrix4f, false);
+  TestAcceptedUniform(GL_FLOAT_MAT4, UniformApiType::kUniformMatrix4f, false);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_UNSIGNED_INT) {
-  TestAcceptedUniform(GL_UNSIGNED_INT, Program::kUniform1ui, true);
+  TestAcceptedUniform(GL_UNSIGNED_INT, UniformApiType::kUniform1ui, true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_UNSIGNED_INT_VEC2) {
-  TestAcceptedUniform(GL_UNSIGNED_INT_VEC2, Program::kUniform2ui, true);
+  TestAcceptedUniform(GL_UNSIGNED_INT_VEC2, UniformApiType::kUniform2ui, true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_UNSIGNED_INT_VEC3) {
-  TestAcceptedUniform(GL_UNSIGNED_INT_VEC3, Program::kUniform3ui, true);
+  TestAcceptedUniform(GL_UNSIGNED_INT_VEC3, UniformApiType::kUniform3ui, true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_UNSIGNED_INT_VEC4) {
-  TestAcceptedUniform(GL_UNSIGNED_INT_VEC4, Program::kUniform4ui, true);
+  TestAcceptedUniform(GL_UNSIGNED_INT_VEC4, UniformApiType::kUniform4ui, true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT2x3) {
-  TestAcceptedUniform(GL_FLOAT_MAT2x3, Program::kUniformMatrix2x3f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT2x3, UniformApiType::kUniformMatrix2x3f,
+                      true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT2x4) {
-  TestAcceptedUniform(GL_FLOAT_MAT2x4, Program::kUniformMatrix2x4f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT2x4, UniformApiType::kUniformMatrix2x4f,
+                      true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT3x2) {
-  TestAcceptedUniform(GL_FLOAT_MAT3x2, Program::kUniformMatrix3x2f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT3x2, UniformApiType::kUniformMatrix3x2f,
+                      true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT3x4) {
-  TestAcceptedUniform(GL_FLOAT_MAT3x4, Program::kUniformMatrix3x4f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT3x4, UniformApiType::kUniformMatrix3x4f,
+                      true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT4x2) {
-  TestAcceptedUniform(GL_FLOAT_MAT4x2, Program::kUniformMatrix4x2f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT4x2, UniformApiType::kUniformMatrix4x2f,
+                      true);
 }
 
 TEST_P(GLES3DecoderTest2, AcceptsUniform_GL_FLOAT_MAT4x3) {
-  TestAcceptedUniform(GL_FLOAT_MAT4x3, Program::kUniformMatrix4x3f, true);
+  TestAcceptedUniform(GL_FLOAT_MAT4x3, UniformApiType::kUniformMatrix4x3f,
+                      true);
 }
 
 }  // namespace gles2
 }  // namespace gpu
-
diff --git a/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc b/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc
index 78631ec29..ddd9240 100644
--- a/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc
+++ b/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc
@@ -25,7 +25,7 @@
 
   srgb_converter_program_ = glCreateProgram();
 
-  const char* kShaderPrecisionPreamble =
+  const char* kShaderPreamble =
       "#ifdef GL_ES\n"
       "precision mediump float;\n"
       "#define TexCoordPrecision mediump\n"
@@ -52,7 +52,7 @@
         "#define VARYING out\n";
   }
 
-  vs_source += kShaderPrecisionPreamble;
+  vs_source += kShaderPreamble;
 
   // TODO(yizhou): gles 2.0 does not support gl_VertexID.
   // Compile the vertex shader
@@ -102,7 +102,7 @@
     fs_source += "#version 150\n";
   }
 
-  fs_source += kShaderPrecisionPreamble;
+  fs_source += kShaderPreamble;
 
   if (feature_info_->gl_version_info().is_es) {
     if (feature_info_->gl_version_info().is_es3) {
diff --git a/gpu/command_buffer/service/indexed_buffer_binding_host.cc b/gpu/command_buffer/service/indexed_buffer_binding_host.cc
index 07d0e92..73170d19 100644
--- a/gpu/command_buffer/service/indexed_buffer_binding_host.cc
+++ b/gpu/command_buffer/service/indexed_buffer_binding_host.cc
@@ -10,11 +10,10 @@
 namespace gles2 {
 
 IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding()
-    : type(kBindBufferNone),
+    : type(IndexedBufferBindingType::kBindBufferNone),
       offset(0),
       size(0),
-      effective_full_buffer_size(0) {
-}
+      effective_full_buffer_size(0) {}
 
 IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding(
     const IndexedBufferBindingHost::IndexedBufferBinding& other)
@@ -30,7 +29,8 @@
 
 bool IndexedBufferBindingHost::IndexedBufferBinding::operator==(
     const IndexedBufferBindingHost::IndexedBufferBinding& other) const {
-  if (type == kBindBufferNone && other.type == kBindBufferNone) {
+  if (type == IndexedBufferBindingType::kBindBufferNone &&
+      other.type == IndexedBufferBindingType::kBindBufferNone) {
     // This should be the most common case so an early out.
     return true;
   }
@@ -47,7 +47,7 @@
     Reset();
     return;
   }
-  type = kBindBufferBase;
+  type = IndexedBufferBindingType::kBindBufferBase;
   buffer = _buffer;
   offset = 0;
   size = 0;
@@ -60,7 +60,7 @@
     Reset();
     return;
   }
-  type = kBindBufferRange;
+  type = IndexedBufferBindingType::kBindBufferRange;
   buffer = _buffer;
   offset = _offset;
   size = _size;
@@ -68,7 +68,7 @@
 }
 
 void IndexedBufferBindingHost::IndexedBufferBinding::Reset() {
-  type = kBindBufferNone;
+  type = IndexedBufferBindingType::kBindBufferNone;
   buffer = nullptr;
   offset = 0;
   size = 0;
@@ -191,7 +191,8 @@
     for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) {
       if (buffer_bindings_[ii].buffer.get() != buffer)
         continue;
-      if (buffer_bindings_[ii].type == kBindBufferRange &&
+      if (buffer_bindings_[ii].type ==
+              IndexedBufferBindingType::kBindBufferRange &&
           buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) {
         DoAdjustedBindBufferRange(target_, ii, buffer->service_id(),
                                   buffer_bindings_[ii].offset,
@@ -230,7 +231,9 @@
     // is bound, we might need to reset the ranges.
     for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) {
       Buffer* buffer = buffer_bindings_[ii].buffer.get();
-      if (buffer && buffer_bindings_[ii].type == kBindBufferRange &&
+      if (buffer &&
+          buffer_bindings_[ii].type ==
+              IndexedBufferBindingType::kBindBufferRange &&
           buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) {
         DoAdjustedBindBufferRange(target_, ii, buffer->service_id(),
                                   buffer_bindings_[ii].offset,
@@ -273,13 +276,13 @@
     return 0;
   GLsizeiptr full_buffer_size = binding.buffer->size();
   switch (binding.type) {
-    case kBindBufferBase:
+    case IndexedBufferBindingType::kBindBufferBase:
       return full_buffer_size;
-    case kBindBufferRange:
+    case IndexedBufferBindingType::kBindBufferRange:
       if (binding.offset + binding.size > full_buffer_size)
         return full_buffer_size - binding.offset;
       return binding.size;
-    case kBindBufferNone:
+    case IndexedBufferBindingType::kBindBufferNone:
       return 0;
   }
   return buffer_bindings_[index].size;
@@ -303,11 +306,11 @@
       continue;
     }
     switch (buffer_bindings_[ii].type) {
-      case kBindBufferBase:
-      case kBindBufferNone:
+      case IndexedBufferBindingType::kBindBufferBase:
+      case IndexedBufferBindingType::kBindBufferNone:
         DoBindBufferBase(ii, buffer_bindings_[ii].buffer.get());
         break;
-      case kBindBufferRange:
+      case IndexedBufferBindingType::kBindBufferRange:
         DoBindBufferRange(ii, buffer_bindings_[ii].buffer.get(),
                           buffer_bindings_[ii].offset,
                           buffer_bindings_[ii].size);
diff --git a/gpu/command_buffer/service/indexed_buffer_binding_host.h b/gpu/command_buffer/service/indexed_buffer_binding_host.h
index b28018d..03aaa5f 100644
--- a/gpu/command_buffer/service/indexed_buffer_binding_host.h
+++ b/gpu/command_buffer/service/indexed_buffer_binding_host.h
@@ -81,7 +81,7 @@
   bool do_buffer_refcounting_;
 
  private:
-  enum IndexedBufferBindingType {
+  enum class IndexedBufferBindingType {
     kBindBufferBase,
     kBindBufferRange,
     kBindBufferNone
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index 5d98b20..28d0dad5 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -250,7 +250,7 @@
 Program::UniformInfo::UniformInfo()
     : size(0),
       type(GL_NONE),
-      accepts_api_type(0),
+      accepts_api_type(UniformApiType::kUniformNone),
       fake_location_base(0),
       is_array(false) {}
 
@@ -261,91 +261,99 @@
                                   const std::vector<GLint>& service_locations)
     : size(service_locations.size()),
       type(_type),
-      accepts_api_type(0),
+      accepts_api_type(UniformApiType::kUniformNone),
       fake_location_base(client_location_base),
       is_array(_is_array),
       name(client_name),
       element_locations(service_locations) {
   switch (type) {
     case GL_INT:
-      accepts_api_type = kUniform1i;
+      accepts_api_type = UniformApiType::kUniform1i;
       break;
     case GL_INT_VEC2:
-      accepts_api_type = kUniform2i;
+      accepts_api_type = UniformApiType::kUniform2i;
       break;
     case GL_INT_VEC3:
-      accepts_api_type = kUniform3i;
+      accepts_api_type = UniformApiType::kUniform3i;
       break;
     case GL_INT_VEC4:
-      accepts_api_type = kUniform4i;
+      accepts_api_type = UniformApiType::kUniform4i;
       break;
 
     case GL_UNSIGNED_INT:
-      accepts_api_type = kUniform1ui;
+      accepts_api_type = UniformApiType::kUniform1ui;
       break;
     case GL_UNSIGNED_INT_VEC2:
-      accepts_api_type = kUniform2ui;
+      accepts_api_type = UniformApiType::kUniform2ui;
       break;
     case GL_UNSIGNED_INT_VEC3:
-      accepts_api_type = kUniform3ui;
+      accepts_api_type = UniformApiType::kUniform3ui;
       break;
     case GL_UNSIGNED_INT_VEC4:
-      accepts_api_type = kUniform4ui;
+      accepts_api_type = UniformApiType::kUniform4ui;
       break;
 
     case GL_BOOL:
-      accepts_api_type = kUniform1i | kUniform1ui | kUniform1f;
+      accepts_api_type = UniformApiType::kUniform1i |
+                         UniformApiType::kUniform1ui |
+                         UniformApiType::kUniform1f;
       break;
     case GL_BOOL_VEC2:
-      accepts_api_type = kUniform2i | kUniform2ui | kUniform2f;
+      accepts_api_type = UniformApiType::kUniform2i |
+                         UniformApiType::kUniform2ui |
+                         UniformApiType::kUniform2f;
       break;
     case GL_BOOL_VEC3:
-      accepts_api_type = kUniform3i | kUniform3ui | kUniform3f;
+      accepts_api_type = UniformApiType::kUniform3i |
+                         UniformApiType::kUniform3ui |
+                         UniformApiType::kUniform3f;
       break;
     case GL_BOOL_VEC4:
-      accepts_api_type = kUniform4i | kUniform4ui | kUniform4f;
+      accepts_api_type = UniformApiType::kUniform4i |
+                         UniformApiType::kUniform4ui |
+                         UniformApiType::kUniform4f;
       break;
 
     case GL_FLOAT:
-      accepts_api_type = kUniform1f;
+      accepts_api_type = UniformApiType::kUniform1f;
       break;
     case GL_FLOAT_VEC2:
-      accepts_api_type = kUniform2f;
+      accepts_api_type = UniformApiType::kUniform2f;
       break;
     case GL_FLOAT_VEC3:
-      accepts_api_type = kUniform3f;
+      accepts_api_type = UniformApiType::kUniform3f;
       break;
     case GL_FLOAT_VEC4:
-      accepts_api_type = kUniform4f;
+      accepts_api_type = UniformApiType::kUniform4f;
       break;
 
     case GL_FLOAT_MAT2:
-      accepts_api_type = kUniformMatrix2f;
+      accepts_api_type = UniformApiType::kUniformMatrix2f;
       break;
     case GL_FLOAT_MAT3:
-      accepts_api_type = kUniformMatrix3f;
+      accepts_api_type = UniformApiType::kUniformMatrix3f;
       break;
     case GL_FLOAT_MAT4:
-      accepts_api_type = kUniformMatrix4f;
+      accepts_api_type = UniformApiType::kUniformMatrix4f;
       break;
 
     case GL_FLOAT_MAT2x3:
-      accepts_api_type = kUniformMatrix2x3f;
+      accepts_api_type = UniformApiType::kUniformMatrix2x3f;
       break;
     case GL_FLOAT_MAT2x4:
-      accepts_api_type = kUniformMatrix2x4f;
+      accepts_api_type = UniformApiType::kUniformMatrix2x4f;
       break;
     case GL_FLOAT_MAT3x2:
-      accepts_api_type = kUniformMatrix3x2f;
+      accepts_api_type = UniformApiType::kUniformMatrix3x2f;
       break;
     case GL_FLOAT_MAT3x4:
-      accepts_api_type = kUniformMatrix3x4f;
+      accepts_api_type = UniformApiType::kUniformMatrix3x4f;
       break;
     case GL_FLOAT_MAT4x2:
-      accepts_api_type = kUniformMatrix4x2f;
+      accepts_api_type = UniformApiType::kUniformMatrix4x2f;
       break;
     case GL_FLOAT_MAT4x3:
-      accepts_api_type = kUniformMatrix4x3f;
+      accepts_api_type = UniformApiType::kUniformMatrix4x3f;
       break;
 
     case GL_SAMPLER_2D:
@@ -365,7 +373,7 @@
     case GL_UNSIGNED_INT_SAMPLER_3D:
     case GL_UNSIGNED_INT_SAMPLER_CUBE:
     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
-      accepts_api_type = kUniform1i;
+      accepts_api_type = UniformApiType::kUniform1i;
       break;
 
     default:
@@ -1115,7 +1123,7 @@
       std::string client_element_name =
           parsed_client_name.base_name() + array_spec;
 
-      auto it = bind_fragment_input_location_map_.find(client_element_name);
+      it = bind_fragment_input_location_map_.find(client_element_name);
       if (it != bind_fragment_input_location_map_.end() && it->second >= 0) {
         size_t client_location = static_cast<size_t>(it->second);
         std::string service_element_name =
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index b4646ba0..b9847df 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -35,6 +35,39 @@
 class Shader;
 class ShaderManager;
 
+enum class UniformApiType : uint32_t {
+  kUniformNone = 0,
+  kUniform1i = 1 << 0,
+  kUniform2i = 1 << 1,
+  kUniform3i = 1 << 2,
+  kUniform4i = 1 << 3,
+  kUniform1f = 1 << 4,
+  kUniform2f = 1 << 5,
+  kUniform3f = 1 << 6,
+  kUniform4f = 1 << 7,
+  kUniformMatrix2f = 1 << 8,
+  kUniformMatrix3f = 1 << 9,
+  kUniformMatrix4f = 1 << 10,
+  kUniform1ui = 1 << 11,
+  kUniform2ui = 1 << 12,
+  kUniform3ui = 1 << 13,
+  kUniform4ui = 1 << 14,
+  kUniformMatrix2x3f = 1 << 15,
+  kUniformMatrix2x4f = 1 << 16,
+  kUniformMatrix3x2f = 1 << 17,
+  kUniformMatrix3x4f = 1 << 18,
+  kUniformMatrix4x2f = 1 << 19,
+  kUniformMatrix4x3f = 1 << 20,
+};
+
+inline constexpr UniformApiType operator|(UniformApiType a, UniformApiType b) {
+  return static_cast<UniformApiType>(uint32_t(a) | uint32_t(b));
+}
+
+inline constexpr UniformApiType operator&(UniformApiType a, UniformApiType b) {
+  return static_cast<UniformApiType>(uint32_t(a) & uint32_t(b));
+}
+
 // This is used to track which attributes a particular program needs
 // so we can verify at glDrawXXX time that every attribute is either disabled
 // or if enabled that it points to a valid source.
@@ -42,35 +75,8 @@
  public:
   static const int kMaxAttachedShaders = 2;
 
-  enum VaryingsPackingOption {
-    kCountOnlyStaticallyUsed,
-    kCountAll
-  };
+  enum VaryingsPackingOption { kCountOnlyStaticallyUsed, kCountAll };
 
-  enum UniformApiType {
-    kUniformNone = 0,
-    kUniform1i = 1 << 0,
-    kUniform2i = 1 << 1,
-    kUniform3i = 1 << 2,
-    kUniform4i = 1 << 3,
-    kUniform1f = 1 << 4,
-    kUniform2f = 1 << 5,
-    kUniform3f = 1 << 6,
-    kUniform4f = 1 << 7,
-    kUniformMatrix2f = 1 << 8,
-    kUniformMatrix3f = 1 << 9,
-    kUniformMatrix4f = 1 << 10,
-    kUniform1ui = 1 << 11,
-    kUniform2ui = 1 << 12,
-    kUniform3ui = 1 << 13,
-    kUniform4ui = 1 << 14,
-    kUniformMatrix2x3f = 1 << 15,
-    kUniformMatrix2x4f = 1 << 16,
-    kUniformMatrix3x2f = 1 << 17,
-    kUniformMatrix3x4f = 1 << 18,
-    kUniformMatrix4x2f = 1 << 19,
-    kUniformMatrix4x3f = 1 << 20,
-  };
   struct FragmentInputInfo {
     FragmentInputInfo(GLenum _type, GLuint _location)
         : type(_type), location(_location) {}
@@ -125,7 +131,7 @@
 
     GLsizei size;
     GLenum type;
-    uint32_t accepts_api_type;
+    UniformApiType accepts_api_type;
     GLint fake_location_base;
     bool is_array;
     std::string name;
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 775a118..6ad44fd 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -1941,9 +1941,8 @@
                              gr_context());
 
   gles2::Texture::ImageState image_state;
-  gl::GLImage* image =
-      source_texture->GetLevelImage(source_target, 0, &image_state);
-  if (image) {
+  if (gl::GLImage* image =
+          source_texture->GetLevelImage(source_target, 0, &image_state)) {
     base::Optional<ScopedPixelUnpackState> pixel_unpack_state;
     if (image->GetType() == gl::GLImage::Type::MEMORY &&
         shared_context_state_->need_context_state_reset()) {
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index fd43b32..a39c21c 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -2759,9 +2759,9 @@
                                       const DoTexImageArguments& args,
                                       TextureRef** texture_ref) {
   const Validators* validators = feature_info_->validators();
-  if (((args.command_type == DoTexImageArguments::kTexImage2D) &&
+  if (((args.command_type == DoTexImageArguments::CommandType::kTexImage2D) &&
        !validators->texture_target.IsValid(args.target)) ||
-      ((args.command_type == DoTexImageArguments::kTexImage3D) &&
+      ((args.command_type == DoTexImageArguments::CommandType::kTexImage3D) &&
        !validators->texture_3_d_target.IsValid(args.target))) {
     ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
         error_state, function_name, args.target, "target");
@@ -2956,7 +2956,7 @@
   if (texture_state->unpack_overlapping_rows_separately_unpack_buffer &&
       buffer) {
     ContextState::Dimension dimension =
-        (args.command_type == DoTexImageArguments::kTexImage3D)
+        (args.command_type == DoTexImageArguments::CommandType::kTexImage3D)
             ? ContextState::k3D
             : ContextState::k2D;
     const PixelStoreParams unpack_params(state->GetUnpackParams(dimension));
@@ -2970,11 +2970,22 @@
                                 args);
 
       DoTexSubImageArguments sub_args = {
-          args.target, args.level, 0, 0, 0, args.width, args.height, args.depth,
-          args.format, args.type, args.pixels, args.pixels_size, args.padding,
-          args.command_type == DoTexImageArguments::kTexImage3D
-              ? DoTexSubImageArguments::kTexSubImage3D
-              : DoTexSubImageArguments::kTexSubImage2D};
+          args.target,
+          args.level,
+          0,
+          0,
+          0,
+          args.width,
+          args.height,
+          args.depth,
+          args.format,
+          args.type,
+          args.pixels,
+          args.pixels_size,
+          args.padding,
+          args.command_type == DoTexImageArguments::CommandType::kTexImage3D
+              ? DoTexSubImageArguments::CommandType::kTexSubImage3D
+              : DoTexSubImageArguments::CommandType::kTexSubImage2D};
       DoTexSubImageRowByRowWorkaround(texture_state, state, sub_args,
                                       unpack_params);
 
@@ -2983,7 +2994,7 @@
     }
   }
 
-  if (args.command_type == DoTexImageArguments::kTexImage3D &&
+  if (args.command_type == DoTexImageArguments::CommandType::kTexImage3D &&
       texture_state->unpack_image_height_workaround_with_unpack_buffer &&
       buffer) {
     ContextState::Dimension dimension = ContextState::k3D;
@@ -3008,7 +3019,7 @@
           args.pixels,
           args.pixels_size,
           args.padding,
-          DoTexSubImageArguments::kTexSubImage3D};
+          DoTexSubImageArguments::CommandType::kTexSubImage3D};
       DoTexSubImageLayerByLayerWorkaround(texture_state, state, sub_args,
                                           unpack_params);
 
@@ -3028,11 +3039,22 @@
                                 args);
 
       DoTexSubImageArguments sub_args = {
-          args.target, args.level, 0, 0, 0, args.width, args.height, args.depth,
-          args.format, args.type, args.pixels, args.pixels_size, args.padding,
-          args.command_type == DoTexImageArguments::kTexImage3D ?
-              DoTexSubImageArguments::kTexSubImage3D :
-              DoTexSubImageArguments::kTexSubImage2D};
+          args.target,
+          args.level,
+          0,
+          0,
+          0,
+          args.width,
+          args.height,
+          args.depth,
+          args.format,
+          args.type,
+          args.pixels,
+          args.pixels_size,
+          args.padding,
+          args.command_type == DoTexImageArguments::CommandType::kTexImage3D
+              ? DoTexSubImageArguments::CommandType::kTexSubImage3D
+              : DoTexSubImageArguments::CommandType::kTexSubImage2D};
       DoTexSubImageWithAlignmentWorkaround(texture_state, state, sub_args);
 
       SetLevelCleared(texture_ref, args.target, args.level, true);
@@ -3070,9 +3092,11 @@
                                          TextureRef** texture_ref) {
   const Validators* validators = feature_info_->validators();
 
-  if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
+  if ((args.command_type ==
+           DoTexSubImageArguments::CommandType::kTexSubImage2D &&
        !validators->texture_target.IsValid(args.target)) ||
-      (args.command_type == DoTexSubImageArguments::kTexSubImage3D &&
+      (args.command_type ==
+           DoTexSubImageArguments::CommandType::kTexSubImage3D &&
        !validators->texture_3_d_target.IsValid(args.target))) {
     ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
                                          args.target, "target");
@@ -3201,7 +3225,8 @@
       args.width != tex_width || args.height != tex_height ||
       args.depth != tex_depth) {
     gfx::Rect cleared_rect;
-    if (args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
+    if (args.command_type ==
+            DoTexSubImageArguments::CommandType::kTexSubImage2D &&
         CombineAdjacentRects(
             texture->GetLevelClearedRect(args.target, args.level),
             gfx::Rect(args.xoffset, args.yoffset, args.width, args.height),
@@ -3230,7 +3255,8 @@
   if (texture_state->unpack_overlapping_rows_separately_unpack_buffer &&
       buffer) {
     ContextState::Dimension dimension =
-        (args.command_type == DoTexSubImageArguments::kTexSubImage3D)
+        (args.command_type ==
+         DoTexSubImageArguments::CommandType::kTexSubImage3D)
             ? ContextState::k3D
             : ContextState::k2D;
     const PixelStoreParams unpack_params(state->GetUnpackParams(dimension));
@@ -3245,7 +3271,8 @@
     }
   }
 
-  if (args.command_type == DoTexSubImageArguments::kTexSubImage3D &&
+  if (args.command_type ==
+          DoTexSubImageArguments::CommandType::kTexSubImage3D &&
       texture_state->unpack_image_height_workaround_with_unpack_buffer &&
       buffer) {
     ContextState::Dimension dimension = ContextState::k3D;
@@ -3276,7 +3303,8 @@
     texture->GetLevelType(args.target, args.level, &tex_type, &internal_format);
     // NOTE: In OpenGL ES 2/3 border is always zero. If that changes we'll need
     // to look it up.
-    if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
+    if (args.command_type ==
+        DoTexSubImageArguments::CommandType::kTexSubImage3D) {
       glTexImage3D(args.target, args.level,
                    AdjustTexInternalFormat(feature_info_.get(), internal_format,
                                            args.type),
@@ -3293,7 +3321,8 @@
     }
   } else {
     TRACE_EVENT0("gpu", "SubImage");
-    if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
+    if (args.command_type ==
+        DoTexSubImageArguments::CommandType::kTexSubImage3D) {
       glTexSubImage3D(args.target, args.level, args.xoffset, args.yoffset,
                       args.zoffset, args.width, args.height, args.depth,
                       AdjustTexFormat(feature_info_.get(), args.format),
@@ -3315,7 +3344,8 @@
   DCHECK(args.width > 0 && args.height > 0 && args.depth > 0);
 
   uint32_t offset = ToGLuint(args.pixels);
-  if (args.command_type == DoTexSubImageArguments::kTexSubImage2D) {
+  if (args.command_type ==
+      DoTexSubImageArguments::CommandType::kTexSubImage2D) {
     PixelStoreParams params = state->GetUnpackParams(ContextState::k2D);
     if (args.height > 1) {
       glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset,
@@ -3436,7 +3466,8 @@
     row_bytes += unpack_params.alignment - alignment_diff;
   }
   DCHECK_EQ(0, row_bytes % unpack_params.alignment);
-  if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
+  if (args.command_type ==
+      DoTexSubImageArguments::CommandType::kTexSubImage3D) {
     GLsizei image_height = args.height;
     if (unpack_params.image_height != 0) {
       image_height = unpack_params.image_height;
@@ -3651,7 +3682,7 @@
 
   ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, function_name);
   {
-    if (args.command_type == DoTexImageArguments::kTexImage3D) {
+    if (args.command_type == DoTexImageArguments::CommandType::kTexImage3D) {
       glTexImage3D(args.target, args.level,
                    AdjustTexInternalFormat(feature_info_.get(),
                                            args.internal_format, args.type),
@@ -3668,7 +3699,7 @@
     }
   }
   GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name);
-  if (args.command_type == DoTexImageArguments::kTexImage3D) {
+  if (args.command_type == DoTexImageArguments::CommandType::kTexImage3D) {
     UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error_TexImage3D", error,
         GetAllGLErrors());
   } else {
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 6c006311..aedf7cc 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -1162,7 +1162,7 @@
   }
 
   struct DoTexImageArguments {
-    enum TexImageCommandType {
+    enum class CommandType {
       kTexImage2D,
       kTexImage3D,
     };
@@ -1179,7 +1179,7 @@
     const void* pixels;
     uint32_t pixels_size;
     uint32_t padding;
-    TexImageCommandType command_type;
+    CommandType command_type;
   };
 
   bool ValidateTexImage(ContextState* state,
@@ -1198,7 +1198,7 @@
                              const DoTexImageArguments& args);
 
   struct DoTexSubImageArguments {
-    enum TexSubImageCommandType {
+    enum class CommandType {
       kTexSubImage2D,
       kTexSubImage3D,
     };
@@ -1216,7 +1216,7 @@
     const void* pixels;
     uint32_t pixels_size;
     uint32_t padding;
-    TexSubImageCommandType command_type;
+    CommandType command_type;
   };
 
   bool ValidateTexSubImage(ContextState* state,
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
index 65feab8..841a1e6 100644
--- a/gpu/config/gpu_info_collector_win.cc
+++ b/gpu/config/gpu_info_collector_win.cc
@@ -106,7 +106,7 @@
   TRACE_EVENT0("gpu", "CollectDriverInfoD3D");
 
   Microsoft::WRL::ComPtr<IDXGIFactory> dxgi_factory;
-  const HRESULT hr = ::CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory));
+  HRESULT hr = ::CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory));
   if (FAILED(hr))
     return false;
 
@@ -125,8 +125,8 @@
     device.device_id = desc.DeviceId;
 
     LARGE_INTEGER umd_version;
-    const HRESULT hr = dxgi_adapter->CheckInterfaceSupport(
-        __uuidof(IDXGIDevice), &umd_version);
+    hr = dxgi_adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice),
+                                             &umd_version);
     if (SUCCEEDED(hr)) {
       device.driver_version = base::StringPrintf(
           "%d.%d.%d.%d", HIWORD(umd_version.HighPart),
diff --git a/gpu/config/gpu_preferences.h b/gpu/config/gpu_preferences.h
index 49f6724..610064b 100644
--- a/gpu/config/gpu_preferences.h
+++ b/gpu/config/gpu_preferences.h
@@ -29,7 +29,7 @@
 const size_t kLowEndMaxProgramCacheMemoryBytes = 128 * 1024;
 #endif
 
-enum VulkanImplementationName : uint32_t {
+enum class VulkanImplementationName : uint32_t {
   kNone = 0,
   kNative = 1,
   kSwiftshader = 2,
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 3d9377f..626a062 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -2247,6 +2247,11 @@
   // to be cloase, it is thus the responsibility of the main controller to
   // dismiss the the advanced sign-in settings by dismssing the settings
   // presented by |self.signinInteractionCoordinator|.
+  // To reproduce this case:
+  //  - open Bookmark view
+  //  - start sign-in
+  //  - tap on "Settings" to open the advanced sign-in settings
+  //  - tap on "Manage Your Google Account"
   DCHECK(self.signinInteractionCoordinator.isSettingsViewPresented);
   [self.signinInteractionCoordinator
       abortAndDismissSettingsViewAnimated:animated
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
index b64424c..31d4bac9 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -99,7 +99,7 @@
       const override;
   bool IsMainFrameSecure() const override;
   PrefService* GetPrefs() const override;
-  password_manager::PasswordStore* GetPasswordStore() const override;
+  password_manager::PasswordStore* GetProfilePasswordStore() const override;
   void NotifyUserAutoSignin(
       std::vector<std::unique_ptr<autofill::PasswordForm>> local_forms,
       const GURL& origin) override;
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index 1287df4..7d065ef 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -155,7 +155,7 @@
   return (delegate_.browserState)->GetPrefs();
 }
 
-PasswordStore* IOSChromePasswordManagerClient::GetPasswordStore() const {
+PasswordStore* IOSChromePasswordManagerClient::GetProfilePasswordStore() const {
   return IOSChromePasswordStoreFactory::GetForBrowserState(
              delegate_.browserState, ServiceAccessType::EXPLICIT_ACCESS)
       .get();
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index 26469f38..7bf11f4 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -93,7 +93,7 @@
 
   PrefService* GetPrefs() const override { return prefs_.get(); }
 
-  password_manager::PasswordStore* GetPasswordStore() const override {
+  password_manager::PasswordStore* GetProfilePasswordStore() const override {
     return store_;
   }
 
diff --git a/ios/chrome/browser/passwords/test/test_password_manager_client.h b/ios/chrome/browser/passwords/test/test_password_manager_client.h
index eefa1a1f..37d2a83 100644
--- a/ios/chrome/browser/passwords/test/test_password_manager_client.h
+++ b/ios/chrome/browser/passwords/test/test_password_manager_client.h
@@ -50,7 +50,7 @@
  private:
   // PasswordManagerClient:
   PrefService* GetPrefs() const override;
-  PasswordStore* GetPasswordStore() const override;
+  PasswordStore* GetProfilePasswordStore() const override;
   const PasswordManager* GetPasswordManager() const override;
   const GURL& GetLastCommittedEntryURL() const override;
   // Stores |manager| into |manager_|. Save() should be
diff --git a/ios/chrome/browser/passwords/test/test_password_manager_client.mm b/ios/chrome/browser/passwords/test/test_password_manager_client.mm
index c233389..3a6501c 100644
--- a/ios/chrome/browser/passwords/test/test_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/test/test_password_manager_client.mm
@@ -56,7 +56,7 @@
   return prefs_.get();
 }
 
-PasswordStore* TestPasswordManagerClient::GetPasswordStore() const {
+PasswordStore* TestPasswordManagerClient::GetProfilePasswordStore() const {
   return store_.get();
 }
 
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index 21fe70e..2711cc4a 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -71,6 +71,9 @@
 const char kReverseAutologinEnabled[] = "reverse_autologin.enabled";
 const char kLastKnownGoogleURL[] = "browser.last_known_google_url";
 const char kLastPromptedGoogleURL[] = "browser.last_prompted_google_url";
+
+// Deprecated 9/2019
+const char kGoogleServicesUsername[] = "google.services.username";
 }
 
 void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
@@ -180,6 +183,7 @@
   registry->RegisterBooleanPref(kReverseAutologinEnabled, true);
   registry->RegisterStringPref(kLastKnownGoogleURL, std::string());
   registry->RegisterStringPref(kLastPromptedGoogleURL, std::string());
+  registry->RegisterStringPref(kGoogleServicesUsername, std::string());
 }
 
 // This method should be periodically pruned of year+ old migrations.
@@ -208,4 +212,7 @@
   syncer::ClearObsoleteSyncLongPollIntervalSeconds(prefs);
   prefs->ClearPref(kLastKnownGoogleURL);
   prefs->ClearPref(kLastPromptedGoogleURL);
+
+  // Added 09/2019
+  prefs->ClearPref(kGoogleServicesUsername);
 }
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
index d8ced07f..180e261 100644
--- a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
@@ -18,6 +18,7 @@
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -94,7 +95,7 @@
   [super viewDidLoad];
 
   self.styler.shouldHideSeparators = YES;
-  self.collectionView.backgroundColor = [UIColor clearColor];
+  self.collectionView.backgroundColor = UIColor.clearColor;
 
   // Add an inset at the bottom so the user can see whether it is possible to
   // scroll to see additional accounts.
@@ -265,12 +266,12 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
 
-  self.view.backgroundColor = [UIColor whiteColor];
+  self.view.backgroundColor = [UIColor colorNamed:kBackgroundColor];
 
   _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
   _titleLabel.text =
       l10n_util::GetNSString(IDS_IOS_SIGNED_IN_ACCOUNTS_VIEW_TITLE);
-  _titleLabel.textColor = [[MDCPalette greyPalette] tint900];
+  _titleLabel.textColor = [UIColor colorNamed:kTextPrimaryColor];
   _titleLabel.font = [MDCTypography headlineFont];
   _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:_titleLabel];
@@ -286,7 +287,7 @@
   _infoLabel.text =
       l10n_util::GetNSString(IDS_IOS_SIGNED_IN_ACCOUNTS_VIEW_INFO);
   _infoLabel.numberOfLines = 0;
-  _infoLabel.textColor = [[MDCPalette greyPalette] tint700];
+  _infoLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
   _infoLabel.font = [MDCTypography body1Font];
   _infoLabel.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:_infoLabel];
@@ -298,12 +299,12 @@
   [_primaryButton
       setTitle:l10n_util::GetNSString(IDS_IOS_SIGNED_IN_ACCOUNTS_VIEW_OK_BUTTON)
       forState:UIControlStateNormal];
-  [_primaryButton setBackgroundColor:[[MDCPalette cr_bluePalette] tint500]
+  [_primaryButton setBackgroundColor:[UIColor colorNamed:kBlueColor]
                             forState:UIControlStateNormal];
-  [_primaryButton setTitleColor:[UIColor whiteColor]
+  [_primaryButton setTitleColor:[UIColor colorNamed:kSolidButtonTextColor]
                        forState:UIControlStateNormal];
-  _primaryButton.underlyingColorHint = [UIColor blackColor];
-  _primaryButton.inkColor = [UIColor colorWithWhite:1 alpha:0.2f];
+  _primaryButton.underlyingColorHint = [UIColor colorNamed:kBackgroundColor];
+  _primaryButton.inkColor = [UIColor colorNamed:kMDCInkColor];
   _primaryButton.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:_primaryButton];
 
@@ -315,12 +316,12 @@
       setTitle:l10n_util::GetNSString(
                    IDS_IOS_SIGNED_IN_ACCOUNTS_VIEW_SETTINGS_BUTTON)
       forState:UIControlStateNormal];
-  [_secondaryButton setBackgroundColor:[UIColor whiteColor]
+  [_secondaryButton setBackgroundColor:UIColor.clearColor
                               forState:UIControlStateNormal];
-  [_secondaryButton setTitleColor:[[MDCPalette cr_bluePalette] tint500]
+  [_secondaryButton setTitleColor:[UIColor colorNamed:kBlueColor]
                          forState:UIControlStateNormal];
-  _secondaryButton.underlyingColorHint = [UIColor whiteColor];
-  _secondaryButton.inkColor = [UIColor colorWithWhite:0 alpha:0.06f];
+  _secondaryButton.underlyingColorHint = [UIColor colorNamed:kBackgroundColor];
+  _secondaryButton.inkColor = [UIColor colorNamed:kMDCSecondaryInkColor];
   _secondaryButton.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:_secondaryButton];
 
diff --git a/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm
index df91db86..58ef0b7eb 100644
--- a/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm
+++ b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm
@@ -7,6 +7,7 @@
 #include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
 #import "ios/chrome/browser/ui/util/rtl_geometry.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/UIColor+cr_semantic_colors.h"
 #import "ios/chrome/common/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
@@ -175,9 +176,9 @@
        withFontScaling:(BOOL)withFontScaling {
   if (cellStyle == CollectionViewCellStyle::kUIKit) {
     self.textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    self.textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
+    self.textLabel.textColor = UIColor.cr_labelColor;
     self.textField.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    self.textField.textColor = [UIColor grayColor];
+    self.textField.textColor = UIColor.cr_secondaryLabelColor;
   } else {
     MaybeSetUILabelScaledFont(withFontScaling, self.textLabel,
                               [[MDCTypography fontLoader] mediumFontOfSize:14]);
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.mm
index 1e27ca6..65e08ee 100644
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.mm
+++ b/ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.mm
@@ -9,6 +9,8 @@
 #include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/UIColor+cr_semantic_colors.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -72,11 +74,13 @@
   cell.detailTextLabel.text = self.detailText;
   [cell cr_setAccessoryType:self.accessoryType];
   if (self.shouldDisplayError) {
-    cell.errorIcon.image = [UIImage imageNamed:@"settings_error"];
-    cell.detailTextLabel.textColor = [[MDCPalette cr_redPalette] tint500];
+    cell.errorIcon.image = [[UIImage imageNamed:@"settings_error"]
+        imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+    cell.errorIcon.tintColor = [UIColor colorNamed:kRedColor];
+    cell.detailTextLabel.textColor = [UIColor colorNamed:kRedColor];
   } else {
     cell.errorIcon.image = nil;
-    cell.detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+    cell.detailTextLabel.textColor = [UIColor colorNamed:kTextPrimaryColor];
   }
 
   if (self.isEnabled) {
@@ -154,15 +158,15 @@
 
   if (cellStyle == CollectionViewCellStyle::kUIKit) {
     _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
+    _textLabel.textColor = UIColor.cr_labelColor;
     _detailTextLabel.font =
         [UIFont systemFontOfSize:kUIKitMultilineDetailFontSize];
-    _detailTextLabel.textColor = UIColorFromRGB(kUIKitMultilineDetailTextColor);
+    _detailTextLabel.textColor = UIColor.cr_secondaryLabelColor;
   } else {
     _textLabel.font = [[MDCTypography fontLoader] mediumFontOfSize:14];
-    _textLabel.textColor = [[MDCPalette greyPalette] tint900];
+    _textLabel.textColor = [UIColor colorNamed:kTextPrimaryColor];
     _detailTextLabel.font = [[MDCTypography fontLoader] regularFontOfSize:14];
-    _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+    _detailTextLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
   }
 }
 
@@ -260,9 +264,10 @@
   self.imageView.image = nil;
   self.textLabel.text = nil;
   self.detailTextLabel.text = nil;
-  self.textLabel.textColor = [[MDCPalette greyPalette] tint900];
-  self.detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+  self.textLabel.textColor = [UIColor colorNamed:kTextPrimaryColor];
+  self.detailTextLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
   self.errorIcon.image = nil;
+  self.errorIcon.tintColor = nil;
   self.accessoryType = MDCCollectionViewCellAccessoryNone;
   self.userInteractionEnabled = YES;
   self.contentView.alpha = 1;
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h b/ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h
index ea4e4b60..31f0c8c 100644
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h
+++ b/ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h
@@ -10,17 +10,14 @@
 // The amount of padding at the top and bottom of UIKit-style cells.
 const CGFloat kUIKitVerticalPadding = 16;
 
-// The font size and color to use for main text in UIKit-style cells.
-const int kUIKitMainTextColor = 0x000000;
+// The font size to use for main text in UIKit-style cells.
 const CGFloat kUIKitMainFontSize = 17;
 
-// The font size and color to use for detail text that is on the trailing edge
+// The font size to use for detail text that is on the trailing edge
 // of the top line.
-const int kUIKitDetailTextColor = 0x767676;
 const CGFloat kUIKitDetailFontSize = 17;
 
-// The font size and color to use for detail text that is on its own line.
-const int kUIKitMultilineDetailTextColor = 0x767676;
+// The font size to use for detail text that is on its own line.
 const CGFloat kUIKitMultilineDetailFontSize = 12;
 
 // The font size and color to use for footer text in UIKit-style cells.
diff --git a/ios/chrome/browser/ui/elements/BUILD.gn b/ios/chrome/browser/ui/elements/BUILD.gn
index 36fad68f..02c5b800 100644
--- a/ios/chrome/browser/ui/elements/BUILD.gn
+++ b/ios/chrome/browser/ui/elements/BUILD.gn
@@ -28,6 +28,7 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/util",
+    "//ios/chrome/common/colors",
   ]
 }
 
diff --git a/ios/chrome/browser/ui/elements/gray_highlight_button.mm b/ios/chrome/browser/ui/elements/gray_highlight_button.mm
index c929124..352476c 100644
--- a/ios/chrome/browser/ui/elements/gray_highlight_button.mm
+++ b/ios/chrome/browser/ui/elements/gray_highlight_button.mm
@@ -4,6 +4,8 @@
 
 #import "ios/chrome/browser/ui/elements/gray_highlight_button.h"
 
+#import "ios/chrome/common/colors/semantic_color_names.h"
+
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
@@ -13,7 +15,7 @@
 - (void)setHighlighted:(BOOL)highlighted {
   [super setHighlighted:highlighted];
   if (highlighted) {
-    self.backgroundColor = [UIColor colorWithWhite:235.0 / 255.0 alpha:1.0];
+    self.backgroundColor = [UIColor colorNamed:kTableViewRowHighlightColor];
   } else {
     self.backgroundColor = [UIColor clearColor];
   }
diff --git a/ios/chrome/browser/ui/infobars/presentation/BUILD.gn b/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
index 30a35c5..7d31a0a 100644
--- a/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
@@ -24,5 +24,6 @@
     "//base",
     "//ios/chrome/browser/ui/infobars/banners:public",
     "//ios/chrome/browser/ui/util",
+    "//ios/chrome/common/colors",
   ]
 }
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm
index 67c9174b3..5b185127 100644
--- a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -19,10 +20,6 @@
 const CGFloat kPresentedViewMaxWidth = 394.0;
 // The rounded corner radius for the container view.
 const CGFloat kContainerCornerRadius = 13.0;
-// The background color for the container view.
-const int kContainerBackgroundColor = 0x2F2F2F;
-// The alpha component for the container view background color.
-const CGFloat kContainerBackgroundColorAlpha = 0.5;
 }  // namespace
 
 @implementation InfobarModalPresentationController
@@ -42,8 +39,7 @@
   self.presentedView.layer.masksToBounds = YES;
   self.presentedView.clipsToBounds = YES;
   self.containerView.backgroundColor =
-      [UIColorFromRGB(kContainerBackgroundColor)
-          colorWithAlphaComponent:kContainerBackgroundColorAlpha];
+      [UIColor colorNamed:kScrimBackgroundColor];
 }
 
 - (CGRect)frameForPresentedView {
diff --git a/ios/chrome/browser/ui/main/scene_delegate.h b/ios/chrome/browser/ui/main/scene_delegate.h
index 84a5dcd..0370ba9 100644
--- a/ios/chrome/browser/ui/main/scene_delegate.h
+++ b/ios/chrome/browser/ui/main/scene_delegate.h
@@ -7,11 +7,16 @@
 
 #import <UIKit/UIKit.h>
 
-// An object acting as a scene delegate for UIKit. Updates the window state.
+#import "ios/chrome/browser/ui/main/scene_state.h"
+
+// An object acting as a scene delegate for UIKit. Updates the scene state.
 @interface SceneDelegate : NSObject <UIWindowSceneDelegate>
 
 @property(nonatomic, strong) UIWindow* window;
 
+// The object that holds the state of the scene associated with this delegate.
+@property(nonatomic, strong) SceneState* sceneState;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_MAIN_SCENE_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/main/scene_delegate.mm b/ios/chrome/browser/ui/main/scene_delegate.mm
index afc6a40..ad51cc2acc 100644
--- a/ios/chrome/browser/ui/main/scene_delegate.mm
+++ b/ios/chrome/browser/ui/main/scene_delegate.mm
@@ -10,4 +10,46 @@
 
 @implementation SceneDelegate
 
+- (SceneState*)sceneState {
+  if (!_sceneState) {
+    _sceneState = [[SceneState alloc] init];
+  }
+  return _sceneState;
+}
+
+#pragma mark - UISceneDelegate
+
+#pragma mark Connecting and Disconnecting the Scene
+
+- (void)scene:(UIScene*)scene
+    willConnectToSession:(UISceneSession*)session
+                 options:(UISceneConnectionOptions*)connectionOptions
+    API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelBackground;
+}
+
+- (void)sceneDidDisconnect:(UIScene*)scene API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelUnattached;
+}
+
+#pragma mark Transitioning to the Foreground
+
+- (void)sceneWillEnterForeground:(UIScene*)scene API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelForegroundInactive;
+}
+
+- (void)sceneDidBecomeActive:(UIScene*)scene API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelForegroundActive;
+}
+
+#pragma mark Transitioning to the Background
+
+- (void)sceneWillResignActive:(UIScene*)scene API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelForegroundInactive;
+}
+
+- (void)sceneDidEnterBackground:(UIScene*)scene API_AVAILABLE(ios(13)) {
+  self.sceneState.activationLevel = SceneActivationLevelBackground;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/main/scene_state.h b/ios/chrome/browser/ui/main/scene_state.h
index 7a31ae9..2d41fe9 100644
--- a/ios/chrome/browser/ui/main/scene_state.h
+++ b/ios/chrome/browser/ui/main/scene_state.h
@@ -7,9 +7,32 @@
 
 #import <UIKit/UIKit.h>
 
+// Describes the possible scene states.
+// This is an iOS 12 compatible version of UISceneActivationState enum.
+typedef NS_ENUM(NSUInteger, SceneActivationLevel) {
+  // The scene is not connected and has no window.
+  SceneActivationLevelUnattached = 0,
+  // The scene is connected, and has a window associated with it. The window is
+  // not visible to the user, except possibly in the app switcher.
+  SceneActivationLevelBackground,
+  // The scene is connected, and its window is on screen, but it's not active
+  // for user input. For example, keyboard events would not be sent to this
+  // window.
+  SceneActivationLevelForegroundInactive,
+  // The scene is connected, has a window, and receives user events.
+  SceneActivationLevelForegroundActive
+};
+
 // An object containing the state of a UIWindowScene. One state object
 // corresponds to one scene.
 @interface SceneState : NSObject
+
+// The current activation level.
+@property(nonatomic, assign) SceneActivationLevel activationLevel;
+
+// Window for the associated scene, if any.
+@property(nonatomic, weak) UIWindow* window;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_MAIN_SCENE_STATE_H_
diff --git a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_modal_presentation_controller.mm b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_modal_presentation_controller.mm
index 93162ea..8b3c574 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_modal_presentation_controller.mm
+++ b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_modal_presentation_controller.mm
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_modal_positioner.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -19,10 +20,6 @@
 const CGFloat kPresentedViewMaxWidth = 394.0;
 // The rounded corner radius for the container view.
 const CGFloat kContainerCornerRadius = 13.0;
-// The background color for the container view.
-const int kContainerBackgroundColor = 0x2F2F2F;
-// The alpha component for the container view background color.
-const CGFloat kContainerBackgroundColorAlpha = 0.5;
 }  // namespace
 
 @implementation SendTabToSelfModalPresentationController
@@ -35,8 +32,7 @@
   self.presentedView.layer.masksToBounds = YES;
   self.presentedView.clipsToBounds = YES;
   self.containerView.backgroundColor =
-      [UIColorFromRGB(kContainerBackgroundColor)
-          colorWithAlphaComponent:kContainerBackgroundColorAlpha];
+      [UIColor colorNamed:kScrimBackgroundColor];
 }
 
 - (CGRect)frameForPresentedView {
diff --git a/ios/chrome/browser/ui/settings/autofill/BUILD.gn b/ios/chrome/browser/ui/settings/autofill/BUILD.gn
index 750f380..7df58c2 100644
--- a/ios/chrome/browser/ui/settings/autofill/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/autofill/BUILD.gn
@@ -125,13 +125,13 @@
     "//build/config/ios:xctest_config",
   ]
   testonly = true
-
   sources = [
     "autofill_add_credit_card_egtest.mm",
   ]
-
   deps = [
     ":feature_flags",
+    "//base",
+    "//ios/chrome/app/strings",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//ios/third_party/earl_grey2:test_lib",
@@ -139,6 +139,5 @@
     "//net:test_support",
     "//ui/base",
   ]
-
   libs = [ "UIKit.framework" ]
 }
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_egtest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_egtest.mm
index abebf86..4b53258 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_egtest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_egtest.mm
@@ -3,19 +3,71 @@
 // found in the LICENSE file.
 
 #import "ios/chrome/browser/ui/settings/autofill/features.h"
+#include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
 #import "ios/testing/earl_grey/app_launch_manager.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
+#include "ui/base/l10n/l10n_util_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 using chrome_test_util::AddPaymentMethodButton;
+using chrome_test_util::ButtonWithAccessibilityLabelId;
 using chrome_test_util::PaymentMethodsButton;
+using chrome_test_util::StaticTextWithAccessibilityLabelId;
+
+namespace {
+
+// Matcher for the 'Name on Card' field in the add credit card view.
+id<GREYMatcher> NameOnCardField() {
+  return grey_accessibilityLabel(
+      l10n_util::GetNSStringWithFixup(IDS_IOS_AUTOFILL_CARDHOLDER));
+}
+
+// Matcher for the 'Card Number' field in the add credit card view.
+id<GREYMatcher> CardNumberField() {
+  return grey_accessibilityLabel(
+      l10n_util::GetNSStringWithFixup(IDS_IOS_AUTOFILL_CARD_NUMBER));
+}
+
+// Matcher for the 'Month of Expiry' field in the add credit card view.
+id<GREYMatcher> MonthOfExpiryField() {
+  return grey_accessibilityLabel(
+      l10n_util::GetNSStringWithFixup(IDS_IOS_AUTOFILL_EXP_MONTH));
+}
+
+// Matcher for the 'Year of Expiry' field in the add credit card view.
+id<GREYMatcher> YearOfExpiryField() {
+  return grey_accessibilityLabel(
+      l10n_util::GetNSStringWithFixup(IDS_IOS_AUTOFILL_EXP_YEAR));
+}
+
+// Matcher for the 'Use Camera' button in the add credit card view.
+id<GREYMatcher> UseCameraButton() {
+  return ButtonWithAccessibilityLabelId(
+      IDS_IOS_AUTOFILL_ADD_CREDIT_CARD_OPEN_CAMERA_BUTTON_LABEL);
+}
+
+// Matcher for the 'Card Number' text field in the add credit card view.
+id<GREYMatcher> CardNumberTextField() {
+  return grey_allOf(
+      grey_accessibilityID([l10n_util::GetNSStringWithFixup(
+          IDS_IOS_AUTOFILL_CARD_NUMBER) stringByAppendingString:@"_textField"]),
+      grey_kindOfClass([UITextField class]), nil);
+}
+
+// Matcher for the Invalid Card Number Alert.
+id<GREYMatcher> InvalidCardNumberAlert() {
+  return StaticTextWithAccessibilityLabelId(
+      IDS_IOS_ADD_CREDIT_CARD_INVALID_CARD_NUMBER_ALERT);
+}
+
+}  // namespace
 
 // Tests for Settings Autofill add credit cards section.
 @interface AutofillAddCreditCardTestCase : ChromeTestCase
@@ -26,11 +78,14 @@
 - (void)setUp {
   [super setUp];
   [[AppLaunchManager sharedManager]
-      ensureAppLaunchedWithFeaturesEnabled:{kSettingsAddPaymentMethod}
+      ensureAppLaunchedWithFeaturesEnabled:{kSettingsAddPaymentMethod,
+                                            kCreditCardScanner}
                                   disabled:{}
                               forceRestart:NO];
   GREYAssertTrue([ChromeEarlGrey isSettingsAddPaymentMethodEnabled],
                  @"SettingsAddPaymentMethod should be enabled");
+  GREYAssertTrue([ChromeEarlGrey isCreditCardScannerEnabled],
+                 @"CreditCardScanner should be enabled");
   [ChromeEarlGrey openNewTab];
   [ChromeEarlGreyUI openSettingsMenu];
   [ChromeEarlGreyUI tapSettingsMenuButton:PaymentMethodsButton()];
@@ -38,4 +93,95 @@
       performAction:grey_tap()];
 }
 
+#pragma mark - Test that all fields on the 'Add Credit Card' screen appear
+
+// Tests that 'Name on Card' field appears on screen.
+- (void)testNameOnCardFieldIsPresent {
+  [[EarlGrey selectElementWithMatcher:NameOnCardField()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Tests that 'Card Number' field appears on screen.
+- (void)testCardNumberFieldIsPresent {
+  [[EarlGrey selectElementWithMatcher:CardNumberField()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Tests that 'Month of Expiry' field appears on screen.
+- (void)testMonthOfExpiryFieldIsPresent {
+  [[EarlGrey selectElementWithMatcher:MonthOfExpiryField()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Tests that 'Year of Expiry' field appears on screen.
+- (void)testYearOfExpiryFieldIsPresent {
+  [[EarlGrey selectElementWithMatcher:YearOfExpiryField()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Tests that 'Use Camera' button appears on screen only for iOS 13.
+- (void)testUseCameraButtonIsPresent {
+  if (@available(iOS 13, *)) {
+    [[EarlGrey selectElementWithMatcher:UseCameraButton()]
+        assertWithMatcher:grey_sufficientlyVisible()];
+  } else {
+    [[EarlGrey selectElementWithMatcher:UseCameraButton()]
+        assertWithMatcher:grey_nil()];
+  }
+}
+
+#pragma mark - Test top toolbar buttons
+
+// Tests that the 'Add' button in the top toolbar is disabled by default.
+- (void)testAddButtonDisabledOnDefault {
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardButton()]
+      assertWithMatcher:grey_allOf(grey_sufficientlyVisible(),
+                                   grey_not(grey_enabled()), nil)];
+}
+
+// Tests that the 'Add' button in the top toolbar is enabled when any text is
+// typed and disabled when there is no text.
+- (void)testAddButtonEnabledDisabledOnModifyingTextField {
+  [[EarlGrey selectElementWithMatcher:CardNumberTextField()]
+      performAction:grey_typeText(@"1234")];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardButton()]
+      assertWithMatcher:grey_allOf(grey_sufficientlyVisible(), grey_enabled(),
+                                   nil)];
+  [[EarlGrey selectElementWithMatcher:CardNumberField()]
+      performAction:grey_clearText()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardButton()]
+      assertWithMatcher:grey_allOf(grey_sufficientlyVisible(),
+                                   grey_not(grey_enabled()), nil)];
+}
+
+// Tests when a user tries to add an invalid card number, an alert is shown. On
+// clicking 'OK' the alert is dismissed.
+- (void)testAddButtonAlertOnInvalidNumber {
+  [[EarlGrey selectElementWithMatcher:CardNumberTextField()]
+      performAction:grey_typeText(@"1234")];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:InvalidCardNumberAlert()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OKButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:InvalidCardNumberAlert()]
+      assertWithMatcher:grey_nil()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OKButton()]
+      assertWithMatcher:grey_nil()];
+}
+
+// Tests that the 'Cancel' button dismisses the screen
+- (void)testCancelButtonDismissesScreen {
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardView()]
+      assertWithMatcher:grey_notNil()];
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::AddCreditCardCancelButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::AddCreditCardView()]
+      assertWithMatcher:grey_nil()];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h
index d8e3fbfb..f452605 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h
@@ -10,6 +10,10 @@
 #import "ios/chrome/browser/ui/settings/autofill/autofill_edit_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_consumer.h"
 
+extern NSString* const kAddCreditCardViewID;
+extern NSString* const kSettingsAddCreditCardButtonID;
+extern NSString* const kSettingsAddCreditCardCancelButtonID;
+
 @protocol AddCreditCardViewControllerDelegate;
 
 // The view controller for adding new credit card.
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm
index 8c9e863..e712381 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm
@@ -22,6 +22,12 @@
 #error "This file requires ARC support."
 #endif
 
+NSString* const kAddCreditCardViewID = @"kAddCreditCardViewID";
+NSString* const kSettingsAddCreditCardButtonID =
+    @"kSettingsAddCreditCardButtonID";
+NSString* const kSettingsAddCreditCardCancelButtonID =
+    @"kSettingsAddCreditCardCancelButtonID";
+
 namespace {
 
 typedef NS_ENUM(NSInteger, SectionIdentifier) {
@@ -83,6 +89,7 @@
   [super viewDidLoad];
 
   self.view.backgroundColor = UIColor.cr_systemGroupedBackgroundColor;
+  self.tableView.accessibilityIdentifier = kAddCreditCardViewID;
 
   self.navigationItem.title = l10n_util::GetNSString(
       IDS_IOS_CREDIT_CARD_SETTINGS_ADD_PAYMENT_METHOD_TITLE);
@@ -93,6 +100,8 @@
               style:UIBarButtonItemStylePlain
              target:self
              action:@selector(handleCancelButton:)];
+  self.navigationItem.leftBarButtonItem.accessibilityIdentifier =
+      kSettingsAddCreditCardCancelButtonID;
 
   self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_ADD_BUTTON)
@@ -100,6 +109,8 @@
              target:self
              action:@selector(didTapAddButton:)];
   self.navigationItem.rightBarButtonItem.enabled = NO;
+  self.navigationItem.rightBarButtonItem.accessibilityIdentifier =
+      kSettingsAddCreditCardButtonID;
 
   [self loadModel];
 }
@@ -178,6 +189,7 @@
   cameraButtonItem.text = l10n_util::GetNSString(
       IDS_IOS_AUTOFILL_ADD_CREDIT_CARD_OPEN_CAMERA_BUTTON_LABEL);
   cameraButtonItem.textAlignment = NSTextAlignmentCenter;
+  cameraButtonItem.accessibilityTraits |= UIAccessibilityTraitButton;
   if (base::FeatureList::IsEnabled(kCreditCardScanner)) {
     if (@available(iOS 13, *)) {
       [model addSectionWithIdentifier:SectionIdentifierCameraButton];
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
index 8fbee99..17611b9 100644
--- a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
@@ -15,6 +15,7 @@
     "//ios/chrome/browser/ui/colors",
     "//ios/chrome/browser/ui/icons",
     "//ios/chrome/browser/ui/util",
+    "//ios/chrome/common/colors",
     "//ios/chrome/common/ui_util",
     "//ios/third_party/material_roboto_font_loader_ios",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.mm
index 354ef2e..0297442 100644
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.mm
@@ -9,6 +9,7 @@
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/UIColor+cr_semantic_colors.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
@@ -102,15 +103,15 @@
     _textLabel = [[UILabel alloc] init];
     _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
     _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
-    _textLabel.backgroundColor = [UIColor clearColor];
+    _textLabel.textColor = UIColor.cr_labelColor;
+    _textLabel.backgroundColor = UIColor.clearColor;
     [contentView addSubview:_textLabel];
 
     _detailTextLabel = [[UILabel alloc] init];
     _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
     _detailTextLabel.font = [UIFont systemFontOfSize:kUIKitDetailFontSize];
-    _detailTextLabel.textColor = UIColorFromRGB(kUIKitDetailTextColor);
-    _detailTextLabel.backgroundColor = [UIColor clearColor];
+    _detailTextLabel.textColor = UIColor.cr_secondaryLabelColor;
+    _detailTextLabel.backgroundColor = UIColor.clearColor;
     [contentView addSubview:_detailTextLabel];
 
     // Set up the width constraints. They are activated here and updated in
diff --git a/ios/chrome/browser/ui/settings/cells/search_engine_item.mm b/ios/chrome/browser/ui/settings/cells/search_engine_item.mm
index b30cb0b..3196411 100644
--- a/ios/chrome/browser/ui/settings/cells/search_engine_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/search_engine_item.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
 #include "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -54,7 +55,7 @@
     cell.titleLabel.textColor = styler.cellTitleColor;
   }
 
-  cell.URLLabel.textColor = UIColorFromRGB(kSettingsCellsURLTextColor);
+  cell.URLLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
 
   [cell configureUILayout];
 }
diff --git a/ios/chrome/browser/ui/settings/cells/settings_cells_constants.h b/ios/chrome/browser/ui/settings/cells/settings_cells_constants.h
index 2af8843..4ca320a 100644
--- a/ios/chrome/browser/ui/settings/cells/settings_cells_constants.h
+++ b/ios/chrome/browser/ui/settings/cells/settings_cells_constants.h
@@ -7,12 +7,6 @@
 
 #import <UIKit/UIKit.h>
 
-// The color of the detail text for the settings cells.
-extern const int kSettingsCellsDetailTextColor;
-
-// The color of the URL text for the settings cells.
-extern const int kSettingsCellsURLTextColor;
-
 // Default height for the settings cells.
 extern const CGFloat kSettingsCellDefaultHeight;
 
diff --git a/ios/chrome/browser/ui/settings/cells/settings_cells_constants.mm b/ios/chrome/browser/ui/settings/cells/settings_cells_constants.mm
index 8aaef5a..4e8a5ea 100644
--- a/ios/chrome/browser/ui/settings/cells/settings_cells_constants.mm
+++ b/ios/chrome/browser/ui/settings/cells/settings_cells_constants.mm
@@ -8,7 +8,4 @@
 #error "This file requires ARC support."
 #endif
 
-const int kSettingsCellsDetailTextColor = 0x767676;
-const int kSettingsCellsURLTextColor = 0x5F6368;
-
 const CGFloat kSettingsCellDefaultHeight = 70;
diff --git a/ios/chrome/browser/ui/settings/language/language_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/language/language_details_table_view_controller.mm
index 82b34040..018f5b1 100644
--- a/ios/chrome/browser/ui/settings/language/language_details_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/language/language_details_table_view_controller.mm
@@ -116,8 +116,7 @@
   }
   if (!self.languageItem.canOfferTranslate) {
     offerTranslateItem.enabled = NO;
-    offerTranslateItem.textColor =
-        UIColorFromRGB(kSettingsCellsDetailTextColor);
+    offerTranslateItem.textColor = [UIColor colorNamed:kTextSecondaryColor];
   }
   [model addItem:offerTranslateItem
       toSectionWithIdentifier:SectionIdentifierOptions];
diff --git a/ios/chrome/common/colors/resources/BUILD.gn b/ios/chrome/common/colors/resources/BUILD.gn
index 8349b71..b250ff0e 100644
--- a/ios/chrome/common/colors/resources/BUILD.gn
+++ b/ios/chrome/common/colors/resources/BUILD.gn
@@ -30,6 +30,7 @@
     ":grid_theme_dark_selection_tint_color",
     ":grid_theme_selection_tint_color",
     ":mdc_ink_color",
+    ":mdc_secondary_ink_color",
     ":placeholder_image_tint_color",
     ":red_color",
     ":red_dark_color",
@@ -208,6 +209,12 @@
   ]
 }
 
+colorset("mdc_secondary_ink_color") {
+  sources = [
+    "mdc_secondary_ink_color.colorset/Contents.json",
+  ]
+}
+
 colorset("placeholder_image_tint_color") {
   sources = [
     "placeholder_image_tint_color.colorset/Contents.json",
diff --git a/ios/chrome/common/colors/resources/mdc_secondary_ink_color.colorset/Contents.json b/ios/chrome/common/colors/resources/mdc_secondary_ink_color.colorset/Contents.json
new file mode 100644
index 0000000..0c7d5e9
--- /dev/null
+++ b/ios/chrome/common/colors/resources/mdc_secondary_ink_color.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "colors" : [
+    {
+      "idiom" : "universal",
+      "color" : {
+        "color-space" : "display-p3",
+        "components" : {
+          "red" : "0x00",
+          "alpha" : "0.06",
+          "blue" : "0x00",
+          "green" : "0x00"
+        }
+      }
+    },
+    {
+      "idiom" : "universal",
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "color" : {
+        "color-space" : "display-p3",
+        "components" : {
+          "red" : "0xFF",
+          "alpha" : "0.06",
+          "blue" : "0xFF",
+          "green" : "0xFF"
+        }
+      }
+    }
+  ]
+}
diff --git a/ios/chrome/common/colors/semantic_color_names.h b/ios/chrome/common/colors/semantic_color_names.h
index cd51923..257b2fd 100644
--- a/ios/chrome/common/colors/semantic_color_names.h
+++ b/ios/chrome/common/colors/semantic_color_names.h
@@ -15,7 +15,11 @@
 extern NSString* const kGridThemeSelectionTintColor;
 // Background color used in the rounded squares behind favicons.
 extern NSString* const kFaviconBackgroundColor;
+// Ink color for an MDC button.
 extern NSString* const kMDCInkColor;
+// Ink color for a secondary style MDC button (button with transparent
+// background).
+extern NSString* const kMDCSecondaryInkColor;
 // Color used to tint placeholder images and icons.
 extern NSString* const kPlaceholderImageTintColor;
 extern NSString* const kScrimBackgroundColor;
diff --git a/ios/chrome/common/colors/semantic_color_names.mm b/ios/chrome/common/colors/semantic_color_names.mm
index c33f3e8..8ad3832c 100644
--- a/ios/chrome/common/colors/semantic_color_names.mm
+++ b/ios/chrome/common/colors/semantic_color_names.mm
@@ -16,6 +16,7 @@
     @"grid_theme_selection_tint_color";
 NSString* const kFaviconBackgroundColor = @"favicon_background_color";
 NSString* const kMDCInkColor = @"mdc_ink_color";
+NSString* const kMDCSecondaryInkColor = @"mdc_secondary_ink_color";
 NSString* const kPlaceholderImageTintColor = @"placeholder_image_tint_color";
 NSString* const kScrimBackgroundColor = @"scrim_background_color";
 NSString* const kSeparatorColor = @"separator_color";
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h
index 6229b79..3636abb 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -372,6 +372,9 @@
 // Returns YES if SettingsAddPaymentMethod feature is enabled.
 - (BOOL)isSettingsAddPaymentMethodEnabled WARN_UNUSED_RESULT;
 
+// Returns YES if CreditCardScanner feature is enabled.
+- (BOOL)isCreditCardScannerEnabled WARN_UNUSED_RESULT;
+
 #pragma mark - Popup Blocking
 
 // Gets the current value of the popup content setting preference for the
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
index 5f9c466..6271a146 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -622,6 +622,10 @@
   return [ChromeEarlGreyAppInterface isSettingsAddPaymentMethodEnabled];
 }
 
+- (BOOL)isCreditCardScannerEnabled {
+  return [ChromeEarlGreyAppInterface isCreditCardScannerEnabled];
+}
+
 #pragma mark - ScopedBlockPopupsPref
 
 - (ContentSetting)popupPrefValue {
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
index 678253c8..49e6755 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -305,6 +305,9 @@
 // Returns YES if SettingsAddPaymentMethod feature is enabled.
 + (BOOL)isSettingsAddPaymentMethodEnabled WARN_UNUSED_RESULT;
 
+// Returns YES if CreditCardScanner feature is enabled.
++ (BOOL)isCreditCardScannerEnabled WARN_UNUSED_RESULT;
+
 #pragma mark - Popup Blocking
 
 // Gets the current value of the popup content setting preference for the
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
index 8f1aacd..2a1c275 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -520,6 +520,10 @@
   return base::FeatureList::IsEnabled(kSettingsAddPaymentMethod);
 }
 
++ (BOOL)isCreditCardScannerEnabled {
+  return base::FeatureList::IsEnabled(kCreditCardScanner);
+}
+
 #pragma mark - ScopedBlockPopupsPref
 
 + (ContentSetting)popupPrefValue {
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h
index 3019e49..4a1aa740 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.h
+++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -163,10 +163,21 @@
 // Returns matcher for the "Payment Methods" button in the settings menu.
 id<GREYMatcher> PaymentMethodsButton();
 
+// Returns matcher for the "Add Credit Card" view in the Settings menu.
+id<GREYMatcher> AddCreditCardView();
+
 // Returns matcher for the "Add Payment Method" button in the Settings Payment
 // Methods view.
 id<GREYMatcher> AddPaymentMethodButton();
 
+// Returns matcher for the "Add" credit card button in the Payment
+// Methods add credit card view.
+id<GREYMatcher> AddCreditCardButton();
+
+// Returns matcher for the "Cancel" button in the Payment Methods add credit
+// card view.
+id<GREYMatcher> AddCreditCardCancelButton();
+
 // Returns matcher for the tools menu table view.
 id<GREYMatcher> ToolsMenuView();
 
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm
index d8a7c5d..a114d1d 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -209,10 +209,22 @@
   return [ChromeMatchersAppInterface paymentMethodsButton];
 }
 
+id<GREYMatcher> AddCreditCardView() {
+  return [ChromeMatchersAppInterface addCreditCardView];
+}
+
 id<GREYMatcher> AddPaymentMethodButton() {
   return [ChromeMatchersAppInterface addPaymentMethodButton];
 }
 
+id<GREYMatcher> AddCreditCardButton() {
+  return [ChromeMatchersAppInterface addCreditCardButton];
+}
+
+id<GREYMatcher> AddCreditCardCancelButton() {
+  return [ChromeMatchersAppInterface addCreditCardCancelButton];
+}
+
 id<GREYMatcher> ToolsMenuView() {
   return [ChromeMatchersAppInterface toolsMenuView];
 }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
index 5b39843..0c6a4a740 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
+++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -166,10 +166,21 @@
 // Returns matcher for the "Payment Methods" button in the settings menu.
 + (id<GREYMatcher>)paymentMethodsButton;
 
+// Returns matcher for the "Add Credit Card" view in the Settings menu.
++ (id<GREYMatcher>)addCreditCardView;
+
 // Returns matcher for the "Add Payment Method" button in the Settings Payment
 // Methods view.
 + (id<GREYMatcher>)addPaymentMethodButton;
 
+// Returns matcher for the "Add" credit card button in the Payment
+// Methods add credit card view.
++ (id<GREYMatcher>)addCreditCardButton;
+
+// Returns matcher for the "Cancel" button in the Payment Methods add credit
+// card view.
++ (id<GREYMatcher>)addCreditCardCancelButton;
+
 // Returns matcher for the tools menu table view.
 + (id<GREYMatcher>)toolsMenuView;
 
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
index 0fac91b..377a723 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -21,6 +21,7 @@
 #import "ios/chrome/browser/ui/payments/payment_request_view_controller.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
 #import "ios/chrome/browser/ui/recent_tabs/recent_tabs_constants.h"
+#import "ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h"
 #import "ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h"
@@ -418,10 +419,22 @@
       buttonWithAccessibilityLabelID:(IDS_AUTOFILL_PAYMENT_METHODS)];
 }
 
++ (id<GREYMatcher>)addCreditCardView {
+  return grey_accessibilityID(kAddCreditCardViewID);
+}
+
 + (id<GREYMatcher>)addPaymentMethodButton {
   return grey_accessibilityID(kSettingsAddPaymentMethodButtonId);
 }
 
++ (id<GREYMatcher>)addCreditCardButton {
+  return grey_accessibilityID(kSettingsAddCreditCardButtonID);
+}
+
++ (id<GREYMatcher>)addCreditCardCancelButton {
+  return grey_accessibilityID(kSettingsAddCreditCardCancelButtonID);
+}
+
 + (id<GREYMatcher>)toolsMenuView {
   return grey_accessibilityID(kPopupMenuToolsMenuTableViewId);
 }
diff --git a/ios/web/navigation/error_retry_state_machine.mm b/ios/web/navigation/error_retry_state_machine.mm
index 5406668..cf95aa2 100644
--- a/ios/web/navigation/error_retry_state_machine.mm
+++ b/ios/web/navigation/error_retry_state_machine.mm
@@ -135,7 +135,11 @@
   switch (state_) {
     case ErrorRetryState::kLoadingPlaceholder:
       // (1) Placeholder load for initial failure succeeded.
-      DCHECK_EQ(web_view_url, CreatePlaceholderUrlForUrl(url_));
+      if (@available(iOS 13, *)) {
+        // This DCHECK is hit on iOS 12 when navigating to restricted URL. See
+        // crbug.com/1000366 for more details.
+        DCHECK_EQ(web_view_url, CreatePlaceholderUrlForUrl(url_));
+      }
       state_ = ErrorRetryState::kReadyToDisplayError;
       return ErrorRetryCommand::kLoadError;
 
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.h b/ios/web_view/internal/passwords/web_view_password_manager_client.h
index 78a6a8e..a7454432 100644
--- a/ios/web_view/internal/passwords/web_view_password_manager_client.h
+++ b/ios/web_view/internal/passwords/web_view_password_manager_client.h
@@ -87,7 +87,7 @@
   const password_manager::PasswordFeatureManager* GetPasswordFeatureManager()
       const override;
   PrefService* GetPrefs() const override;
-  password_manager::PasswordStore* GetPasswordStore() const override;
+  password_manager::PasswordStore* GetProfilePasswordStore() const override;
   void NotifyUserAutoSignin(
       std::vector<std::unique_ptr<autofill::PasswordForm>> local_forms,
       const GURL& origin) override;
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.mm b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
index 183996a..33966d6 100644
--- a/ios/web_view/internal/passwords/web_view_password_manager_client.mm
+++ b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
@@ -127,7 +127,7 @@
   return delegate_.browserState->GetPrefs();
 }
 
-PasswordStore* WebViewPasswordManagerClient::GetPasswordStore() const {
+PasswordStore* WebViewPasswordManagerClient::GetProfilePasswordStore() const {
   return ios_web_view::WebViewPasswordStoreFactory::GetForBrowserState(
              delegate_.browserState, ServiceAccessType::EXPLICIT_ACCESS)
       .get();
diff --git a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
index a7fd400..8ff0dec 100644
--- a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
+++ b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
@@ -65,7 +65,6 @@
   // ChromeWebView's signin state.
   PrefService* pref_service = browser_state->GetPrefs();
   pref_service->ClearPref(prefs::kGoogleServicesAccountId);
-  pref_service->ClearPref(prefs::kGoogleServicesUsername);
   pref_service->ClearPref(prefs::kGoogleServicesUserAccountId);
 
   IOSWebViewSigninClient* client =
diff --git a/printing/backend/cups_connection.cc b/printing/backend/cups_connection.cc
index 202a806..24885c6 100644
--- a/printing/backend/cups_connection.cc
+++ b/printing/backend/cups_connection.cc
@@ -124,7 +124,7 @@
   auto dests = std::move(enumerator.get_dests());
   std::vector<CupsPrinter> printers;
   for (auto& dest : dests) {
-    printers.emplace_back(cups_http_.get(), std::move(dest), nullptr);
+    printers.emplace_back(cups_http_.get(), std::move(dest));
   }
 
   return printers;
@@ -139,10 +139,8 @@
   if (!dest)
     return nullptr;
 
-  cups_dinfo_t* info = cupsCopyDestInfo(cups_http_.get(), dest);
   return std::make_unique<CupsPrinter>(
-      cups_http_.get(), std::unique_ptr<cups_dest_t, DestinationDeleter>(dest),
-      std::unique_ptr<cups_dinfo_t, DestInfoDeleter>(info));
+      cups_http_.get(), std::unique_ptr<cups_dest_t, DestinationDeleter>(dest));
 }
 
 bool CupsConnection::GetJobs(const std::vector<std::string>& printer_ids,
diff --git a/printing/backend/cups_printer.cc b/printing/backend/cups_printer.cc
index 44b686a2..c8c873e1 100644
--- a/printing/backend/cups_printer.cc
+++ b/printing/backend/cups_printer.cc
@@ -24,24 +24,15 @@
 namespace printing {
 
 CupsPrinter::CupsPrinter(http_t* http,
-                         std::unique_ptr<cups_dest_t, DestinationDeleter> dest,
-                         std::unique_ptr<cups_dinfo_t, DestInfoDeleter> info)
-    : cups_http_(http),
-      destination_(std::move(dest)),
-      dest_info_(std::move(info)) {
+                         std::unique_ptr<cups_dest_t, DestinationDeleter> dest)
+    : cups_http_(http), destination_(std::move(dest)) {
   DCHECK(cups_http_);
   DCHECK(destination_);
 }
 
-CupsPrinter::CupsPrinter(CupsPrinter&& printer)
-    : cups_http_(printer.cups_http_),
-      destination_(std::move(printer.destination_)),
-      dest_info_(std::move(printer.dest_info_)) {
-  DCHECK(cups_http_);
-  DCHECK(destination_);
-}
+CupsPrinter::CupsPrinter(CupsPrinter&& printer) = default;
 
-CupsPrinter::~CupsPrinter() {}
+CupsPrinter::~CupsPrinter() = default;
 
 bool CupsPrinter::is_default() const {
   return destination_->is_default;
@@ -49,7 +40,7 @@
 
 ipp_attribute_t* CupsPrinter::GetSupportedOptionValues(
     const char* option_name) const {
-  if (!InitializeDestInfo())
+  if (!EnsureDestInfo())
     return nullptr;
 
   return cupsFindDestSupported(cups_http_, destination_.get(), dest_info_.get(),
@@ -75,7 +66,7 @@
 
 ipp_attribute_t* CupsPrinter::GetDefaultOptionValue(
     const char* option_name) const {
-  if (!InitializeDestInfo())
+  if (!EnsureDestInfo())
     return nullptr;
 
   return cupsFindDestDefault(cups_http_, destination_.get(), dest_info_.get(),
@@ -84,7 +75,7 @@
 
 bool CupsPrinter::CheckOptionSupported(const char* name,
                                        const char* value) const {
-  if (!InitializeDestInfo())
+  if (!EnsureDestInfo())
     return false;
 
   int supported = cupsCheckDestSupported(cups_http_, destination_.get(),
@@ -133,11 +124,7 @@
   return make_and_model ? std::string(make_and_model) : std::string();
 }
 
-bool CupsPrinter::IsAvailable() const {
-  return InitializeDestInfo();
-}
-
-bool CupsPrinter::InitializeDestInfo() const {
+bool CupsPrinter::EnsureDestInfo() const {
   if (dest_info_)
     return true;
 
diff --git a/printing/backend/cups_printer.h b/printing/backend/cups_printer.h
index d66ba52..720aae74 100644
--- a/printing/backend/cups_printer.h
+++ b/printing/backend/cups_printer.h
@@ -50,11 +50,9 @@
 // share an http connection which the CupsConnection closes on destruction.
 class PRINTING_EXPORT CupsPrinter : public CupsOptionProvider {
  public:
-  // Create a printer with a connection defined by |http| and |dest|.  |info|
-  // can be null and will be lazily initialized when needed.
+  // Create a printer with a connection defined by |http| and |dest|.
   CupsPrinter(http_t* http,
-              std::unique_ptr<cups_dest_t, DestinationDeleter> dest,
-              std::unique_ptr<cups_dinfo_t, DestInfoDeleter> info);
+              std::unique_ptr<cups_dest_t, DestinationDeleter> dest);
 
   CupsPrinter(CupsPrinter&& printer);
 
@@ -80,8 +78,8 @@
 
   std::string GetMakeAndModel() const;
 
-  // Returns true if the printer is currently reachable and working.
-  bool IsAvailable() const;
+  // Lazily initialize dest info as it can require a network call
+  bool EnsureDestInfo() const;
 
   // Populates |basic_info| with the relevant information about the printer
   bool ToPrinterInfo(PrinterBasicInfo* basic_info) const;
@@ -124,9 +122,6 @@
   bool CancelJob(int job_id);
 
  private:
-  // Lazily initialize dest info as it can require a network call
-  bool InitializeDestInfo() const;
-
   // http connection owned by the CupsConnection which created this object
   http_t* const cups_http_;
 
diff --git a/printing/backend/print_backend_cups_ipp.cc b/printing/backend/print_backend_cups_ipp.cc
index 2cd6362..8789dbd 100644
--- a/printing/backend/print_backend_cups_ipp.cc
+++ b/printing/backend/print_backend_cups_ipp.cc
@@ -66,7 +66,7 @@
                                               PrinterBasicInfo* printer_info) {
   std::unique_ptr<CupsPrinter> printer(
       cups_connection_->GetPrinter(printer_name));
-  if (!printer || !printer->IsAvailable())
+  if (!printer)
     return false;
 
   DCHECK_EQ(printer_name, printer->GetName());
@@ -79,7 +79,7 @@
     PrinterSemanticCapsAndDefaults* printer_info) {
   std::unique_ptr<CupsPrinter> printer(
       cups_connection_->GetPrinter(printer_name));
-  if (!printer || !printer->IsAvailable())
+  if (!printer || !printer->EnsureDestInfo())
     return false;
 
   CapsAndDefaultsFromPrinter(*printer, printer_info);
@@ -91,7 +91,7 @@
     const std::string& printer_name) {
   std::unique_ptr<CupsPrinter> printer(
       cups_connection_->GetPrinter(printer_name));
-  if (!printer || !printer->IsAvailable())
+  if (!printer)
     return std::string();
 
   DCHECK_EQ(printer_name, printer->GetName());
@@ -99,9 +99,7 @@
 }
 
 bool PrintBackendCupsIpp::IsValidPrinter(const std::string& printer_name) {
-  std::unique_ptr<CupsPrinter> printer(
-      cups_connection_->GetPrinter(printer_name));
-  return printer ? printer->IsAvailable() : false;
+  return !!cups_connection_->GetPrinter(printer_name);
 }
 
 }  // namespace printing
diff --git a/services/audio/test/audio_system_to_service_adapter_test.cc b/services/audio/test/audio_system_to_service_adapter_test.cc
index 0722b3ee4..e239779 100644
--- a/services/audio/test/audio_system_to_service_adapter_test.cc
+++ b/services/audio/test/audio_system_to_service_adapter_test.cc
@@ -69,7 +69,7 @@
   // AudioSystem conformance tests won't set expecnations.
   NiceMock<MockFunction<void(void)>> system_info_bind_requested_;
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<media::MockAudioManager> audio_manager_;
   std::unique_ptr<mojom::SystemInfo> system_info_impl_;
   std::unique_ptr<mojo::Receiver<mojom::SystemInfo>> system_info_receiver_;
@@ -433,8 +433,8 @@
   MOCK_METHOD0(ClientConnected, void(void));
   MOCK_METHOD0(ClientDisconnected, void(void));
 
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME};
 
   const base::Optional<std::string> valid_reply_{kValidReplyId};
   base::MockCallback<media::AudioSystem::OnDeviceIdCallback> response_received_;
diff --git a/services/device/bluetooth/bluetooth_system.cc b/services/device/bluetooth/bluetooth_system.cc
index 61852c89..ccc3e2bc 100644
--- a/services/device/bluetooth/bluetooth_system.cc
+++ b/services/device/bluetooth/bluetooth_system.cc
@@ -61,14 +61,15 @@
 
 void BluetoothSystem::Create(
     mojo::PendingReceiver<mojom::BluetoothSystem> receiver,
-    mojom::BluetoothSystemClientPtr client) {
+    mojo::PendingRemote<mojom::BluetoothSystemClient> client) {
   mojo::MakeSelfOwnedReceiver(
       std::make_unique<BluetoothSystem>(std::move(client)),
       std::move(receiver));
 }
 
-BluetoothSystem::BluetoothSystem(mojom::BluetoothSystemClientPtr client) {
-  client_ptr_ = std::move(client);
+BluetoothSystem::BluetoothSystem(
+    mojo::PendingRemote<mojom::BluetoothSystemClient> client)
+    : client_(std::move(client)) {
   GetBluetoothAdapterClient()->AddObserver(this);
 
   std::vector<dbus::ObjectPath> object_paths =
@@ -131,7 +132,7 @@
   if (properties->powered.name() == property_name)
     UpdateStateAndNotifyIfNecessary();
   else if (properties->discovering.name() == property_name)
-    client_ptr_->OnScanStateChanged(GetScanStateFromActiveAdapter());
+    client_->OnScanStateChanged(GetScanStateFromActiveAdapter());
 }
 
 void BluetoothSystem::GetState(GetStateCallback callback) {
@@ -159,7 +160,7 @@
 
   DCHECK_NE(state_, State::kTransitioning);
   state_ = State::kTransitioning;
-  client_ptr_->OnStateChanged(state_);
+  client_->OnStateChanged(state_);
 
   GetBluetoothAdapterClient()
       ->GetProperties(active_adapter_.value())
@@ -293,7 +294,7 @@
   }
 
   if (old_state != state_)
-    client_ptr_->OnStateChanged(state_);
+    client_->OnStateChanged(state_);
 }
 
 BluetoothSystem::ScanState BluetoothSystem::GetScanStateFromActiveAdapter() {
diff --git a/services/device/bluetooth/bluetooth_system.h b/services/device/bluetooth/bluetooth_system.h
index 34bf1e6..377bbc6 100644
--- a/services/device/bluetooth/bluetooth_system.h
+++ b/services/device/bluetooth/bluetooth_system.h
@@ -13,6 +13,8 @@
 #include "dbus/object_path.h"
 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/device/public/mojom/bluetooth_system.mojom.h"
 
 namespace bluez {
@@ -26,9 +28,10 @@
                         public bluez::BluetoothAdapterClient::Observer {
  public:
   static void Create(mojo::PendingReceiver<mojom::BluetoothSystem> receiver,
-                     mojom::BluetoothSystemClientPtr client);
+                     mojo::PendingRemote<mojom::BluetoothSystemClient> client);
 
-  explicit BluetoothSystem(mojom::BluetoothSystemClientPtr client);
+  explicit BluetoothSystem(
+      mojo::PendingRemote<mojom::BluetoothSystemClient> client);
   ~BluetoothSystem() override;
 
   // bluez::BluetoothAdapterClient::Observer
@@ -62,7 +65,7 @@
       StopScanCallback callback,
       const base::Optional<bluez::BluetoothAdapterClient::Error>& error);
 
-  mojom::BluetoothSystemClientPtr client_ptr_;
+  mojo::Remote<mojom::BluetoothSystemClient> client_;
 
   // The ObjectPath of the adapter being used. Updated as BT adapters are
   // added and removed. nullopt if there is no adapter.
diff --git a/services/device/bluetooth/bluetooth_system_factory.cc b/services/device/bluetooth/bluetooth_system_factory.cc
index 496ca3d..be0b883 100644
--- a/services/device/bluetooth/bluetooth_system_factory.cc
+++ b/services/device/bluetooth/bluetooth_system_factory.cc
@@ -24,7 +24,7 @@
 
 void BluetoothSystemFactory::Create(
     mojo::PendingReceiver<mojom::BluetoothSystem> system_receiver,
-    mojom::BluetoothSystemClientPtr system_client) {
+    mojo::PendingRemote<mojom::BluetoothSystemClient> system_client) {
   BluetoothSystem::Create(std::move(system_receiver), std::move(system_client));
 }
 
diff --git a/services/device/bluetooth/bluetooth_system_factory.h b/services/device/bluetooth/bluetooth_system_factory.h
index f6058aa..2e2d45d7 100644
--- a/services/device/bluetooth/bluetooth_system_factory.h
+++ b/services/device/bluetooth/bluetooth_system_factory.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/device/public/mojom/bluetooth_system.mojom.h"
 
 namespace device {
@@ -20,8 +21,9 @@
   ~BluetoothSystemFactory() override;
 
   // mojom::BluetoothSystemFactory
-  void Create(mojo::PendingReceiver<mojom::BluetoothSystem> system_receiver,
-              mojom::BluetoothSystemClientPtr system_client) override;
+  void Create(
+      mojo::PendingReceiver<mojom::BluetoothSystem> system_receiver,
+      mojo::PendingRemote<mojom::BluetoothSystemClient> system_client) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BluetoothSystemFactory);
diff --git a/services/device/bluetooth/bluetooth_system_unittest.cc b/services/device/bluetooth/bluetooth_system_unittest.cc
index d70fe2c..f1aab71 100644
--- a/services/device/bluetooth/bluetooth_system_unittest.cc
+++ b/services/device/bluetooth/bluetooth_system_unittest.cc
@@ -21,7 +21,7 @@
 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
 #include "device/bluetooth/dbus/bluetooth_device_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/device/device_service_test_base.h"
 #include "services/device/public/mojom/bluetooth_system.mojom-test-utils.h"
@@ -741,12 +741,9 @@
 
  protected:
   mojo::Remote<mojom::BluetoothSystem> CreateBluetoothSystem() {
-    mojom::BluetoothSystemClientPtr client_ptr;
-    system_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
-
     mojo::Remote<mojom::BluetoothSystem> system;
     system_factory_->Create(system.BindNewPipeAndPassReceiver(),
-                            std::move(client_ptr));
+                            system_client_receiver_.BindNewPipeAndPassRemote());
     return system;
   }
 
@@ -768,7 +765,7 @@
   TestBluetoothAdapterClient* test_bluetooth_adapter_client_;
   TestBluetoothDeviceClient* test_bluetooth_device_client_;
 
-  mojo::Binding<mojom::BluetoothSystemClient> system_client_binding_{this};
+  mojo::Receiver<mojom::BluetoothSystemClient> system_client_receiver_{this};
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BluetoothSystemTest);
@@ -777,15 +774,12 @@
 // Tests that the Create method for BluetoothSystemFactory works.
 TEST_F(BluetoothSystemTest, FactoryCreate) {
   mojo::Remote<mojom::BluetoothSystem> system;
-  mojo::Binding<mojom::BluetoothSystemClient> client_binding(this);
-
-  mojom::BluetoothSystemClientPtr client_ptr;
-  client_binding.Bind(mojo::MakeRequest(&client_ptr));
+  mojo::Receiver<mojom::BluetoothSystemClient> client_receiver(this);
 
   EXPECT_FALSE(system.is_bound());
 
   system_factory_->Create(system.BindNewPipeAndPassReceiver(),
-                          std::move(client_ptr));
+                          client_receiver.BindNewPipeAndPassRemote());
   base::RunLoop run_loop;
   system.FlushAsyncForTesting(run_loop.QuitClosure());
   run_loop.Run();
diff --git a/services/device/public/mojom/bluetooth_system.mojom b/services/device/public/mojom/bluetooth_system.mojom
index 3f958b33..8a3a5df8 100644
--- a/services/device/public/mojom/bluetooth_system.mojom
+++ b/services/device/public/mojom/bluetooth_system.mojom
@@ -73,7 +73,7 @@
 // Factory to get an instance of the BluetoothSystem interface.
 interface BluetoothSystemFactory {
   Create(pending_receiver<BluetoothSystem> system,
-         BluetoothSystemClient system_client);
+         pending_remote<BluetoothSystemClient> system_client);
 };
 
 // High level interface targeted towards UI level components that:
diff --git a/services/tracing/perfetto/test_utils.cc b/services/tracing/perfetto/test_utils.cc
index a11dd2d..f234325 100644
--- a/services/tracing/perfetto/test_utils.cc
+++ b/services/tracing/perfetto/test_utils.cc
@@ -232,7 +232,7 @@
                                bool has_more) {
   for (auto& encoded_packet : packets) {
     perfetto::protos::TracePacket packet;
-    EXPECT_TRUE(encoded_packet.Decode(&packet));
+    EXPECT_TRUE(packet.ParseFromString(encoded_packet.GetRawBytesForTesting()));
     ++received_packets_;
     if (packet.for_testing().str() == kPerfettoTestString) {
       ++received_test_packets_;
diff --git a/services/tracing/perfetto/track_event_json_exporter.cc b/services/tracing/perfetto/track_event_json_exporter.cc
index c3fdd911..f44b1e31 100644
--- a/services/tracing/perfetto/track_event_json_exporter.cc
+++ b/services/tracing/perfetto/track_event_json_exporter.cc
@@ -10,6 +10,7 @@
 #include "base/json/string_escape.h"
 #include "base/strings/string_util.h"
 #include "base/trace_event/common/trace_event_common.h"
+#include "third_party/perfetto/include/perfetto/ext/tracing/core/sliced_protobuf_input_stream.h"
 #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_packet.pb.h"
 
 namespace tracing {
@@ -85,7 +86,8 @@
     // reduces binary bloat and only has the fields we are interested in. So
     // Decode the serialized proto as a ChromeTracePacket.
     perfetto::protos::ChromeTracePacket packet;
-    bool decoded = encoded_packet.Decode(&packet);
+    ::perfetto::SlicedProtobufInputStream stream(&encoded_packet.slices());
+    bool decoded = packet.ParseFromZeroCopyStream(&stream);
     DCHECK(decoded);
 
     // If this is a different packet_sequence_id we have to reset all our state
diff --git a/services/video_capture/test/virtual_device_unittest.cc b/services/video_capture/test/virtual_device_unittest.cc
index 62bdb868..6f15ace 100644
--- a/services/video_capture/test/virtual_device_unittest.cc
+++ b/services/video_capture/test/virtual_device_unittest.cc
@@ -95,7 +95,7 @@
   std::unique_ptr<MockProducer> producer_;
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   media::VideoCaptureDeviceInfo device_info_;
 };
 
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index 1a7f5e4..59614d0 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -83,8 +83,6 @@
     "fileapi/file_system_backend.h",
     "fileapi/file_system_context.cc",
     "fileapi/file_system_context.h",
-    "fileapi/file_system_features.cc",
-    "fileapi/file_system_features.h",
     "fileapi/file_system_file_stream_reader.cc",
     "fileapi/file_system_file_stream_reader.h",
     "fileapi/file_system_file_util.cc",
diff --git a/storage/browser/fileapi/file_system_context.cc b/storage/browser/fileapi/file_system_context.cc
index e34edd52..252abc1 100644
--- a/storage/browser/fileapi/file_system_context.cc
+++ b/storage/browser/fileapi/file_system_context.cc
@@ -474,20 +474,12 @@
       FileSystemURL(url::Origin::Create(origin), type, path));
 }
 
-#if defined(OS_CHROMEOS)
-void FileSystemContext::EnableTemporaryFileSystemInIncognito() {
-  sandbox_backend_->set_enable_temporary_file_system_in_incognito(true);
-}
-#endif
-
 bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const {
   // We never support accessing files in isolated filesystems via an URL.
   if (url.mount_type() == kFileSystemTypeIsolated)
     return false;
-  if (url.type() == kFileSystemTypeTemporary &&
-      sandbox_backend_->enable_temporary_file_system_in_incognito()) {
+  if (url.type() == kFileSystemTypeTemporary)
     return true;
-  }
   return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
 }
 
diff --git a/storage/browser/fileapi/file_system_context.h b/storage/browser/fileapi/file_system_context.h
index b49512b..0274165 100644
--- a/storage/browser/fileapi/file_system_context.h
+++ b/storage/browser/fileapi/file_system_context.h
@@ -279,12 +279,6 @@
                                            FileSystemType type,
                                            const base::FilePath& path) const;
 
-#if defined(OS_CHROMEOS)
-  // Used only on ChromeOS for now. It can be removed when
-  // kEnableFilesystemInIncognito feature flag is removed.
-  void EnableTemporaryFileSystemInIncognito();
-#endif
-
   SandboxFileSystemBackendDelegate* sandbox_delegate() {
     return sandbox_delegate_.get();
   }
diff --git a/storage/browser/fileapi/file_system_features.cc b/storage/browser/fileapi/file_system_features.cc
deleted file mode 100644
index fb35cfe..0000000
--- a/storage/browser/fileapi/file_system_features.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "storage/browser/fileapi/file_system_features.h"
-
-namespace storage {
-
-namespace features {
-
-// Enables Filesystem API in incognito mode.
-const base::Feature kEnableFilesystemInIncognito{
-    "EnableFilesystemInIncognito", base::FEATURE_ENABLED_BY_DEFAULT};
-}  // namespace features
-
-}  // namespace storage
diff --git a/storage/browser/fileapi/file_system_features.h b/storage/browser/fileapi/file_system_features.h
deleted file mode 100644
index 7c5861b3..0000000
--- a/storage/browser/fileapi/file_system_features.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_FEATURES_H_
-#define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_FEATURES_H_
-
-#include "base/component_export.h"
-#include "base/feature_list.h"
-
-namespace storage {
-
-namespace features {
-
-COMPONENT_EXPORT(STORAGE_BROWSER)
-extern const base::Feature kEnableFilesystemInIncognito;
-
-}  // namespace features
-
-}  // namespace storage
-
-#endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_FEATURES_H_
\ No newline at end of file
diff --git a/storage/browser/fileapi/file_system_file_stream_reader.cc b/storage/browser/fileapi/file_system_file_stream_reader.cc
index dffd4b9e..8657f56 100644
--- a/storage/browser/fileapi/file_system_file_stream_reader.cc
+++ b/storage/browser/fileapi/file_system_file_stream_reader.cc
@@ -15,7 +15,6 @@
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation_runner.h"
 #include "storage/browser/fileapi/obfuscated_file_util_memory_delegate.h"
 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
@@ -102,8 +101,7 @@
   // Keep the reference (if it's non-null) so that the file won't go away.
   snapshot_ref_ = std::move(file_ref);
 
-  if (file_system_context_->is_incognito() &&
-      base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
+  if (file_system_context_->is_incognito()) {
     base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate;
     if (url_.type() == kFileSystemTypePluginPrivate) {
       auto* backend = static_cast<PluginPrivateFileSystemBackend*>(
diff --git a/storage/browser/fileapi/file_system_usage_cache_unittest.cc b/storage/browser/fileapi/file_system_usage_cache_unittest.cc
index 6641e9ee..6144fee 100644
--- a/storage/browser/fileapi/file_system_usage_cache_unittest.cc
+++ b/storage/browser/fileapi/file_system_usage_cache_unittest.cc
@@ -11,9 +11,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using storage::FileSystemUsageCache;
@@ -23,12 +21,7 @@
 class FileSystemUsageCacheTest : public testing::Test,
                                  public ::testing::WithParamInterface<bool> {
  public:
-  FileSystemUsageCacheTest() : usage_cache_(is_incognito()) {
-    if (is_incognito()) {
-      feature_list_.InitAndEnableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    }
-  }
+  FileSystemUsageCacheTest() : usage_cache_(is_incognito()) {}
 
   void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); }
 
@@ -42,7 +35,6 @@
   FileSystemUsageCache* usage_cache() { return &usage_cache_; }
 
  private:
-  base::test::ScopedFeatureList feature_list_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   base::ScopedTempDir data_dir_;
   FileSystemUsageCache usage_cache_;
diff --git a/storage/browser/fileapi/obfuscated_file_util.cc b/storage/browser/fileapi/obfuscated_file_util.cc
index bdb9c54f..fe268d7 100644
--- a/storage/browser/fileapi/obfuscated_file_util.cc
+++ b/storage/browser/fileapi/obfuscated_file_util.cc
@@ -24,7 +24,6 @@
 #include "base/time/time.h"
 #include "storage/browser/fileapi/file_observers.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation_context.h"
 #include "storage/browser/fileapi/obfuscated_file_util_disk_delegate.h"
 #include "storage/browser/fileapi/obfuscated_file_util_memory_delegate.h"
@@ -280,8 +279,7 @@
   DCHECK(!is_incognito_ ||
          (env_override && leveldb_chrome::IsMemEnv(env_override)));
 
-  if (is_incognito_ &&
-      base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
+  if (is_incognito_) {
     delegate_ = std::make_unique<ObfuscatedFileUtilMemoryDelegate>(
         file_system_directory_);
   } else {
@@ -955,8 +953,7 @@
 
   InitOriginDatabase(GURL(), false);
   base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> file_util_delegate;
-  if (is_incognito() &&
-      base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
+  if (is_incognito()) {
     file_util_delegate =
         static_cast<ObfuscatedFileUtilMemoryDelegate*>(delegate())
             ->GetWeakPtr();
diff --git a/storage/browser/fileapi/obfuscated_file_util_unittest.cc b/storage/browser/fileapi/obfuscated_file_util_unittest.cc
index f4889aee..1c4e70e 100644
--- a/storage/browser/fileapi/obfuscated_file_util_unittest.cc
+++ b/storage/browser/fileapi/obfuscated_file_util_unittest.cc
@@ -29,7 +29,6 @@
 #include "storage/browser/fileapi/external_mount_points.h"
 #include "storage/browser/fileapi/file_system_backend.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation_context.h"
 #include "storage/browser/fileapi/file_system_usage_cache.h"
 #include "storage/browser/fileapi/obfuscated_file_util.h"
@@ -71,7 +70,7 @@
 
 namespace {
 
-enum TestMode { kRegular, kIncognitoDisabled, kIncognitoEnabled };
+enum TestMode { kRegular, kIncognito };
 
 bool FileExists(const base::FilePath& path) {
   return base::PathExists(path) && !base::DirectoryExists(path);
@@ -174,22 +173,9 @@
         type_(storage::kFileSystemTypeTemporary),
         sandbox_file_system_(origin_, type_),
         quota_status_(blink::mojom::QuotaStatusCode::kUnknown),
-        usage_(-1) {
-    if (GetParam() == TestMode::kRegular) {
-      is_incognito_ = false;
-      return;
-    }
-    is_incognito_ = true;
-    if (GetParam() == TestMode::kIncognitoDisabled) {
-      feature_list_.InitAndDisableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    } else {
-      feature_list_.InitAndEnableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    }
-  }
+        usage_(-1) {}
 
-  bool in_memory_test() { return GetParam() == TestMode::kIncognitoEnabled; }
+  bool is_incognito() { return GetParam() == TestMode::kIncognito; }
 
   void SetUp() override {
     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
@@ -197,7 +183,7 @@
     storage_policy_ = new MockSpecialStoragePolicy();
 
     quota_manager_ = new storage::QuotaManager(
-        is_incognito_, data_dir_.GetPath(),
+        is_incognito(), data_dir_.GetPath(),
         base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get(),
         storage::GetQuotaSettingsFunc());
     storage::QuotaSettings settings;
@@ -212,24 +198,24 @@
     // another sandbox_backend, and another OFU.
     // We need to pass in the context to skip all that.
     file_system_context_ =
-        in_memory_test() ? CreateIncognitoFileSystemContextForTesting(
-                               base::ThreadTaskRunnerHandle::Get(),
-                               base::ThreadTaskRunnerHandle::Get(),
-                               quota_manager_->proxy(), data_dir_.GetPath())
-                         : CreateFileSystemContextForTesting(
-                               quota_manager_->proxy(), data_dir_.GetPath());
+        is_incognito() ? CreateIncognitoFileSystemContextForTesting(
+                             base::ThreadTaskRunnerHandle::Get(),
+                             base::ThreadTaskRunnerHandle::Get(),
+                             quota_manager_->proxy(), data_dir_.GetPath())
+                       : CreateFileSystemContextForTesting(
+                             quota_manager_->proxy(), data_dir_.GetPath());
 
     sandbox_file_system_.SetUp(file_system_context_.get());
 
     change_observers_ =
         storage::MockFileChangeObserver::CreateList(&change_observer_);
 
-    if (is_incognito_)
+    if (is_incognito())
       incognito_leveldb_environment_ = leveldb_chrome::NewMemEnv("FileSystem");
   }
 
   void TearDown() override {
-    if (in_memory_test())
+    if (is_incognito())
       ASSERT_TRUE(IsDirectoryEmpty(data_dir_.GetPath()));
 
     quota_manager_ = nullptr;
@@ -289,8 +275,8 @@
     return std::unique_ptr<ObfuscatedFileUtil>(
         ObfuscatedFileUtil::CreateForTesting(
             storage_policy, data_dir_path(),
-            is_incognito_ ? incognito_leveldb_environment_.get() : nullptr,
-            is_incognito_));
+            is_incognito() ? incognito_leveldb_environment_.get() : nullptr,
+            is_incognito()));
   }
 
   ObfuscatedFileUtil* ofu() {
@@ -390,14 +376,14 @@
     EXPECT_EQ(base::File::FILE_OK,
               ofu()->GetFileInfo(context.get(), url, &file_info0, &data_path));
     EXPECT_EQ(data_path, local_path);
-    EXPECT_EQ(!in_memory_test(), FileExists(data_path));
+    EXPECT_EQ(!is_incognito(), FileExists(data_path));
 
     const char data[] = "test data";
     const int length = base::size(data) - 1;
 
     base::File file = ofu()->CreateOrOpen(
         context.get(), url, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
-    if (in_memory_test()) {
+    if (is_incognito()) {
       ASSERT_FALSE(file.IsValid());
       auto* memory_delegate =
           static_cast<storage::ObfuscatedFileUtilMemoryDelegate*>(
@@ -414,7 +400,7 @@
     }
 
     base::File::Info file_info1;
-    if (!in_memory_test())
+    if (!is_incognito())
       EXPECT_EQ(length, GetLocalFileSize(data_path));
     EXPECT_EQ(length, GetPathSize(url));
     context.reset(NewContext(nullptr));
@@ -825,13 +811,12 @@
   void CheckFileSize(FileSystemURL& url,
                      base::FilePath& local_path,
                      int64_t expected_size) {
-    if (!in_memory_test())
+    if (!is_incognito())
       EXPECT_EQ(expected_size, GetLocalFileSize(local_path));
     EXPECT_EQ(expected_size, GetPathSize(url));
   }
 
  protected:
-  bool is_incognito_;
   base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<leveldb::Env> incognito_leveldb_environment_;
   base::test::TaskEnvironment task_environment_;
@@ -855,8 +840,7 @@
 INSTANTIATE_TEST_SUITE_P(,
                          ObfuscatedFileUtilTest,
                          testing::Values(TestMode::kRegular,
-                                         TestMode::kIncognitoDisabled,
-                                         TestMode::kIncognitoEnabled));
+                                         TestMode::kIncognito));
 
 TEST_P(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
   FileSystemURL url = CreateURLFromUTF8("fake/file");
@@ -897,7 +881,7 @@
   base::FilePath local_path;
   EXPECT_EQ(base::File::FILE_OK,
             ofu()->GetLocalFilePath(context.get(), url, &local_path));
-  EXPECT_EQ(!in_memory_test(), base::PathExists(local_path));
+  EXPECT_NE(is_incognito(), base::PathExists(local_path));
   EXPECT_TRUE(PathExists(url));
 
   // Verify that deleting a file isn't stopped by zero quota, and that it frees
@@ -934,7 +918,7 @@
   context.reset(NewContext(nullptr));
   EXPECT_EQ(base::File::FILE_OK,
             ofu()->GetLocalFilePath(context.get(), url, &local_path));
-  EXPECT_EQ(!in_memory_test(), base::PathExists(local_path));
+  EXPECT_NE(is_incognito(), base::PathExists(local_path));
   EXPECT_TRUE(PathExists(url));
 
   context.reset(NewContext(nullptr));
@@ -1025,7 +1009,7 @@
     ASSERT_EQ(1019, ComputeTotalFileSize());
   }
 
-  if (!in_memory_test()) {
+  if (!is_incognito()) {
     // Delete backing file to make following truncation fail.
     base::FilePath local_path;
     ASSERT_EQ(
@@ -2395,7 +2379,7 @@
   // TODO(https://crbug.com/936722): After CreateOrOpen is modified to return
   // file error instead of file, the in-memory test can proceed through the next
   // steps.
-  if (in_memory_test())
+  if (is_incognito())
     return;
 
   // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
diff --git a/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc b/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
index a8d346b..285b50d 100644
--- a/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
+++ b/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_usage_cache.h"
 #include "storage/browser/fileapi/obfuscated_file_util.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
@@ -101,12 +100,7 @@
  public:
   QuotaBackendImplTest()
       : file_system_usage_cache_(is_incognito()),
-        quota_manager_proxy_(new MockQuotaManagerProxy) {
-    if (is_incognito()) {
-      feature_list_.InitAndEnableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    }
-  }
+        quota_manager_proxy_(new MockQuotaManagerProxy) {}
 
   void SetUp() override {
     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.cc b/storage/browser/fileapi/sandbox_file_stream_writer.cc
index fd018c9..10257d3 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.cc
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.cc
@@ -18,7 +18,6 @@
 #include "storage/browser/fileapi/file_observers.h"
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation_runner.h"
 #include "storage/browser/fileapi/obfuscated_file_util_memory_delegate.h"
 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
@@ -143,8 +142,7 @@
   }
   DCHECK(!file_writer_.get());
 
-  if (file_system_context_->is_incognito() &&
-      base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
+  if (file_system_context_->is_incognito()) {
     base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate;
     if (url_.type() == kFileSystemTypePluginPrivate) {
       auto* backend = static_cast<PluginPrivateFileSystemBackend*>(
diff --git a/storage/browser/fileapi/sandbox_file_system_backend.cc b/storage/browser/fileapi/sandbox_file_system_backend.cc
index b1a073e..e6e58337 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend.cc
+++ b/storage/browser/fileapi/sandbox_file_system_backend.cc
@@ -19,7 +19,6 @@
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "storage/browser/fileapi/file_stream_writer.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation.h"
 #include "storage/browser/fileapi/file_system_operation_context.h"
 #include "storage/browser/fileapi/file_system_options.h"
@@ -38,9 +37,7 @@
 
 SandboxFileSystemBackend::SandboxFileSystemBackend(
     SandboxFileSystemBackendDelegate* delegate)
-    : delegate_(delegate),
-      enable_temporary_file_system_in_incognito_(base::FeatureList::IsEnabled(
-          features::kEnableFilesystemInIncognito)) {}
+    : delegate_(delegate) {}
 
 SandboxFileSystemBackend::~SandboxFileSystemBackend() = default;
 
@@ -68,8 +65,7 @@
   DCHECK(CanHandleType(url.type()));
   DCHECK(delegate_);
   if (delegate_->file_system_options().is_incognito() &&
-      !(url.type() == kFileSystemTypeTemporary &&
-        enable_temporary_file_system_in_incognito_)) {
+      url.type() != kFileSystemTypeTemporary) {
     // TODO(kinuko): return an isolated temporary directory.
     std::move(callback).Run(GURL(), std::string(),
                             base::File::FILE_ERROR_SECURITY);
diff --git a/storage/browser/fileapi/sandbox_file_system_backend.h b/storage/browser/fileapi/sandbox_file_system_backend.h
index 921ccfe..b5acfdb9 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend.h
+++ b/storage/browser/fileapi/sandbox_file_system_backend.h
@@ -74,19 +74,9 @@
   // This method can only be called on the file thread.
   SandboxFileSystemBackendDelegate::OriginEnumerator* CreateOriginEnumerator();
 
-  void set_enable_temporary_file_system_in_incognito(bool enable) {
-    enable_temporary_file_system_in_incognito_ = enable;
-  }
-  bool enable_temporary_file_system_in_incognito() const {
-    return enable_temporary_file_system_in_incognito_;
-  }
-
-
  private:
   SandboxFileSystemBackendDelegate* delegate_;  // Not owned.
 
-  bool enable_temporary_file_system_in_incognito_;
-
   DISALLOW_COPY_AND_ASSIGN(SandboxFileSystemBackend);
 };
 
diff --git a/storage/browser/fileapi/sandbox_file_system_backend_unittest.cc b/storage/browser/fileapi/sandbox_file_system_backend_unittest.cc
index 11a487d..2a353dd8 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend_unittest.cc
+++ b/storage/browser/fileapi/sandbox_file_system_backend_unittest.cc
@@ -15,11 +15,9 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "storage/browser/fileapi/file_system_backend.h"
-#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_url.h"
 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
 #include "storage/browser/test/test_file_system_options.h"
@@ -75,18 +73,9 @@
 
 }  // namespace
 
-class SandboxFileSystemBackendTest
-    : public testing::Test,
-      public ::testing::WithParamInterface<bool> {
+class SandboxFileSystemBackendTest : public testing::Test {
  protected:
   void SetUp() override {
-    if (IsIncognitoEnabled()) {
-      feature_list_.InitAndEnableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    } else {
-      feature_list_.InitAndDisableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    }
     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
     SetUpNewDelegate(CreateAllowFileAccessOptions());
   }
@@ -105,8 +94,6 @@
     backend_.reset(new SandboxFileSystemBackend(delegate_.get()));
   }
 
-  bool IsIncognitoEnabled() { return GetParam(); }
-
   storage::SandboxFileSystemBackendDelegate::OriginEnumerator*
   CreateOriginEnumerator() const {
     return backend_->CreateOriginEnumerator();
@@ -150,19 +137,16 @@
   base::test::TaskEnvironment task_environment_;
   std::unique_ptr<storage::SandboxFileSystemBackendDelegate> delegate_;
   std::unique_ptr<storage::SandboxFileSystemBackend> backend_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(, SandboxFileSystemBackendTest, ::testing::Bool());
-
-TEST_P(SandboxFileSystemBackendTest, Empty) {
+TEST_F(SandboxFileSystemBackendTest, Empty) {
   SetUpNewBackend(CreateAllowFileAccessOptions());
   std::unique_ptr<SandboxFileSystemBackendDelegate::OriginEnumerator>
       enumerator(CreateOriginEnumerator());
   ASSERT_TRUE(enumerator->Next().is_empty());
 }
 
-TEST_P(SandboxFileSystemBackendTest, EnumerateOrigins) {
+TEST_F(SandboxFileSystemBackendTest, EnumerateOrigins) {
   SetUpNewBackend(CreateAllowFileAccessOptions());
   const char* temporary_origins[] = {
     "http://www.bar.com/",
@@ -211,7 +195,7 @@
   EXPECT_EQ(persistent_size, persistent_actual_size);
 }
 
-TEST_P(SandboxFileSystemBackendTest, GetRootPathCreateAndExamine) {
+TEST_F(SandboxFileSystemBackendTest, GetRootPathCreateAndExamine) {
   std::vector<base::FilePath> returned_root_path(
       base::size(kRootPathTestCases));
   SetUpNewBackend(CreateAllowFileAccessOptions());
@@ -251,7 +235,7 @@
   }
 }
 
-TEST_P(SandboxFileSystemBackendTest,
+TEST_F(SandboxFileSystemBackendTest,
        GetRootPathCreateAndExamineWithNewBackend) {
   std::vector<base::FilePath> returned_root_path(
       base::size(kRootPathTestCases));
@@ -275,7 +259,7 @@
   EXPECT_EQ(root_path1.value(), root_path2.value());
 }
 
-TEST_P(SandboxFileSystemBackendTest, GetRootPathGetWithoutCreate) {
+TEST_F(SandboxFileSystemBackendTest, GetRootPathGetWithoutCreate) {
   SetUpNewBackend(CreateDisallowFileAccessOptions());
 
   // Try to get a root directory without creating.
@@ -288,7 +272,7 @@
   }
 }
 
-TEST_P(SandboxFileSystemBackendTest, GetRootPathInIncognito) {
+TEST_F(SandboxFileSystemBackendTest, GetRootPathInIncognito) {
   SetUpNewBackend(CreateIncognitoFileSystemOptions());
 
   // Try to get a root directory.
@@ -296,15 +280,14 @@
     SCOPED_TRACE(testing::Message() << "RootPath (incognito) #" << i << " "
                  << kRootPathTestCases[i].expected_path);
     EXPECT_EQ(
-        IsIncognitoEnabled() &&
-            kRootPathTestCases[i].type == storage::kFileSystemTypeTemporary,
+        kRootPathTestCases[i].type == storage::kFileSystemTypeTemporary,
         GetRootPath(GURL(kRootPathTestCases[i].origin_url),
                     kRootPathTestCases[i].type,
                     storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, nullptr));
   }
 }
 
-TEST_P(SandboxFileSystemBackendTest, GetRootPathFileURI) {
+TEST_F(SandboxFileSystemBackendTest, GetRootPathFileURI) {
   SetUpNewBackend(CreateDisallowFileAccessOptions());
   for (size_t i = 0; i < base::size(kRootPathFileURITestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "RootPathFileURI (disallow) #"
@@ -316,7 +299,7 @@
   }
 }
 
-TEST_P(SandboxFileSystemBackendTest, GetRootPathFileURIWithAllowFlag) {
+TEST_F(SandboxFileSystemBackendTest, GetRootPathFileURIWithAllowFlag) {
   SetUpNewBackend(CreateAllowFileAccessOptions());
   for (size_t i = 0; i < base::size(kRootPathFileURITestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "RootPathFileURI (allow) #"
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 90acaf951..d655ac6 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -791,6 +791,29 @@
             ]
         }
     ],
+    "AutofillKeyboardAccessory": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_Full",
+                    "enable_features": [
+                        "AutofillKeyboardAccessoryView",
+                        "AutofillManualFallbackAndroid"
+                    ]
+                },
+                {
+                    "name": "Disabled",
+                    "disable_features": [
+                        "AutofillKeyboardAccessoryView",
+                        "AutofillManualFallbackAndroid"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutofillLocalCardMigrationUsesStrikeSystemV2": [
         {
             "platforms": [
@@ -4166,29 +4189,6 @@
             ]
         }
     ],
-    "PasswordsKeyboardAccessory": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "AutomaticPasswordGeneration",
-                        "PasswordsKeyboardAccessory"
-                    ]
-                },
-                {
-                    "name": "Disabled",
-                    "disable_features": [
-                        "AutomaticPasswordGeneration",
-                        "PasswordsKeyboardAccessory"
-                    ]
-                }
-            ]
-        }
-    ],
     "PauseBrowserInitiatedHeavyTrafficForP2P": [
         {
             "platforms": [
diff --git a/third_party/blink/perf_tests/websocket/server.js b/third_party/blink/perf_tests/websocket/server.js
index 75caac5..3a59b3e 100644
--- a/third_party/blink/perf_tests/websocket/server.js
+++ b/third_party/blink/perf_tests/websocket/server.js
@@ -7,11 +7,31 @@
 console.log(getNow() + " WebSocket server started.");
 const arrayBuf = 1000*1000; // 1MB
 const totalIter = 100;
-ws_server.on('connection', function(ws_socket) {
-  console.log(getNow() + " Connection established.");
-  const data = new ArrayBuffer(arrayBuf);
-  for (let i = 0; i < totalIter; i++) {
-    ws_socket.send(data, {binary: true});
+
+const charArray1000 = [];
+for (i = 0; i < 1000; i++) {
+  charArray1000.push(i % 128);
+}
+const asciiArray1K = String.fromCharCode.apply(this, charArray1000);
+const textArray1M = [];
+for (i = 0; i < 1000; i++) {
+  textArray1M.push(asciiArray1K);
+}
+const asciiText1MB = textArray1M.join('');
+
+ws_server.on('connection', function(ws_socket, request) {
+  console.log(getNow() + ' Connection established. url=' + request.url);
+  if (request.url === '/') {
+    const data = new ArrayBuffer(arrayBuf);
+    for (let i = 0; i < totalIter; i++) {
+      ws_socket.send(data, {binary: true});
+    }
+  } else if (request.url === '/text') {
+    for (let i = 0; i < totalIter; i++) {
+      ws_socket.send(asciiText1MB);
+    }
+  } else {
+    console.log('Invalid request: ' + request.url);
   }
   ws_socket.close();
   console.log(getNow() + " Connection closed.");
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 83c483ab..f9ebdf8 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -149,12 +149,20 @@
     "platform/modules/mediastream/web_platform_media_stream_source.h",
     "platform/modules/mediastream/web_platform_media_stream_track.h",
     "platform/modules/mediastream/webrtc_uma_histograms.h",
+    "platform/modules/p2p/empty_network_manager.h",
+    "platform/modules/p2p/filtering_network_manager.h",
+    "platform/modules/p2p/ipc_network_manager.h",
+    "platform/modules/p2p/network_list_manager.h",
+    "platform/modules/p2p/network_list_observer.h",
     "platform/modules/p2p/network_manager_uma.h",
+    "platform/modules/p2p/socket_client.h",
+    "platform/modules/p2p/socket_client_delegate.h",
     "platform/modules/peerconnection/audio_codec_factory.h",
     "platform/modules/peerconnection/rtc_event_log_output_sink.h",
     "platform/modules/peerconnection/rtc_event_log_output_sink_proxy_util.h",
     "platform/modules/peerconnection/rtc_video_decoder_factory_util.h",
     "platform/modules/peerconnection/rtc_video_encoder_factory_util.h",
+    "platform/modules/peerconnection/stun_field_trial.h",
     "platform/modules/peerconnection/two_keys_adapter_map.h",
     "platform/modules/peerconnection/video_codec_factory.h",
     "platform/modules/peerconnection/webrtc_audio_sink.h",
@@ -554,9 +562,13 @@
     "//third_party/webrtc/modules/audio_device:audio_device_api",
     "//third_party/webrtc/modules/audio_processing:api",
     "//third_party/webrtc/modules/video_coding:video_codec_interface",
+    "//third_party/webrtc/p2p:libstunprober",
     "//third_party/webrtc/pc:peerconnection",
     "//third_party/webrtc/rtc_base:rtc_base",
     "//third_party/webrtc/rtc_base:rtc_task_queue",
+
+    # TODO(titovartem) remove dependency on WebRTC internals.
+    "//third_party/webrtc/rtc_base/third_party/sigslot:sigslot",
     "//third_party/webrtc_overrides:init_webrtc",
     "//ui/base:base",
     "//v8:v8_headers",
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index 18587dd..62aa0ba 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2410,6 +2410,8 @@
   kPointerLockUnadjustedMovement = 3027,
   kCreateObjectBlob = 3028,
   kQuotaRead = 3029,
+  kDelegateFocus = 3030,
+  kDelegateFocusNotFirstInFlatTree = 3031,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/modules/p2p/DEPS b/third_party/blink/public/platform/modules/p2p/DEPS
new file mode 100644
index 0000000..66a33743
--- /dev/null
+++ b/third_party/blink/public/platform/modules/p2p/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+    "+net/base/ip_endpoint.h",
+    "+services/network/public/cpp/p2p_socket_type.h",
+]
diff --git a/content/renderer/p2p/empty_network_manager.h b/third_party/blink/public/platform/modules/p2p/empty_network_manager.h
similarity index 75%
rename from content/renderer/p2p/empty_network_manager.h
rename to third_party/blink/public/platform/modules/p2p/empty_network_manager.h
index 65220f46..41f5495 100644
--- a/content/renderer/p2p/empty_network_manager.h
+++ b/third_party/blink/public/platform/modules/p2p/empty_network_manager.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_P2P_EMPTY_NETWORK_MANAGER_H_
-#define CONTENT_RENDERER_P2P_EMPTY_NETWORK_MANAGER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_EMPTY_NETWORK_MANAGER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_EMPTY_NETWORK_MANAGER_H_
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/webrtc/rtc_base/network.h"
 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
 
@@ -16,19 +16,22 @@
 class IPAddress;
 }  // namespace rtc
 
-namespace content {
+namespace blink {
 
 // A NetworkManager implementation which handles the case where local address
 // enumeration is not requested and just returns empty network lists. This class
 // is not thread safe and should only be used by WebRTC's network thread.
+//
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also, move it away from std::vector.
 class EmptyNetworkManager : public rtc::NetworkManagerBase,
                             public sigslot::has_slots<> {
  public:
   // This class is created by WebRTC's signaling thread but used by WebRTC's
   // worker thread |task_runner|.
-  CONTENT_EXPORT explicit EmptyNetworkManager(
+  BLINK_PLATFORM_EXPORT explicit EmptyNetworkManager(
       rtc::NetworkManager* network_manager);
-  CONTENT_EXPORT ~EmptyNetworkManager() override;
+  BLINK_PLATFORM_EXPORT ~EmptyNetworkManager() override;
 
   // rtc::NetworkManager:
   void StartUpdating() override;
@@ -45,7 +48,7 @@
   // default IP addresses.
   void OnNetworksChanged();
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Whether we have fired the first SignalNetworksChanged.
   // Used to ensure we only report metrics once.
@@ -64,6 +67,6 @@
   DISALLOW_COPY_AND_ASSIGN(EmptyNetworkManager);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_EMPTY_NETWORK_MANAGER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_EMPTY_NETWORK_MANAGER_H_
diff --git a/content/renderer/p2p/filtering_network_manager.h b/third_party/blink/public/platform/modules/p2p/filtering_network_manager.h
similarity index 83%
rename from content/renderer/p2p/filtering_network_manager.h
rename to third_party/blink/public/platform/modules/p2p/filtering_network_manager.h
index eeff4d8e..bb957e6 100644
--- a/content/renderer/p2p/filtering_network_manager.h
+++ b/third_party/blink/public/platform/modules/p2p/filtering_network_manager.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_P2P_FILTERING_NETWORK_MANAGER_H_
-#define CONTENT_RENDERER_P2P_FILTERING_NETWORK_MANAGER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_FILTERING_NETWORK_MANAGER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_FILTERING_NETWORK_MANAGER_H_
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
-#include "content/common/content_export.h"
 #include "third_party/blink/public/platform/modules/p2p/network_manager_uma.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/webrtc/rtc_base/network.h"
 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
 #include "url/gurl.h"
@@ -19,7 +19,7 @@
 class MediaPermission;
 }  // namespace media
 
-namespace content {
+namespace blink {
 
 // FilteringNetworkManager exposes rtc::NetworkManager to
 // PeerConnectionDependencyFactory and wraps the IpcNetworkManager. It only
@@ -32,19 +32,22 @@
 // to reduce any extra call setup delay. This class is not thread safe and
 // should only be used by WebRTC's network thread. It inherits from
 // rtc::NetworkManagerBase to have the same implementation of
-// GetAnyAddressNetworks(). We can't mark the whole class CONTENT_EXPORT as it
-// requires all super classes to be CONTENT_EXPORT as well.
+// GetAnyAddressNetworks(). We can't mark the whole class BLINK_PLATFORM_EXPORT
+// as it requires all super classes to be BLINK_PLATFORM_EXPORT as well.
+//
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also, move it away from url/gurl.h.
 class FilteringNetworkManager : public rtc::NetworkManagerBase,
                                 public sigslot::has_slots<> {
  public:
   // This class is created by WebRTC's signaling thread but used by WebRTC's
   // worker thread |task_runner|.
-  CONTENT_EXPORT FilteringNetworkManager(
+  BLINK_PLATFORM_EXPORT FilteringNetworkManager(
       rtc::NetworkManager* network_manager,
       const GURL& requesting_origin,
       media::MediaPermission* media_permission);
 
-  CONTENT_EXPORT ~FilteringNetworkManager() override;
+  BLINK_PLATFORM_EXPORT ~FilteringNetworkManager() override;
 
   // rtc::NetworkManager:
   void Initialize() override;
@@ -88,7 +91,7 @@
   rtc::NetworkManager* network_manager_;
 
   // The class is created by the signaling thread but used by the worker thread.
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   media::MediaPermission* media_permission_;
 
@@ -120,6 +123,6 @@
   DISALLOW_COPY_AND_ASSIGN(FilteringNetworkManager);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_FILTERING_NETWORK_MANAGER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_FILTERING_NETWORK_MANAGER_H_
diff --git a/content/renderer/p2p/ipc_network_manager.h b/third_party/blink/public/platform/modules/p2p/ipc_network_manager.h
similarity index 64%
rename from content/renderer/p2p/ipc_network_manager.h
rename to third_party/blink/public/platform/modules/p2p/ipc_network_manager.h
index d0d3b0b..d70b628 100644
--- a/content/renderer/p2p/ipc_network_manager.h
+++ b/third_party/blink/public/platform/modules/p2p/ipc_network_manager.h
@@ -2,17 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_P2P_IPC_NETWORK_MANAGER_H_
-#define CONTENT_RENDERER_P2P_IPC_NETWORK_MANAGER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_IPC_NETWORK_MANAGER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_IPC_NETWORK_MANAGER_H_
 
 #include <memory>
-#include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "content/renderer/p2p/network_list_manager.h"
-#include "content/renderer/p2p/network_list_observer.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_observer.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/webrtc/rtc_base/mdns_responder_interface.h"
 #include "third_party/webrtc/rtc_base/network.h"
 
@@ -20,16 +18,16 @@
 class IPAddress;
 }  // namespace net
 
-namespace content {
+namespace blink {
 
 // IpcNetworkManager is a NetworkManager for libjingle that gets a
 // list of network interfaces from the browser.
 class IpcNetworkManager : public rtc::NetworkManagerBase,
-                          public NetworkListObserver {
+                          public blink::NetworkListObserver {
  public:
   // Constructor doesn't take ownership of the |network_list_manager|.
-  CONTENT_EXPORT IpcNetworkManager(
-      NetworkListManager* network_list_manager,
+  BLINK_PLATFORM_EXPORT IpcNetworkManager(
+      blink::NetworkListManager* network_list_manager,
       std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder);
   ~IpcNetworkManager() override;
 
@@ -38,7 +36,7 @@
   void StopUpdating() override;
   webrtc::MdnsResponderInterface* GetMdnsResponder() const override;
 
-  // P2PSocketDispatcher::NetworkListObserver interface.
+  // blink::NetworkListObserver interface.
   void OnNetworkListChanged(
       const net::NetworkInterfaceList& list,
       const net::IPAddress& default_ipv4_local_address,
@@ -47,7 +45,7 @@
  private:
   void SendNetworksChangedSignal();
 
-  NetworkListManager* network_list_manager_;
+  blink::NetworkListManager* network_list_manager_;
   std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder_;
   int start_count_ = 0;
   bool network_list_received_ = false;
@@ -55,6 +53,6 @@
   base::WeakPtrFactory<IpcNetworkManager> weak_factory_{this};
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_IPC_NETWORK_MANAGER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_IPC_NETWORK_MANAGER_H_
diff --git a/content/renderer/p2p/network_list_manager.h b/third_party/blink/public/platform/modules/p2p/network_list_manager.h
similarity index 68%
rename from content/renderer/p2p/network_list_manager.h
rename to third_party/blink/public/platform/modules/p2p/network_list_manager.h
index c0e0f58b..0928325 100644
--- a/content/renderer/p2p/network_list_manager.h
+++ b/third_party/blink/public/platform/modules/p2p/network_list_manager.h
@@ -6,14 +6,18 @@
 // IpcNetworkManager such that it doesn't depend on implementation of
 // P2PSocketDispatcher.
 
-#ifndef CONTENT_RENDERER_P2P_NETWORK_LIST_MANAGER_H_
-#define CONTENT_RENDERER_P2P_NETWORK_LIST_MANAGER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_MANAGER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_MANAGER_H_
 
-namespace content {
+#include "third_party/blink/public/platform/web_common.h"
+
+namespace blink {
 
 class NetworkListObserver;
 
-class CONTENT_EXPORT NetworkListManager {
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped.
+class BLINK_PLATFORM_EXPORT NetworkListManager {
  public:
   // Add a new network list observer. Each observer is called
   // immidiately after it is registered and then later whenever
@@ -33,6 +37,6 @@
   virtual ~NetworkListManager() {}
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_NETWORK_LIST_MANAGER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_MANAGER_H_
diff --git a/third_party/blink/public/platform/modules/p2p/network_list_observer.h b/third_party/blink/public/platform/modules/p2p/network_list_observer.h
new file mode 100644
index 0000000..8c80fbd
--- /dev/null
+++ b/third_party/blink/public/platform/modules/p2p/network_list_observer.h
@@ -0,0 +1,35 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_OBSERVER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_OBSERVER_H_
+
+#include <vector>
+
+namespace net {
+class IPAddress;
+struct NetworkInterface;
+typedef std::vector<NetworkInterface> NetworkInterfaceList;
+}  // namespace net
+
+namespace blink {
+
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also, move it away from std::vector.
+class NetworkListObserver {
+ public:
+  virtual ~NetworkListObserver() {}
+
+  virtual void OnNetworkListChanged(
+      const net::NetworkInterfaceList& list,
+      const net::IPAddress& default_ipv4_local_address,
+      const net::IPAddress& default_ipv6_local_address) = 0;
+
+ protected:
+  NetworkListObserver() {}
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_NETWORK_LIST_OBSERVER_H_
diff --git a/content/renderer/p2p/socket_client.h b/third_party/blink/public/platform/modules/p2p/socket_client.h
similarity index 72%
rename from content/renderer/p2p/socket_client.h
rename to third_party/blink/public/platform/modules/p2p/socket_client.h
index 694d10e..6d7fe7a 100644
--- a/content/renderer/p2p/socket_client.h
+++ b/third_party/blink/public/platform/modules/p2p/socket_client.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_P2P_SOCKET_CLIENT_H_
-#define CONTENT_RENDERER_P2P_SOCKET_CLIENT_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_H_
 
 #include <stdint.h>
 
@@ -16,11 +16,14 @@
 struct PacketOptions;
 }
 
-namespace content {
+namespace blink {
 
 class P2PSocketClientDelegate;
 
 // P2P socket that routes all calls over IPC.
+//
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also, move it away from std::vector.
 class P2PSocketClient {
  public:
   virtual ~P2PSocketClient() {}
@@ -42,6 +45,6 @@
  protected:
   P2PSocketClient() {}
 };
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_SOCKET_CLIENT_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_H_
diff --git a/content/renderer/p2p/socket_client_delegate.h b/third_party/blink/public/platform/modules/p2p/socket_client_delegate.h
similarity index 74%
rename from content/renderer/p2p/socket_client_delegate.h
rename to third_party/blink/public/platform/modules/p2p/socket_client_delegate.h
index 680e6f2f..e9eaf28d 100644
--- a/content/renderer/p2p/socket_client_delegate.h
+++ b/third_party/blink/public/platform/modules/p2p/socket_client_delegate.h
@@ -2,21 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_P2P_SOCKET_CLIENT_DELEGATE_H_
-#define CONTENT_RENDERER_P2P_SOCKET_CLIENT_DELEGATE_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_DELEGATE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_DELEGATE_H_
 
 #include <vector>
 
 #include "net/base/ip_endpoint.h"
 #include "services/network/public/cpp/p2p_socket_type.h"
 
-namespace content {
+namespace blink {
 
 class P2PSocketClient;
 
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also, move it away from std::vector.
 class P2PSocketClientDelegate {
  public:
-  virtual ~P2PSocketClientDelegate() { }
+  virtual ~P2PSocketClientDelegate() {}
 
   // Called after the socket has been opened with the local endpoint address
   // as argument. Please note that in the precence of multiple interfaces,
@@ -43,6 +45,6 @@
                               const base::TimeTicks& timestamp) = 0;
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_P2P_SOCKET_CLIENT_DELEGATE_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_P2P_SOCKET_CLIENT_DELEGATE_H_
diff --git a/third_party/blink/public/platform/modules/peerconnection/DEPS b/third_party/blink/public/platform/modules/peerconnection/DEPS
index 68362d4..b9fba478 100644
--- a/third_party/blink/public/platform/modules/peerconnection/DEPS
+++ b/third_party/blink/public/platform/modules/peerconnection/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+    "+base/timer/timer.h",
     "+media/base/audio_parameters.h",
     "+media/base/audio_push_fifo.h",
     "+media/base/video_codecs.h",
diff --git a/content/renderer/media/webrtc/stun_field_trial.h b/third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h
similarity index 72%
rename from content/renderer/media/webrtc/stun_field_trial.h
rename to third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h
index 81b7419..45953c03 100644
--- a/content/renderer/media/webrtc/stun_field_trial.h
+++ b/third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h
@@ -2,20 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_STUN_FIELD_TRIAL_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_STUN_FIELD_TRIAL_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_PEERCONNECTION_STUN_FIELD_TRIAL_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_PEERCONNECTION_STUN_FIELD_TRIAL_H_
 
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "base/timer/timer.h"
-#include "content/common/content_export.h"
-#include "content/renderer/p2p/network_list_manager.h"
-#include "content/renderer/p2p/network_list_observer.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_observer.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/webrtc/p2p/stunprober/stun_prober.h"
 #include "third_party/webrtc/rtc_base/network.h"
 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
@@ -25,7 +24,7 @@
 class SocketAddress;
 }  // namespace rtc
 
-namespace content {
+namespace blink {
 
 // Wait for 30 seconds to avoid high CPU usage during browser start-up which
 // might affect the accuracy of the trial. The trial wakes up the browser every
@@ -33,10 +32,13 @@
 // stun probe.
 static const int kExperimentStartDelayMs = 30000;
 
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// all users of it have been Onion souped. Also migrate away from std::vector
+// and std::string.
 class StunProberTrial : public stunprober::StunProber::Observer,
                         public sigslot::has_slots<> {
  public:
-  struct CONTENT_EXPORT Param {
+  struct BLINK_PLATFORM_EXPORT Param {
     Param();
     ~Param();
     int requests_per_ip = 0;
@@ -47,9 +49,9 @@
     std::vector<rtc::SocketAddress> servers;
   };
 
-  StunProberTrial(rtc::NetworkManager* network_manager,
-                  const std::string& params,
-                  rtc::PacketSocketFactory* factory);
+  BLINK_PLATFORM_EXPORT StunProberTrial(rtc::NetworkManager* network_manager,
+                                        const std::string& params,
+                                        rtc::PacketSocketFactory* factory);
   ~StunProberTrial() override;
 
  private:
@@ -59,8 +61,9 @@
   void OnNetworksChanged();
 
   // Parsing function to decode the '/' separated parameter string |params|.
-  static CONTENT_EXPORT bool ParseParameters(const std::string& param_line,
-                                             Param* params);
+  static BLINK_PLATFORM_EXPORT bool ParseParameters(
+      const std::string& param_line,
+      Param* params);
 
   // stunprober::StunProber::Observer:
   void OnPrepared(stunprober::StunProber* prober,
@@ -85,7 +88,7 @@
   int started_probers_ = 0;
   int finished_probers_ = 0;
   std::vector<stunprober::StunProber*> probers_;
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // The reason we use a timer instead of depending on the OnFinished callback
   // of each prober is that the OnFinished is not fired at the last of STUN
@@ -98,6 +101,6 @@
   DISALLOW_COPY_AND_ASSIGN(StunProberTrial);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_STUN_FIELD_TRIAL_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_PEERCONNECTION_STUN_FIELD_TRIAL_H_
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 10eab39..1a08bba 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -656,6 +656,8 @@
 
   virtual bool IsWebRtcHWDecodingEnabled() { return true; }
 
+  virtual bool AllowsLoopbackInPeerConnection() { return false; }
+
   // VideoCapture -------------------------------------------------------
 
   virtual WebVideoCaptureImplManager* GetVideoCaptureImplManager() {
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 8f62613..47a2e2f 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -521,11 +521,8 @@
   // Tells the embedder to navigate back or forward in session history by
   // the given offset (relative to the current position in session
   // history). |has_user_gesture| tells whether or not this is the consequence
-  // of a user action. |from_script| tells whether the action was initiated from
-  // the execution of a script.
-  virtual void NavigateBackForwardSoon(int offset,
-                                       bool has_user_gesture,
-                                       bool from_script) {}
+  // of a user action.
+  virtual void NavigateBackForwardSoon(int offset, bool has_user_gesture) {}
 
   // Returns token to be used as a frame id in the devtools protocol.
   // It is derived from the content's devtools_frame_token, is
diff --git a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
index 48ccf85..4975513 100644
--- a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
+++ b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
@@ -68,7 +68,7 @@
 //
 // The trace format is described at:
 // https://wicg.github.io/js-self-profiling/#the-profilertrace-dictionary
-class ProfilerTraceBuilder
+class ProfilerTraceBuilder final
     : public GarbageCollectedFinalized<ProfilerTraceBuilder> {
  public:
   static ProfilerTrace* FromProfile(ScriptState*,
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
index 6d93d2fe..da59492f 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
@@ -35,7 +35,7 @@
 // but (for security reasons) separate JavaScript wrappers must exist. For this
 // reason, a SerializedScriptValue can only be unpacked once, but thereafter it
 // can be deserialized multiple times.
-class CORE_EXPORT UnpackedSerializedScriptValue
+class CORE_EXPORT UnpackedSerializedScriptValue final
     : public GarbageCollectedFinalized<UnpackedSerializedScriptValue> {
  public:
   // Callers should use SerializedScriptValue::Unpack.
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
index 0b632ab8..9c9142d 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -324,6 +324,7 @@
     {% endcall %}
 
     {% call(property) apply_inherit(property) %}
+  state.Style()->Clear{{action}}Directives();
   const CounterDirectiveMap* parent_map = state.ParentStyle()->GetCounterDirectives();
   if (!parent_map)
     return;
diff --git a/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl b/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
index 19a4466..9eadaec6d 100644
--- a/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
@@ -23,7 +23,7 @@
 class {{ agent | agent_name_to_class }};
 {% endfor %}
 
-class {{export_symbol}} {{sink_class}} : public GarbageCollectedFinalized<{{sink_class}}> {
+class {{export_symbol}} {{sink_class}} final : public GarbageCollectedFinalized<{{sink_class}}> {
 
  public:
   enum AgentType : unsigned {
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h
index f859710..d56997d 100644
--- a/third_party/blink/renderer/core/animation/animation.h
+++ b/third_party/blink/renderer/core/animation/animation.h
@@ -421,7 +421,7 @@
   // CompositorAnimation objects need to eagerly sever their connection to their
   // Animation delegate; use a separate 'holder' on-heap object to accomplish
   // that.
-  class CompositorAnimationHolder
+  class CompositorAnimationHolder final
       : public GarbageCollectedFinalized<CompositorAnimationHolder> {
     USING_PRE_FINALIZER(CompositorAnimationHolder, Dispose);
 
diff --git a/third_party/blink/renderer/core/animation/element_animations.h b/third_party/blink/renderer/core/animation/element_animations.h
index 4a69003..8a1fe6d 100644
--- a/third_party/blink/renderer/core/animation/element_animations.h
+++ b/third_party/blink/renderer/core/animation/element_animations.h
@@ -46,7 +46,7 @@
 using AnimationCountedSet = HeapHashCountedSet<WeakMember<Animation>>;
 using WorkletAnimationSet = HeapHashSet<WeakMember<WorkletAnimationBase>>;
 
-class CORE_EXPORT ElementAnimations
+class CORE_EXPORT ElementAnimations final
     : public GarbageCollectedFinalized<ElementAnimations> {
  public:
   ElementAnimations();
diff --git a/third_party/blink/renderer/core/animation/interpolation_effect.h b/third_party/blink/renderer/core/animation/interpolation_effect.h
index b8d5dfe..8fd8c6d 100644
--- a/third_party/blink/renderer/core/animation/interpolation_effect.h
+++ b/third_party/blink/renderer/core/animation/interpolation_effect.h
@@ -52,7 +52,7 @@
   void Trace(Visitor*);
 
  private:
-  class InterpolationRecord
+  class InterpolationRecord final
       : public GarbageCollectedFinalized<InterpolationRecord> {
    public:
     InterpolationRecord(Interpolation* interpolation,
diff --git a/third_party/blink/renderer/core/animation/sampled_effect.h b/third_party/blink/renderer/core/animation/sampled_effect.h
index b35a695..01aade7e 100644
--- a/third_party/blink/renderer/core/animation/sampled_effect.h
+++ b/third_party/blink/renderer/core/animation/sampled_effect.h
@@ -16,7 +16,7 @@
 
 // Associates the results of sampling an EffectModel with metadata used for
 // effect ordering and managing composited animations.
-class SampledEffect : public GarbageCollectedFinalized<SampledEffect> {
+class SampledEffect final : public GarbageCollectedFinalized<SampledEffect> {
  public:
   SampledEffect(KeyframeEffect*, unsigned sequence_number);
 
diff --git a/third_party/blink/renderer/core/clipboard/data_object_item.h b/third_party/blink/renderer/core/clipboard/data_object_item.h
index 82a11c42..a057b4833 100644
--- a/third_party/blink/renderer/core/clipboard/data_object_item.h
+++ b/third_party/blink/renderer/core/clipboard/data_object_item.h
@@ -40,7 +40,7 @@
 
 namespace blink {
 
-class CORE_EXPORT DataObjectItem
+class CORE_EXPORT DataObjectItem final
     : public GarbageCollectedFinalized<DataObjectItem> {
  public:
   enum ItemKind { kStringKind, kFileKind };
diff --git a/third_party/blink/renderer/core/content_capture/sent_nodes.h b/third_party/blink/renderer/core/content_capture/sent_nodes.h
index 194b29a8..8ef40844 100644
--- a/third_party/blink/renderer/core/content_capture/sent_nodes.h
+++ b/third_party/blink/renderer/core/content_capture/sent_nodes.h
@@ -15,7 +15,7 @@
 
 // The class manages a list of nodes that have been sent, is only used when
 // kNodeID is used, see WebContentCaptureClient::GetNodeType().
-class SentNodes : public GarbageCollectedFinalized<SentNodes> {
+class SentNodes final : public GarbageCollectedFinalized<SentNodes> {
  public:
   bool HasSent(const Node& node);
   void OnSent(const Node& node);
diff --git a/third_party/blink/renderer/core/content_capture/task_session.h b/third_party/blink/renderer/core/content_capture/task_session.h
index e648a52f..a7c2892e 100644
--- a/third_party/blink/renderer/core/content_capture/task_session.h
+++ b/third_party/blink/renderer/core/content_capture/task_session.h
@@ -37,13 +37,14 @@
 // ContentCaptureTask gets the data per document by using
 // GetUnsentDocumentSession() and GetNextUnsentNode(), and must send
 // all data out before capturing on-screen content again.
-class TaskSession : public GarbageCollectedFinalized<TaskSession> {
+class TaskSession final : public GarbageCollectedFinalized<TaskSession> {
  public:
   // This class manages the captured content and the detached nodes per
   // document, the data is moved to the ContentCaptureTask while required. This
   // class has an instance per document, will be released while the associated
   // document is GC-ed, see TaskSession::to_document_session_.
-  class DocumentSession : public GarbageCollectedFinalized<DocumentSession> {
+  class DocumentSession final
+      : public GarbageCollectedFinalized<DocumentSession> {
    public:
     // The callback for total_sent_nodes_ metrics.
     using SentNodeCountCallback = base::RepeatingCallback<void(size_t)>;
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
index d595fe5..ad9a447 100644
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -197,6 +197,7 @@
                     "frame/report_body.idl",
                     "frame/reporting_observer.idl",
                     "frame/scheduling.idl",
+                    "frame/selector.idl",
                     "frame/test_report_body.idl",
                     "frame/user_activation.idl",
                     "frame/visual_viewport.idl",
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn
index 3974064..5372cf79 100644
--- a/third_party/blink/renderer/core/css/BUILD.gn
+++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -106,6 +106,8 @@
     "css_keyframes_rule.h",
     "css_layout_function_value.cc",
     "css_layout_function_value.h",
+    "css_light_dark_color_pair.cc",
+    "css_light_dark_color_pair.h",
     "css_markup.cc",
     "css_markup.h",
     "css_math_expression_node.cc",
@@ -590,6 +592,7 @@
     "css_font_face_source_test.cc",
     "css_gradient_value_test.cc",
     "css_invalid_variable_value_test.cc",
+    "css_light_dark_color_pair_test.cc",
     "css_math_expression_node_test.cc",
     "css_page_rule_test.cc",
     "css_paint_value_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.h b/third_party/blink/renderer/core/css/css_default_style_sheets.h
index a8a705d..8ad6b8a 100644
--- a/third_party/blink/renderer/core/css/css_default_style_sheets.h
+++ b/third_party/blink/renderer/core/css/css_default_style_sheets.h
@@ -36,9 +36,8 @@
 class RuleSet;
 class StyleSheetContents;
 
-class CSSDefaultStyleSheets
+class CSSDefaultStyleSheets final
     : public GarbageCollectedFinalized<CSSDefaultStyleSheets> {
-
  public:
   CORE_EXPORT static CSSDefaultStyleSheets& Instance();
 
diff --git a/third_party/blink/renderer/core/css/css_global_rule_set.h b/third_party/blink/renderer/core/css/css_global_rule_set.h
index 0fb3a072..2e6bf7b 100644
--- a/third_party/blink/renderer/core/css/css_global_rule_set.h
+++ b/third_party/blink/renderer/core/css/css_global_rule_set.h
@@ -22,7 +22,8 @@
 // possible to the ScopedStyleResolver as possible to avoid full reconstruction
 // of these rulesets on shadow tree changes. See https://crbug.com/401359
 
-class CSSGlobalRuleSet : public GarbageCollectedFinalized<CSSGlobalRuleSet> {
+class CSSGlobalRuleSet final
+    : public GarbageCollectedFinalized<CSSGlobalRuleSet> {
  public:
   CSSGlobalRuleSet() = default;
 
diff --git a/third_party/blink/renderer/core/css/css_light_dark_color_pair.cc b/third_party/blink/renderer/core/css/css_light_dark_color_pair.cc
new file mode 100644
index 0000000..201654e4
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_light_dark_color_pair.cc
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_light_dark_color_pair.h"
+
+namespace blink {
+
+String CSSLightDarkColorPair::CustomCSSText() const {
+  String first = First().CssText();
+  String second = Second().CssText();
+  return "-internal-light-dark-color(" + first + ", " + second + ")";
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_light_dark_color_pair.h b/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
new file mode 100644
index 0000000..84737f5
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_LIGHT_DARK_COLOR_PAIR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_LIGHT_DARK_COLOR_PAIR_H_
+
+#include "third_party/blink/renderer/core/css/css_value_pair.h"
+
+namespace blink {
+
+class CORE_EXPORT CSSLightDarkColorPair : public CSSValuePair {
+ public:
+  CSSLightDarkColorPair(const CSSValue* first, const CSSValue* second)
+      : CSSValuePair(kLightDarkColorPairClass, first, second) {}
+  String CustomCSSText() const;
+  void TraceAfterDispatch(blink::Visitor* visitor) {
+    CSSValuePair::TraceAfterDispatch(visitor);
+  }
+};
+
+template <>
+struct DowncastTraits<CSSLightDarkColorPair> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsLightDarkColorPair();
+  }
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_LIGHT_DARK_COLOR_PAIR_H_
diff --git a/third_party/blink/renderer/core/css/css_light_dark_color_pair_test.cc b/third_party/blink/renderer/core/css/css_light_dark_color_pair_test.cc
new file mode 100644
index 0000000..e3523d7
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_light_dark_color_pair_test.cc
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_light_dark_color_pair.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser.h"
+
+namespace blink {
+
+namespace {
+
+const CSSValue* CreateLightDarkColorPair(const char* value) {
+  auto* ua_context = MakeGarbageCollected<CSSParserContext>(
+      kUASheetMode, SecureContextMode::kInsecureContext);
+  return CSSParser::ParseSingleValue(CSSPropertyID::kColor, value, ua_context);
+}
+
+TEST(CSSLightDarkColorPairTest, Equals) {
+  const auto* value1 =
+      CreateLightDarkColorPair("-internal-light-dark-color(red, green)");
+  const auto* value2 =
+      CreateLightDarkColorPair("-internal-light-dark-color(red, green)");
+  const auto* value3 =
+      CreateLightDarkColorPair("-internal-light-dark-color(#000, #fff)");
+  const auto* value4 = CreateLightDarkColorPair(
+      "-internal-light-dark-color(rgb(0, 0, 0), rgb(255, 255, 255))");
+  ASSERT_TRUE(value1);
+  ASSERT_TRUE(value2);
+  ASSERT_TRUE(value3);
+  ASSERT_TRUE(value4);
+  EXPECT_TRUE(*value1 == *value1);
+  EXPECT_TRUE(*value1 == *value2);
+  EXPECT_TRUE(*value3 == *value3);
+  EXPECT_TRUE(*value4 == *value4);
+  EXPECT_TRUE(*value3 == *value4);
+}
+
+}  // namespace
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_property_source_data.h b/third_party/blink/renderer/core/css/css_property_source_data.h
index fb283eb8..1e087063 100644
--- a/third_party/blink/renderer/core/css/css_property_source_data.h
+++ b/third_party/blink/renderer/core/css/css_property_source_data.h
@@ -83,7 +83,8 @@
 
 namespace blink {
 
-class CSSRuleSourceData : public GarbageCollectedFinalized<CSSRuleSourceData> {
+class CSSRuleSourceData final
+    : public GarbageCollectedFinalized<CSSRuleSourceData> {
  public:
   explicit CSSRuleSourceData(StyleRule::RuleType type) : type(type) {}
   void Trace(blink::Visitor* visitor) { visitor->Trace(child_rules); }
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index 50ae3d7..4cc574c 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -652,7 +652,7 @@
 }
 
 // See the function above if you need to update this.
-struct SameSizeAsCSSPropertyValueSet
+struct SameSizeAsCSSPropertyValueSet final
     : public GarbageCollectedFinalized<SameSizeAsCSSPropertyValueSet> {
   unsigned bitfield;
 };
diff --git a/third_party/blink/renderer/core/css/css_value.cc b/third_party/blink/renderer/core/css/css_value.cc
index 1c0a54ad..5b546d21 100644
--- a/third_party/blink/renderer/core/css/css_value.cc
+++ b/third_party/blink/renderer/core/css/css_value.cc
@@ -55,6 +55,7 @@
 #include "third_party/blink/renderer/core/css/css_invalid_variable_value.h"
 #include "third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h"
 #include "third_party/blink/renderer/core/css/css_layout_function_value.h"
+#include "third_party/blink/renderer/core/css/css_light_dark_color_pair.h"
 #include "third_party/blink/renderer/core/css/css_math_function_value.h"
 #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
 #include "third_party/blink/renderer/core/css/css_paint_value.h"
@@ -81,7 +82,7 @@
 
 using namespace cssvalue;
 
-struct SameSizeAsCSSValue
+struct SameSizeAsCSSValue final
     : public GarbageCollectedFinalized<SameSizeAsCSSValue> {
   uint32_t bitfields;
 };
@@ -263,6 +264,8 @@
         return CompareCSSValues<CSSPendingSubstitutionValue>(*this, other);
       case kInvalidVariableValueClass:
         return CompareCSSValues<CSSInvalidVariableValue>(*this, other);
+      case kLightDarkColorPairClass:
+        return CompareCSSValues<CSSLightDarkColorPair>(*this, other);
     }
     NOTREACHED();
     return false;
@@ -378,6 +381,8 @@
       return To<CSSPendingSubstitutionValue>(this)->CustomCSSText();
     case kInvalidVariableValueClass:
       return To<CSSInvalidVariableValue>(this)->CustomCSSText();
+    case kLightDarkColorPairClass:
+      return To<CSSLightDarkColorPair>(this)->CustomCSSText();
   }
   NOTREACHED();
   return String();
@@ -545,6 +550,9 @@
     case kInvalidVariableValueClass:
       To<CSSInvalidVariableValue>(this)->~CSSInvalidVariableValue();
       return;
+    case kLightDarkColorPairClass:
+      To<CSSLightDarkColorPair>(this)->~CSSLightDarkColorPair();
+      return;
   }
   NOTREACHED();
 }
@@ -710,6 +718,9 @@
     case kInvalidVariableValueClass:
       To<CSSInvalidVariableValue>(this)->TraceAfterDispatch(visitor);
       return;
+    case kLightDarkColorPairClass:
+      To<CSSLightDarkColorPair>(this)->TraceAfterDispatch(visitor);
+      return;
   }
   NOTREACHED();
 }
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h
index 0673a4a3..debf1fba 100644
--- a/third_party/blink/renderer/core/css/css_value.h
+++ b/third_party/blink/renderer/core/css/css_value.h
@@ -171,6 +171,9 @@
   bool IsShorthandWrapperValue() const {
     return class_type_ == kKeyframeShorthandClass;
   }
+  bool IsLightDarkColorPair() const {
+    return class_type_ == kLightDarkColorPairClass;
+  }
 
   bool HasFailedOrCanceledSubresources() const;
   bool MayContainUrl() const;
@@ -201,6 +204,7 @@
     kStringClass,
     kURIClass,
     kValuePairClass,
+    kLightDarkColorPairClass,
 
     // Basic shape classes.
     // TODO(sashab): Represent these as a single subclass, BasicShapeClass.
diff --git a/third_party/blink/renderer/core/css/css_value_pair.h b/third_party/blink/renderer/core/css/css_value_pair.h
index d36680d..2cd6b476 100644
--- a/third_party/blink/renderer/core/css/css_value_pair.h
+++ b/third_party/blink/renderer/core/css/css_value_pair.h
@@ -66,6 +66,18 @@
 
   void TraceAfterDispatch(blink::Visitor*);
 
+ protected:
+  CSSValuePair(ClassType class_type,
+               const CSSValue* first,
+               const CSSValue* second)
+      : CSSValue(class_type),
+        first_(first),
+        second_(second),
+        identical_values_policy_(kKeepIdenticalValues) {
+    DCHECK(first_);
+    DCHECK(second_);
+  }
+
  private:
   Member<const CSSValue> first_;
   Member<const CSSValue> second_;
diff --git a/third_party/blink/renderer/core/css/css_value_pool.h b/third_party/blink/renderer/core/css/css_value_pool.h
index ce42ae5e..b24ea1c 100644
--- a/third_party/blink/renderer/core/css/css_value_pool.h
+++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -48,9 +48,8 @@
 
 namespace blink {
 
-class CORE_EXPORT CSSValuePool
+class CORE_EXPORT CSSValuePool final
     : public GarbageCollectedFinalized<CSSValuePool> {
-
  public:
   using PassKey = util::PassKey<CSSValuePool>;
 
diff --git a/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h b/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
index 6b7ad89..77ecf76 100644
--- a/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
+++ b/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
@@ -21,7 +21,7 @@
 // Currently, the only strong references to this class are from individual lazy
 // properties, so after an entire lazy sheet is parsed, the extra memory should
 // be released.
-class CSSLazyParsingState
+class CSSLazyParsingState final
     : public GarbageCollectedFinalized<CSSLazyParsingState> {
  public:
   CSSLazyParsingState(const CSSParserContext*,
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.h b/third_party/blink/renderer/core/css/parser/css_parser_context.h
index c7435d833..82ccd8f7 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_context.h
+++ b/third_party/blink/renderer/core/css/parser/css_parser_context.h
@@ -23,7 +23,7 @@
 class StyleRuleKeyframe;
 class StyleSheetContents;
 
-class CORE_EXPORT CSSParserContext
+class CORE_EXPORT CSSParserContext final
     : public GarbageCollectedFinalized<CSSParserContext> {
  public:
   // https://drafts.csswg.org/selectors/#profiles
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
index eec141a0..39790d61 100644
--- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
+++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/css/css_image_set_value.h"
 #include "third_party/blink/renderer/core/css/css_image_value.h"
 #include "third_party/blink/renderer/core/css/css_initial_value.h"
+#include "third_party/blink/renderer/core/css/css_light_dark_color_pair.h"
 #include "third_party/blink/renderer/core/css/css_math_expression_node.h"
 #include "third_party/blink/renderer/core/css/css_math_function_value.h"
 #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
@@ -859,8 +860,8 @@
   return true;
 }
 
-static CSSValuePair* ParseLightDarkColor(CSSParserTokenRange& range,
-                                         CSSParserMode mode) {
+static CSSLightDarkColorPair* ParseLightDarkColor(CSSParserTokenRange& range,
+                                                  CSSParserMode mode) {
   if (range.Peek().FunctionId() != CSSValueID::kInternalLightDarkColor)
     return nullptr;
   if (!isValueAllowedInMode(CSSValueID::kInternalLightDarkColor, mode))
@@ -872,8 +873,7 @@
   CSSValue* dark_color = ConsumeColor(args, kUASheetMode);
   if (!dark_color || !args.AtEnd())
     return nullptr;
-  return MakeGarbageCollected<CSSValuePair>(light_color, dark_color,
-                                            CSSValuePair::kKeepIdenticalValues);
+  return MakeGarbageCollected<CSSLightDarkColorPair>(light_color, dark_color);
 }
 
 CSSValue* ConsumeColor(CSSParserTokenRange& range,
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
index 011f495..83e6028 100644
--- a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
+++ b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
@@ -714,4 +714,15 @@
   }
 }
 
+TEST(CSSPropertyParserTest, UAInternalLightDarkColorSerialization) {
+  auto* ua_context = MakeGarbageCollected<CSSParserContext>(
+      kUASheetMode, SecureContextMode::kInsecureContext);
+  const CSSValue* value = CSSParser::ParseSingleValue(
+      CSSPropertyID::kColor, "-internal-light-dark-color(red,#aaa)",
+      ua_context);
+  ASSERT_TRUE(value);
+  EXPECT_EQ("-internal-light-dark-color(red, rgb(170, 170, 170))",
+            value->CssText());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/property_registration.h b/third_party/blink/renderer/core/css/property_registration.h
index 25eed14e..55f4504 100644
--- a/third_party/blink/renderer/core/css/property_registration.h
+++ b/third_party/blink/renderer/core/css/property_registration.h
@@ -23,7 +23,7 @@
 
 using CSSInterpolationTypes = Vector<std::unique_ptr<CSSInterpolationType>>;
 
-class CORE_EXPORT PropertyRegistration
+class CORE_EXPORT PropertyRegistration final
     : public GarbageCollectedFinalized<PropertyRegistration> {
  public:
   static PropertyRegistration* MaybeCreate(Document&,
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h
index f404dfc..b46f6a9 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -323,6 +323,8 @@
   bool print_media_type_ = false;
   bool was_viewport_resized_ = false;
   DISALLOW_COPY_AND_ASSIGN(StyleResolver);
+
+  FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, ApplyInternalLightDarkColor);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
index db90ffd..3f976db 100644
--- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
@@ -44,7 +44,7 @@
 class MutableCSSPropertyValueSet;
 class StyleRuleViewport;
 
-class CORE_EXPORT ViewportStyleResolver
+class CORE_EXPORT ViewportStyleResolver final
     : public GarbageCollectedFinalized<ViewportStyleResolver> {
  public:
   explicit ViewportStyleResolver(Document&);
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 6776c98ac..0ea9ef2 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -175,7 +175,7 @@
 // specific group are appended to the "universal" rules. The grouping is done to
 // optimize finding what rules apply to an element under consideration by
 // ElementRuleCollector::CollectMatchingRules.
-class CORE_EXPORT RuleSet : public GarbageCollectedFinalized<RuleSet> {
+class CORE_EXPORT RuleSet final : public GarbageCollectedFinalized<RuleSet> {
  public:
   RuleSet() : rule_count_(0) {}
 
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc
index fc4f780..e5f576a 100644
--- a/third_party/blink/renderer/core/css/style_rule.cc
+++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -40,7 +40,7 @@
 
 namespace blink {
 
-struct SameSizeAsStyleRuleBase
+struct SameSizeAsStyleRuleBase final
     : public GarbageCollectedFinalized<SameSizeAsStyleRuleBase> {
   unsigned bitfields;
 };
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.h b/third_party/blink/renderer/core/css/style_sheet_contents.h
index 80e49b2..bad98c2c 100644
--- a/third_party/blink/renderer/core/css/style_sheet_contents.h
+++ b/third_party/blink/renderer/core/css/style_sheet_contents.h
@@ -47,7 +47,7 @@
 class StyleRuleNamespace;
 enum class ParseSheetResult;
 
-class CORE_EXPORT StyleSheetContents
+class CORE_EXPORT StyleSheetContents final
     : public GarbageCollectedFinalized<StyleSheetContents> {
  public:
   static const Document* SingleOwnerDocument(const StyleSheetContents*);
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 2575d4d..d841eec1 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -297,7 +297,6 @@
 #include "third_party/blink/renderer/platform/language.h"
 #include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h"
 #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
 #include "third_party/blink/renderer/platform/network/network_state_notifier.h"
@@ -327,45 +326,6 @@
 
 namespace blink {
 
-namespace {
-
-class ResourceLoadObserverForUnintentionalRequestsMadeByImportedDocument final
-    : public ResourceLoadObserver {
-  void DidStartRequest(const FetchParameters&, ResourceType type) override {
-    UMA_HISTOGRAM_ENUMERATION("HTMLImport.UnexpectedRequest", type);
-  }
-  void WillSendRequest(uint64_t identifier,
-                       const ResourceRequest&,
-                       const ResourceResponse& redirect_response,
-                       ResourceType,
-                       const FetchInitiatorInfo&) override {}
-  void DidChangePriority(uint64_t identifier,
-                         ResourceLoadPriority,
-                         int intra_priority_value) override {}
-  void DidReceiveResponse(uint64_t identifier,
-                          const ResourceRequest& request,
-                          const ResourceResponse& response,
-                          const Resource* resource,
-                          ResponseSource) override {}
-  void DidReceiveData(uint64_t identifier,
-                      base::span<const char> chunk) override {}
-  void DidReceiveTransferSizeUpdate(uint64_t identifier,
-                                    int transfer_size_diff) override {}
-  void DidDownloadToBlob(uint64_t identifier, BlobDataHandle*) override {}
-  void DidFinishLoading(uint64_t identifier,
-                        base::TimeTicks finish_time,
-                        int64_t encoded_data_length,
-                        int64_t decoded_body_length,
-                        bool should_report_corb_blocking) override {}
-  void DidFailLoading(const KURL&,
-                      uint64_t identifier,
-                      const ResourceError&,
-                      int64_t encoded_data_length,
-                      IsInternalRequest) override {}
-};
-
-}  // namespace
-
 using namespace html_names;
 
 class DocumentOutliveTimeReporter : public BlinkGCObserver {
@@ -1187,11 +1147,8 @@
         GetTaskRunner(TaskType::kNetworking), nullptr /* loader_factory */));
 
     if (imports_controller_) {
-      // We don't expect the fetcher to be used, so add a ResourceLoadObserver
-      // which counts such unexpected use.
-      fetcher_->SetResourceLoadObserver(
-          MakeGarbageCollected<
-              ResourceLoadObserverForUnintentionalRequestsMadeByImportedDocument>());
+      // We don't expect the fetcher to be used, so count such unexpected use.
+      fetcher_->SetShouldLogRequestAsInvalidInImportedDocument();
     }
   }
   DCHECK(fetcher_);
@@ -4239,7 +4196,9 @@
   return false;
 }
 
-void Document::DispatchUnloadEvents(DocumentLoadTiming* timing) {
+void Document::DispatchUnloadEvents(
+    SecurityOrigin* committing_origin,
+    base::Optional<Document::UnloadEventTiming>* unload_timing) {
   PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
   if (parser_)
     parser_->StopParsing();
@@ -4297,21 +4256,25 @@
 
       load_event_progress_ = kUnloadEventInProgress;
       Event& unload_event = *Event::Create(event_type_names::kUnload);
-      if (timing && timing->UnloadEventStart().is_null() &&
-          timing->UnloadEventEnd().is_null()) {
-        DCHECK(!timing->NavigationStart().is_null());
-        const base::TimeTicks unload_event_start = base::TimeTicks::Now();
-        timing->MarkUnloadEventStart(unload_event_start);
-        frame_->DomWindow()->DispatchEvent(unload_event, this);
-        const base::TimeTicks unload_event_end = base::TimeTicks::Now();
+      const base::TimeTicks unload_event_start = base::TimeTicks::Now();
+      frame_->DomWindow()->DispatchEvent(unload_event, this);
+      const base::TimeTicks unload_event_end = base::TimeTicks::Now();
+
+      if (unload_timing) {
+        // Record unload event timing when navigating cross-document.
         DEFINE_STATIC_LOCAL(
             CustomCountHistogram, unload_histogram,
             ("DocumentEventTiming.UnloadDuration", 0, 10000000, 50));
         unload_histogram.CountMicroseconds(unload_event_end -
                                            unload_event_start);
-        timing->MarkUnloadEventEnd(unload_event_end);
-      } else {
-        frame_->DomWindow()->DispatchEvent(unload_event, frame_->GetDocument());
+
+        // Fill in the unload timing if the new document origin has access to
+        // them.
+        if (committing_origin->CanRequest(Url())) {
+          auto& timing = unload_timing->emplace();
+          timing.unload_event_start = unload_event_start;
+          timing.unload_event_end = unload_event_end;
+        }
       }
     }
     load_event_progress_ = kUnloadEventHandled;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 18822db..e5d4754 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -104,7 +104,6 @@
 class DocumentFragment;
 class DocumentInit;
 class DocumentLoader;
-class DocumentLoadTiming;
 class DocumentMarkerController;
 class DocumentNameCollection;
 class DocumentOutliveTimeReporter;
@@ -657,10 +656,15 @@
                                  bool is_reload,
                                  bool& did_allow_navigation);
 
+  struct UnloadEventTiming {
+    base::TimeTicks unload_event_start;
+    base::TimeTicks unload_event_end;
+  };
   // Dispatches "pagehide", "visibilitychange" and "unload" events, if not
-  // dispatched already. Fills unload timing in the next document's load timing
-  // if present.
-  void DispatchUnloadEvents(DocumentLoadTiming*);
+  // dispatched already. Fills unload timing if present and |committing_origin|
+  // has access to the unload timing of the document.
+  void DispatchUnloadEvents(SecurityOrigin* committing_origin,
+                            base::Optional<Document::UnloadEventTiming>*);
 
   void DispatchFreezeEvent();
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 092e3715..3c936fb 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3740,6 +3740,7 @@
     return;
 
   if (AuthorShadowRoot() && AuthorShadowRoot()->delegatesFocus()) {
+    UseCounter::Count(GetDocument(), WebFeature::kDelegateFocus);
     Element* focused_element = GetDocument().FocusedElement();
     if (focused_element &&
         IsShadowIncludingInclusiveAncestorOf(*focused_element))
diff --git a/third_party/blink/renderer/core/dom/element_data.cc b/third_party/blink/renderer/core/dom/element_data.cc
index 92e725d..4317ce0 100644
--- a/third_party/blink/renderer/core/dom/element_data.cc
+++ b/third_party/blink/renderer/core/dom/element_data.cc
@@ -36,7 +36,7 @@
 
 namespace blink {
 
-struct SameSizeAsElementData
+struct SameSizeAsElementData final
     : public GarbageCollectedFinalized<SameSizeAsElementData> {
   unsigned bitfield;
   Member<void*> willbe_member;
diff --git a/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc b/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
index 102f56e..9e79ebcc 100644
--- a/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
+++ b/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
@@ -100,7 +100,7 @@
 // This is a hack for test purposes. The test below forces a GC to happen and
 // claims that there are no GC pointers on the stack. For this to be valid, the
 // tracker itself must live on the heap, not on the stack.
-struct LiveNodeListRegistryWrapper
+struct LiveNodeListRegistryWrapper final
     : public GarbageCollectedFinalized<LiveNodeListRegistryWrapper> {
   LiveNodeListRegistry registry;
   void Trace(Visitor* visitor) { visitor->Trace(registry); }
diff --git a/third_party/blink/renderer/core/dom/text_link_colors.cc b/third_party/blink/renderer/core/dom/text_link_colors.cc
index 39bceb8d..2435781 100644
--- a/third_party/blink/renderer/core/dom/text_link_colors.cc
+++ b/third_party/blink/renderer/core/dom/text_link_colors.cc
@@ -31,7 +31,7 @@
 
 #include "third_party/blink/renderer/core/css/css_color_value.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
-#include "third_party/blink/renderer/core/css/css_value_pair.h"
+#include "third_party/blink/renderer/core/css/css_light_dark_color_pair.h"
 #include "third_party/blink/renderer/core/css/style_color.h"
 #include "third_party/blink/renderer/core/layout/layout_theme.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -65,10 +65,11 @@
   if (auto* color_value = DynamicTo<CSSColorValue>(value))
     return color_value->Value();
 
-  if (auto* pair = DynamicTo<CSSValuePair>(value)) {
-    const CSSColorValue& color_value = To<CSSColorValue>(
-        WebColorScheme::kLight ? pair->First() : pair->Second());
-    return color_value.Value();
+  if (auto* pair = DynamicTo<CSSLightDarkColorPair>(value)) {
+    const CSSValue& color_value =
+        color_scheme == WebColorScheme::kLight ? pair->First() : pair->Second();
+    return ColorFromCSSValue(color_value, current_color, color_scheme,
+                             for_visited_link);
   }
 
   CSSValueID value_id = To<CSSIdentifierValue>(value).GetValueID();
diff --git a/third_party/blink/renderer/core/dom/visited_link_state.h b/third_party/blink/renderer/core/dom/visited_link_state.h
index 1f207ee..27a3d7d 100644
--- a/third_party/blink/renderer/core/dom/visited_link_state.h
+++ b/third_party/blink/renderer/core/dom/visited_link_state.h
@@ -40,7 +40,8 @@
 
 class Document;
 
-class VisitedLinkState : public GarbageCollectedFinalized<VisitedLinkState> {
+class VisitedLinkState final
+    : public GarbageCollectedFinalized<VisitedLinkState> {
  public:
   explicit VisitedLinkState(const Document&);
 
diff --git a/third_party/blink/renderer/core/editing/commands/undo_step.h b/third_party/blink/renderer/core/editing/commands/undo_step.h
index 688b3b8..a1b7577 100644
--- a/third_party/blink/renderer/core/editing/commands/undo_step.h
+++ b/third_party/blink/renderer/core/editing/commands/undo_step.h
@@ -39,7 +39,7 @@
 
 class SimpleEditCommand;
 
-class UndoStep : public GarbageCollectedFinalized<UndoStep> {
+class UndoStep final : public GarbageCollectedFinalized<UndoStep> {
  public:
   UndoStep(Document*,
            const SelectionForUndoStep& starting_selection,
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h b/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
index c1c3508..d89db9e 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
@@ -43,7 +43,7 @@
 class SpellCheckRequester;
 class WebTextCheckClient;
 
-class CORE_EXPORT SpellCheckRequest
+class CORE_EXPORT SpellCheckRequest final
     : public GarbageCollectedFinalized<SpellCheckRequest> {
  public:
   static const int kUnrequestedTextCheckingSequence = -1;
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index 3a0e018..62506531 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -668,8 +668,7 @@
     web_frame_->Client()->LoadErrorPage(reason);
 }
 
-bool LocalFrameClientImpl::NavigateBackForward(int offset,
-                                               bool from_script) const {
+bool LocalFrameClientImpl::NavigateBackForward(int offset) const {
   WebViewImpl* webview = web_frame_->ViewImpl();
   DCHECK(webview->Client());
   DCHECK(web_frame_->Client());
@@ -682,8 +681,7 @@
 
   bool has_user_gesture =
       LocalFrame::HasTransientUserActivation(web_frame_->GetFrame());
-  web_frame_->Client()->NavigateBackForwardSoon(offset, has_user_gesture,
-                                                from_script);
+  web_frame_->Client()->NavigateBackForwardSoon(offset, has_user_gesture);
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
index 1a06ac70..f243cc52 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -143,7 +143,7 @@
   void DownloadURL(const ResourceRequest&,
                    DownloadCrossOriginRedirects) override;
   void LoadErrorPage(int reason) override;
-  bool NavigateBackForward(int offset, bool from_script) const override;
+  bool NavigateBackForward(int offset) const override;
   void DidAccessInitialDocument() override;
   void DidDisplayInsecureContent() override;
   void DidContainInsecureFormAction() override;
diff --git a/third_party/blink/renderer/core/exported/web_hit_test_result.cc b/third_party/blink/renderer/core/exported/web_hit_test_result.cc
index 12f681b..3a4398d 100644
--- a/third_party/blink/renderer/core/exported/web_hit_test_result.cc
+++ b/third_party/blink/renderer/core/exported/web_hit_test_result.cc
@@ -37,7 +37,7 @@
 
 namespace blink {
 
-class WebHitTestResultPrivate
+class WebHitTestResultPrivate final
     : public GarbageCollectedFinalized<WebHitTestResultPrivate> {
  public:
   WebHitTestResultPrivate(const HitTestResult&);
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn
index 2896125..54db2cf 100644
--- a/third_party/blink/renderer/core/frame/BUILD.gn
+++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -168,6 +168,7 @@
     "screen.h",
     "screen_orientation_controller.cc",
     "screen_orientation_controller.h",
+    "selector.h",
     "settings.cc",
     "settings.h",
     "settings_delegate.cc",
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
index 3d4e153c2..a7d32a5b 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy.h
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -128,7 +128,7 @@
       const blink::WebVector<WebContentSecurityPolicy>&) = 0;
 };
 
-class CORE_EXPORT ContentSecurityPolicy
+class CORE_EXPORT ContentSecurityPolicy final
     : public GarbageCollectedFinalized<ContentSecurityPolicy> {
  public:
   enum ExceptionStatus { kWillThrowException, kWillNotThrowException };
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
index 07a24d7..ead1777 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -28,7 +28,7 @@
 
 typedef HeapVector<Member<SourceListDirective>> SourceListDirectiveVector;
 
-class CORE_EXPORT CSPDirectiveList
+class CORE_EXPORT CSPDirectiveList final
     : public GarbageCollectedFinalized<CSPDirectiveList> {
  public:
   static CSPDirectiveList* Create(ContentSecurityPolicy*,
diff --git a/third_party/blink/renderer/core/frame/csp/csp_source.h b/third_party/blink/renderer/core/frame/csp/csp_source.h
index 23c02f72..331d20a 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_source.h
+++ b/third_party/blink/renderer/core/frame/csp/csp_source.h
@@ -18,7 +18,8 @@
 class ContentSecurityPolicy;
 class KURL;
 
-class CORE_EXPORT CSPSource : public GarbageCollectedFinalized<CSPSource> {
+class CORE_EXPORT CSPSource final
+    : public GarbageCollectedFinalized<CSPSource> {
  public:
   enum WildcardDisposition { kNoWildcard, kHasWildcard };
 
diff --git a/third_party/blink/renderer/core/frame/history.cc b/third_party/blink/renderer/core/frame/history.cc
index db65bba..0eef974 100644
--- a/third_party/blink/renderer/core/frame/history.cc
+++ b/third_party/blink/renderer/core/frame/history.cc
@@ -89,7 +89,7 @@
 }
 
 SerializedScriptValue* History::StateInternal() const {
-  if (!GetFrame())
+  if (!GetFrame() || !GetFrame()->Loader().GetDocumentLoader())
     return nullptr;
 
   if (HistoryItem* history_item =
@@ -195,7 +195,7 @@
     return;
 
   if (delta) {
-    GetFrame()->Client()->NavigateBackForward(delta, true);
+    GetFrame()->Client()->NavigateBackForward(delta);
   } else {
     // We intentionally call reload() for the current frame if delta is zero.
     // Otherwise, navigation happens on the root frame.
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 52f5679..7a267d52 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -308,7 +308,7 @@
   // both when unloading itself and when unloading its descendants.
   IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
       GetDocument());
-  loader_.DispatchUnloadEvent();
+  loader_.DispatchUnloadEvent(nullptr, nullptr);
   DetachChildren();
 
   // All done if detaching the subframes brought about a detach of this frame
@@ -376,7 +376,7 @@
 }
 
 bool LocalFrame::DetachDocument() {
-  return Loader().DetachDocument();
+  return Loader().DetachDocument(nullptr, nullptr);
 }
 
 void LocalFrame::CheckCompleted() {
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 9134ca8d..5d06878 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -194,7 +194,7 @@
                            DownloadCrossOriginRedirects) = 0;
   virtual void LoadErrorPage(int reason) = 0;
 
-  virtual bool NavigateBackForward(int offset, bool from_script) const = 0;
+  virtual bool NavigateBackForward(int offset) const = 0;
 
   // Another page has accessed the initial empty document of this frame. It is
   // no longer safe to display a provisional URL, since a URL spoof is now
diff --git a/third_party/blink/renderer/core/frame/location.cc b/third_party/blink/renderer/core/frame/location.cc
index 2eb0735..dcd0a33 100644
--- a/third_party/blink/renderer/core/frame/location.cc
+++ b/third_party/blink/renderer/core/frame/location.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/selector.h"
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
 #include "third_party/blink/renderer/core/loader/frame_loader.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
@@ -45,10 +46,12 @@
 
 namespace blink {
 
-Location::Location(DOMWindow* dom_window) : dom_window_(dom_window) {}
+Location::Location(DOMWindow* dom_window)
+    : dom_window_(dom_window), selector_(MakeGarbageCollected<Selector>()) {}
 
 void Location::Trace(blink::Visitor* visitor) {
   visitor->Trace(dom_window_);
+  visitor->Trace(selector_);
   ScriptWrappable::Trace(visitor);
 }
 
@@ -95,6 +98,10 @@
   return DOMURLUtilsReadOnly::origin(Url());
 }
 
+Selector* Location::selector() const {
+  return selector_;
+}
+
 DOMStringList* Location::ancestorOrigins() const {
   auto* origins = MakeGarbageCollected<DOMStringList>();
   if (!IsAttached())
diff --git a/third_party/blink/renderer/core/frame/location.h b/third_party/blink/renderer/core/frame/location.h
index 2b8601a..e042d15c 100644
--- a/third_party/blink/renderer/core/frame/location.h
+++ b/third_party/blink/renderer/core/frame/location.h
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/dom_string_list.h"
 #include "third_party/blink/renderer/core/frame/dom_window.h"
+#include "third_party/blink/renderer/core/frame/selector.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -82,6 +83,8 @@
 
   DOMStringList* ancestorOrigins() const;
 
+  Selector* selector() const;
+
   // Just return the |this| object the way the normal valueOf function on the
   // Object prototype would.  The valueOf function is only added to make sure
   // that it cannot be overwritten on location objects, since that would provide
@@ -112,6 +115,8 @@
   const KURL& Url() const;
 
   const Member<DOMWindow> dom_window_;
+
+  Member<Selector> selector_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/location.idl b/third_party/blink/renderer/core/frame/location.idl
index ea47333..da798f6 100644
--- a/third_party/blink/renderer/core/frame/location.idl
+++ b/third_party/blink/renderer/core/frame/location.idl
@@ -59,6 +59,8 @@
     [SetterCallWith=Isolate, RaisesException=Setter, Unforgeable] attribute USVString search;
     [SetterCallWith=Isolate, RaisesException=Setter, Unforgeable] attribute USVString hash;
 
+    [RuntimeEnabled=TextFragmentIdentifiers] readonly attribute Selector selector;
+
     // TODO(foolip): Location does not have a valueOf() override in the spec.
     // See the comment in Location.h for the purpose of this.
     [NotEnumerable, CallWith=ThisValue, Unforgeable] any valueOf();
diff --git a/third_party/blink/renderer/core/frame/selector.h b/third_party/blink/renderer/core/frame/selector.h
new file mode 100644
index 0000000..f006f48
--- /dev/null
+++ b/third_party/blink/renderer/core/frame/selector.h
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SELECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SELECTOR_H_
+
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+// TODO(crbug/1000308): Implement the Selector type. This member currently
+// serves as a feature detectable API for the Text Fragment Identifiers
+// feature.
+class Selector : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SELECTOR_H_
diff --git a/third_party/blink/renderer/core/frame/selector.idl b/third_party/blink/renderer/core/frame/selector.idl
new file mode 100644
index 0000000..13eadaf
--- /dev/null
+++ b/third_party/blink/renderer/core/frame/selector.idl
@@ -0,0 +1,8 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/ScrollToTextFragment
+[RuntimeEnabled=TextFragmentIdentifiers]
+interface Selector {
+};
diff --git a/third_party/blink/renderer/core/frame/viewport_data.h b/third_party/blink/renderer/core/frame/viewport_data.h
index 439b0a2..93c2580b 100644
--- a/third_party/blink/renderer/core/frame/viewport_data.h
+++ b/third_party/blink/renderer/core/frame/viewport_data.h
@@ -15,7 +15,7 @@
 
 class Document;
 
-class ViewportData : public GarbageCollectedFinalized<ViewportData> {
+class ViewportData final : public GarbageCollectedFinalized<ViewportData> {
  public:
   ViewportData(Document& document);
   void Trace(Visitor* visitor);
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index d1f0794..6a5a39d4 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -686,7 +686,7 @@
   // when unloading itself.
   IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
       GetFrame()->GetDocument());
-  GetFrame()->Loader().DispatchUnloadEvent();
+  GetFrame()->Loader().DispatchUnloadEvent(nullptr, nullptr);
 }
 
 void WebLocalFrameImpl::ExecuteScript(const WebScriptSource& source) {
diff --git a/third_party/blink/renderer/core/html/forms/form_data.h b/third_party/blink/renderer/core/html/forms/form_data.h
index 5e9eb52..625cb5e 100644
--- a/third_party/blink/renderer/core/html/forms/form_data.h
+++ b/third_party/blink/renderer/core/html/forms/form_data.h
@@ -119,7 +119,8 @@
 // Represents entry, which is a pair of a name and a value.
 // https://xhr.spec.whatwg.org/#concept-formdata-entry
 // Entry objects are immutable.
-class FormData::Entry : public GarbageCollectedFinalized<FormData::Entry> {
+class FormData::Entry final
+    : public GarbageCollectedFinalized<FormData::Entry> {
  public:
   Entry(const String& name, const String& value);
   Entry(const String& name, Blob* blob, const String& filename);
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
index 9750e22d..0651302 100644
--- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
+++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
@@ -20,7 +20,7 @@
 class ResourceRequest;
 class Visitor;
 
-class LazyLoadFrameObserver
+class LazyLoadFrameObserver final
     : public GarbageCollectedFinalized<LazyLoadFrameObserver> {
  public:
   // This enum is logged to histograms, so values should not be reordered or
diff --git a/third_party/blink/renderer/core/html/parser/html_stack_item.h b/third_party/blink/renderer/core/html/parser/html_stack_item.h
index d81933a..bf566ec 100644
--- a/third_party/blink/renderer/core/html/parser/html_stack_item.h
+++ b/third_party/blink/renderer/core/html/parser/html_stack_item.h
@@ -37,7 +37,7 @@
 
 class ContainerNode;
 
-class HTMLStackItem : public GarbageCollectedFinalized<HTMLStackItem> {
+class HTMLStackItem final : public GarbageCollectedFinalized<HTMLStackItem> {
  public:
   enum ItemType { kItemForContextElement, kItemForDocumentFragmentNode };
 
diff --git a/third_party/blink/renderer/core/input/gesture_manager.h b/third_party/blink/renderer/core/input/gesture_manager.h
index 7d9c046..9e33609cb 100644
--- a/third_party/blink/renderer/core/input/gesture_manager.h
+++ b/third_party/blink/renderer/core/input/gesture_manager.h
@@ -22,7 +22,7 @@
 
 // This class takes care of gestures and delegating the action based on the
 // gesture to the responsible class.
-class CORE_EXPORT GestureManager
+class CORE_EXPORT GestureManager final
     : public GarbageCollectedFinalized<GestureManager> {
  public:
   GestureManager(LocalFrame&,
diff --git a/third_party/blink/renderer/core/input/keyboard_event_manager.h b/third_party/blink/renderer/core/input/keyboard_event_manager.h
index 1c4373b..31a6ec3e 100644
--- a/third_party/blink/renderer/core/input/keyboard_event_manager.h
+++ b/third_party/blink/renderer/core/input/keyboard_event_manager.h
@@ -24,7 +24,7 @@
 
 enum class OverrideCapsLockState { kDefault, kOn, kOff };
 
-class CORE_EXPORT KeyboardEventManager
+class CORE_EXPORT KeyboardEventManager final
     : public GarbageCollectedFinalized<KeyboardEventManager> {
  public:
   static const int kAccessKeyModifiers =
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc
index 8771efbda..c001d20 100644
--- a/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -649,6 +649,7 @@
   if (element.AuthorShadowRoot() &&
       element.AuthorShadowRoot()->delegatesFocus()) {
     Document* doc = frame_->GetDocument();
+    UseCounter::Count(doc, WebFeature::kDelegateFocus);
     Element* focused_element = doc->FocusedElement();
     if (focused_element &&
         element.IsShadowIncludingInclusiveAncestorOf(*focused_element)) {
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.h b/third_party/blink/renderer/core/input/pointer_event_manager.h
index f02d6ca..0ea444c6 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager.h
+++ b/third_party/blink/renderer/core/input/pointer_event_manager.h
@@ -24,7 +24,7 @@
 
 // This class takes care of dispatching all pointer events and keeps track of
 // properties of active pointer events.
-class CORE_EXPORT PointerEventManager
+class CORE_EXPORT PointerEventManager final
     : public GarbageCollectedFinalized<PointerEventManager> {
  public:
   PointerEventManager(LocalFrame&, MouseEventManager&);
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.h b/third_party/blink/renderer/core/input/touch_event_manager.h
index e168bcb6..7f6d37db 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.h
+++ b/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -26,7 +26,7 @@
 
 // This class takes care of dispatching all touch events and
 // maintaining related states.
-class CORE_EXPORT TouchEventManager
+class CORE_EXPORT TouchEventManager final
     : public GarbageCollectedFinalized<TouchEventManager> {
  public:
 
@@ -48,7 +48,7 @@
  private:
   // Class represending one touch point event with its coalesced events and
   // related attributes.
-  class TouchPointAttributes
+  class TouchPointAttributes final
       : public GarbageCollectedFinalized<TouchPointAttributes> {
    public:
     void Trace(blink::Visitor* visitor) { visitor->Trace(target_); }
diff --git a/third_party/blink/renderer/core/inspector/dom_patch_support.h b/third_party/blink/renderer/core/inspector/dom_patch_support.h
index 4093b871..4673de76 100644
--- a/third_party/blink/renderer/core/inspector/dom_patch_support.h
+++ b/third_party/blink/renderer/core/inspector/dom_patch_support.h
@@ -55,7 +55,7 @@
   Node* PatchNode(Node*, const String& markup, ExceptionState&);
 
  private:
-  class Digest : public GarbageCollectedFinalized<Digest> {
+  class Digest final : public GarbageCollectedFinalized<Digest> {
    public:
     explicit Digest(Node* node) : node_(node) {}
     void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/core/inspector/inspector_resource_container.h b/third_party/blink/renderer/core/inspector/inspector_resource_container.h
index 74bd997..5fdef9f6 100644
--- a/third_party/blink/renderer/core/inspector/inspector_resource_container.h
+++ b/third_party/blink/renderer/core/inspector/inspector_resource_container.h
@@ -19,7 +19,7 @@
 class InspectedFrames;
 class LocalFrame;
 
-class CORE_EXPORT InspectorResourceContainer
+class CORE_EXPORT InspectorResourceContainer final
     : public GarbageCollectedFinalized<InspectorResourceContainer> {
  public:
   explicit InspectorResourceContainer(InspectedFrames*);
diff --git a/third_party/blink/renderer/core/layout/layout_video.cc b/third_party/blink/renderer/core/layout/layout_video.cc
index 6f50070..b45e3da9 100644
--- a/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/third_party/blink/renderer/core/layout/layout_video.cc
@@ -110,9 +110,10 @@
   // Cache the image intrinsic size so we can continue to use it to draw the
   // image correctly even if we know the video intrinsic size but aren't able to
   // draw video frames yet (we don't want to scale the poster to the video size
-  // without keeping aspect ratio).
-  if (VideoElement()->ShouldDisplayPosterImage())
-    cached_image_size_ = IntrinsicSize();
+  // without keeping aspect ratio). We do not need to check
+  // |ShouldDisplayPosterImage| because the image can be ready before we find
+  // out we actually need it.
+  cached_image_size_ = IntrinsicSize();
 
   // The intrinsic size is now that of the image, but in case we already had the
   // intrinsic size of the video we call this here to restore the video size.
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 41e2fc1..75161db 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -337,9 +337,7 @@
 
   void TransitionToCommittedForNewPage() override {}
 
-  bool NavigateBackForward(int offset, bool from_script) const override {
-    return false;
-  }
+  bool NavigateBackForward(int offset) const override { return false; }
   void DidDisplayInsecureContent() override {}
   void DidContainInsecureFormAction() override {}
   void DidRunInsecureContent(const SecurityOrigin*, const KURL&) override {}
diff --git a/third_party/blink/renderer/core/loader/form_submission.h b/third_party/blink/renderer/core/loader/form_submission.h
index 519bdea..338875eb 100644
--- a/third_party/blink/renderer/core/loader/form_submission.h
+++ b/third_party/blink/renderer/core/loader/form_submission.h
@@ -47,7 +47,7 @@
 class HTMLFormControlElement;
 class HTMLFormElement;
 
-class FormSubmission : public GarbageCollectedFinalized<FormSubmission> {
+class FormSubmission final : public GarbageCollectedFinalized<FormSubmission> {
  public:
   enum SubmitMethod { kGetMethod, kPostMethod, kDialogMethod };
 
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index b92e161..9b44389 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/public/web/web_navigation_params.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
-#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
 #include "third_party/blink/renderer/core/events/page_transition_event.h"
@@ -206,11 +205,8 @@
       frame_, kWebNavigationTypeOther, std::move(navigation_params),
       nullptr /* extra_data */);
   provisional_document_loader_->StartLoading();
-  WillCommitNavigation();
-  if (!DetachDocument())
-    return;
 
-  CommitDocumentLoader(provisional_document_loader_.Release());
+  CommitDocumentLoader(provisional_document_loader_.Release(), base::nullopt);
 
   // Load the document if needed.
   document_loader_->StartLoadingResponse();
@@ -299,21 +295,20 @@
   Client()->DidUpdateCurrentHistoryItem();
 }
 
-void FrameLoader::DispatchUnloadEvent() {
+void FrameLoader::DispatchUnloadEvent(
+    SecurityOrigin* committing_origin,
+    base::Optional<Document::UnloadEventTiming>* timing) {
   FrameNavigationDisabler navigation_disabler(*frame_);
   SaveScrollState();
 
   Document* document = frame_->GetDocument();
   if (document && !SVGImage::IsInSVGImage(document)) {
-    document->DispatchUnloadEvents(
-        provisional_document_loader_
-            ? &provisional_document_loader_->GetTiming()
-            : nullptr);
+    document->DispatchUnloadEvents(committing_origin, timing);
     // Remove event listeners if we're firing unload events for a reason other
     // than committing a navigation. In the commit case, we'll determine whether
     // event listeners should be retained when choosing whether to reuse the
     // LocalDOMWindow.
-    if (!provisional_document_loader_)
+    if (!timing)
       document->RemoveAllEventListenersRecursively();
   }
 }
@@ -917,6 +912,10 @@
     DCHECK(history_item);
   }
 
+  base::Optional<Document::UnloadEventTiming> unload_timing;
+  scoped_refptr<SecurityOrigin> security_origin =
+      SecurityOrigin::Create(navigation_params->url);
+
   // TODO(dgozman): get rid of provisional document loader and most of the code
   // below. We should probably call DocumentLoader::CommitNavigation directly.
   DocumentLoader* provisional_document_loader = Client()->CreateDocumentLoader(
@@ -941,15 +940,15 @@
     virtual_time_pauser_.PauseVirtualTime();
 
     provisional_document_loader_->StartLoading();
-    WillCommitNavigation();
-
-    if (!DetachDocument())
+    virtual_time_pauser_.UnpauseVirtualTime();
+    DCHECK(Client()->HasWebView());
+    if (!DetachDocument(security_origin.get(), &unload_timing))
       return;
   }
 
   std::move(call_before_attaching_new_document).Run();
 
-  CommitDocumentLoader(provisional_document_loader_.Release());
+  CommitDocumentLoader(provisional_document_loader_.Release(), unload_timing);
 
   // Load the document if needed.
   document_loader_->StartLoadingResponse();
@@ -1012,7 +1011,9 @@
   }
 }
 
-bool FrameLoader::DetachDocument() {
+bool FrameLoader::DetachDocument(
+    SecurityOrigin* committing_origin,
+    base::Optional<Document::UnloadEventTiming>* timing) {
   PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
   DocumentLoader* pdl = provisional_document_loader_;
 
@@ -1031,7 +1032,7 @@
   IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
       frame_->GetDocument());
   if (document_loader_)
-    DispatchUnloadEvent();
+    DispatchUnloadEvent(committing_origin, timing);
   frame_->DetachChildren();
   // The previous calls to dispatchUnloadEvent() and detachChildren() can
   // execute arbitrary script via things like unload events. If the executed
@@ -1065,24 +1066,22 @@
   return true;
 }
 
-void FrameLoader::WillCommitNavigation() {
-  DCHECK(Client()->HasWebView());
-
-  // Check if the destination page is allowed to access the previous page's
-  // timing information.
-  if (frame_->GetDocument()) {
-    scoped_refptr<const SecurityOrigin> security_origin =
-        SecurityOrigin::Create(provisional_document_loader_->Url());
-    provisional_document_loader_->GetTiming()
-        .SetHasSameOriginAsPreviousDocument(
-            security_origin->CanRequest(frame_->GetDocument()->Url()));
-  }
-  virtual_time_pauser_.UnpauseVirtualTime();
-}
-
-void FrameLoader::CommitDocumentLoader(DocumentLoader* document_loader) {
+void FrameLoader::CommitDocumentLoader(
+    DocumentLoader* document_loader,
+    const base::Optional<Document::UnloadEventTiming>& unload_timing) {
   document_loader_ = document_loader;
   CHECK(document_loader_);
+
+  // Update the DocumentLoadTiming with the timings from the previous document
+  // unload event.
+  if (unload_timing.has_value()) {
+    document_loader_->GetTiming().SetHasSameOriginAsPreviousDocument(true);
+    document_loader_->GetTiming().MarkUnloadEventStart(
+        unload_timing->unload_event_start);
+    document_loader_->GetTiming().MarkUnloadEventEnd(
+        unload_timing->unload_event_end);
+  }
+
   document_loader_->MarkAsCommitted();
 
   TakeObjectSnapshot();
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h
index b13f954a..33245362 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -44,6 +44,7 @@
 #include "third_party/blink/public/web/web_frame_load_type.h"
 #include "third_party/blink/public/web/web_navigation_type.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/frame_types.h"
 #include "third_party/blink/renderer/core/frame/sandbox_flags.h"
 #include "third_party/blink/renderer/core/loader/frame_loader_state_machine.h"
@@ -57,7 +58,6 @@
 namespace blink {
 
 class ContentSecurityPolicy;
-class Document;
 class DocumentLoader;
 class LocalFrame;
 class Frame;
@@ -180,12 +180,23 @@
   // This will attempt to detach the current document. It will dispatch unload
   // events and abort XHR requests. Returns true if the frame is ready to
   // receive the next document commit, or false otherwise.
-  bool DetachDocument();
+  bool DetachDocument(SecurityOrigin* committing_origin,
+                      base::Optional<Document::UnloadEventTiming>*);
 
   FrameLoaderStateMachine* StateMachine() const { return &state_machine_; }
 
   bool ShouldClose(bool is_reload = false);
-  void DispatchUnloadEvent();
+
+  // Dispatches the Unload event for the current document. If this is due to the
+  // commit of a navigation, both |committing_origin| and the
+  // Optional<Document::UnloadEventTiming>* should be non null.
+  // |committing_origin| is the origin of the document that is being committed.
+  // If it is allowed to access the unload timings of the current document, the
+  // Document::UnloadEventTiming will be created and populated.
+  // If the dispatch of the unload event is not due to a commit, both parameters
+  // should be null.
+  void DispatchUnloadEvent(SecurityOrigin* committing_origin,
+                           base::Optional<Document::UnloadEventTiming>*);
 
   bool AllowPlugins(ReasonForCallingAllowPlugins);
 
@@ -248,10 +259,9 @@
   std::unique_ptr<TracedValue> ToTracedValue() const;
   void TakeObjectSnapshot() const;
 
-  void WillCommitNavigation();
-
   // Commits the given |document_loader|.
-  void CommitDocumentLoader(DocumentLoader* document_loader);
+  void CommitDocumentLoader(DocumentLoader* document_loader,
+                            const base::Optional<Document::UnloadEventTiming>&);
 
   LocalFrameClient* Client() const;
 
diff --git a/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h b/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
index 9cad373..f144596 100644
--- a/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
+++ b/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
@@ -25,7 +25,7 @@
 // For SignedExchangeSubresourcePrefetch feature. This class holds the
 // prefetched signed exchange info and will returns loaders for matching
 // requests.
-class PrefetchedSignedExchangeManager
+class PrefetchedSignedExchangeManager final
     : public GarbageCollectedFinalized<PrefetchedSignedExchangeManager> {
  public:
   // If threre are no "allowed-alt-sxg" link headers in |inner_link_header|,
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc
index aa350fb..ca5ecf8 100644
--- a/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1190,8 +1190,29 @@
   OwnerMap owner_map;
   ScopedFocusNavigation scope =
       ScopedFocusNavigation::OwnedByShadowHost(shadow_host, owner_map);
-  return FindFocusableElementAcrossFocusScopes(kWebFocusTypeForward, scope,
-                                               owner_map);
+  Element* result = FindFocusableElementAcrossFocusScopes(kWebFocusTypeForward,
+                                                          scope, owner_map);
+  if (!result)
+    return nullptr;
+  // Check if |found| is the first focusable element under |element|, and count
+  // if it's not.
+  const Node* current = &shadow_host;
+  while ((current = FlatTreeTraversal::Next(*current))) {
+    if (!current->IsElementNode())
+      continue;
+    if (current == result) {
+      // We've reached |found|, which means |found| is the first focusable
+      // element so we don't count this.
+      break;
+    }
+    if (ToElement(current)->IsFocusable()) {
+      UseCounter::Count(shadow_host.GetDocument(),
+                        WebFeature::kDelegateFocusNotFirstInFlatTree);
+      break;
+    }
+  }
+
+  return result;
 }
 
 Element* FocusController::FindFocusableElementAfter(Element& element,
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/third_party/blink/renderer/core/page/spatial_navigation_controller.h
index aa546d7..b878ac1 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.h
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.h
@@ -24,7 +24,7 @@
 // Navigation is used to move and interact with a page in a purely directional
 // way, e.g. keyboard arrows. We use the term "interest" to specify which
 // element the user is currently on.
-class CORE_EXPORT SpatialNavigationController
+class CORE_EXPORT SpatialNavigationController final
     : public GarbageCollectedFinalized<SpatialNavigationController> {
  public:
   explicit SpatialNavigationController(Page& page);
diff --git a/third_party/blink/renderer/core/paint/image_element_timing.h b/third_party/blink/renderer/core/paint/image_element_timing.h
index 113c415d..58c1cff 100644
--- a/third_party/blink/renderer/core/paint/image_element_timing.h
+++ b/third_party/blink/renderer/core/paint/image_element_timing.h
@@ -79,7 +79,7 @@
                                 base::TimeTicks timestamp);
 
   // Class containing information about image element timing.
-  class ElementTimingInfo
+  class ElementTimingInfo final
       : public GarbageCollectedFinalized<ElementTimingInfo> {
    public:
     ElementTimingInfo(const String& url,
diff --git a/third_party/blink/renderer/core/streams/readable_stream_native.cc b/third_party/blink/renderer/core/streams/readable_stream_native.cc
index 632ea367..0f305b8 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_native.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_native.cc
@@ -41,7 +41,7 @@
 // TODO(ricea): Create internal versions of ReadableStreamDefaultReader::Read()
 // and WritableStreamDefaultWriter::Write() to bypass promise creation and so
 // reduce the number of allocations on the hot path.
-class ReadableStreamNative::PipeToEngine
+class ReadableStreamNative::PipeToEngine final
     : public GarbageCollectedFinalized<PipeToEngine> {
  public:
   PipeToEngine(ScriptState* script_state, PipeOptions pipe_options)
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.h b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
index 3e6ecf2..d34ce283 100644
--- a/third_party/blink/renderer/core/streams/stream_promise_resolver.h
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
@@ -21,7 +21,7 @@
 // need to be stored somewhere: promises on the stack should generally use
 // v8::Local<v8::Promise>, or ScriptPromise if they are to be returned to the
 // bindings code.
-class CORE_EXPORT StreamPromiseResolver
+class CORE_EXPORT StreamPromiseResolver final
     : public GarbageCollectedFinalized<StreamPromiseResolver> {
  public:
   // Implements "a promise rejected with" from the INFRA standard.
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
index 36e484b..47f1f2a2 100644
--- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
+++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -34,7 +34,7 @@
         name: "ScrollAnchorDisablingPropertyChanged",
         fields_to_diff: ["width", "min-width", "max-width", "height", "min-height", "max-height", "margin-top", "margin-left", "margin-right", "margin-bottom", 
                   "left", "right", "top", "bottom", "padding-top", 
-                  "padding-left", "padding-right", "padding-bottom"],
+                  "padding-left", "padding-right", "padding-bottom", "content-size"],
         methods_to_diff: [
           {
             method: "GetPosition()",
@@ -228,7 +228,7 @@
         fields_to_diff: ["width", "min-width", "max-width", "height", "min-height",
                 "max-height", "VerticalAlignLength", "box-sizing", "align-content",
                 "align-items", "align-self", "justify-content", "justify-items",
-                "justify-self", "contain"],
+                "justify-self", "contain", "content-size"],
         methods_to_diff: [
           {
             method: "VerticalAlign()",
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc
index 0c048fa..0ed2dce 100644
--- a/third_party/blink/renderer/core/style/computed_style_test.cc
+++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
 #include "third_party/blink/renderer/core/css/css_test_helpers.h"
 #include "third_party/blink/renderer/core/css/css_value_list.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
@@ -535,4 +536,53 @@
   EXPECT_EQ(WebColorScheme::kLight, style->UsedColorScheme());
 }
 
+TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
+  ScopedCSSColorSchemeForTest scoped_property_enabled(true);
+
+  std::unique_ptr<DummyPageHolder> dummy_page_holder_ =
+      std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
+  const ComputedStyle* initial = &ComputedStyle::InitialStyle();
+
+  auto* ua_context = MakeGarbageCollected<CSSParserContext>(
+      kUASheetMode, SecureContextMode::kInsecureContext);
+  const CSSValue* internal_light_dark = CSSParser::ParseSingleValue(
+      CSSPropertyID::kColor, "-internal-light-dark-color(black, white)",
+      ua_context);
+
+  dummy_page_holder_->GetDocument().GetSettings()->SetPreferredColorScheme(
+      PreferredColorScheme::kDark);
+  StyleResolverState state(dummy_page_holder_->GetDocument(),
+                           *dummy_page_holder_->GetDocument().documentElement(),
+                           initial, initial);
+
+  StyleResolver& resolver =
+      dummy_page_holder_->GetDocument().EnsureStyleResolver();
+
+  scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+  state.SetStyle(style);
+
+  CSSValueList* dark_value = CSSValueList::CreateSpaceSeparated();
+  dark_value->Append(*CSSIdentifierValue::Create(CSSValueID::kDark));
+
+  CSSValueList* light_value = CSSValueList::CreateSpaceSeparated();
+  light_value->Append(*CSSIdentifierValue::Create(CSSValueID::kLight));
+
+  CSSPropertyRef scheme_property("color-scheme", state.GetDocument());
+  CSSPropertyRef color_property("color", state.GetDocument());
+
+  To<Longhand>(color_property.GetProperty())
+      .ApplyValue(state, *internal_light_dark);
+  To<Longhand>(scheme_property.GetProperty()).ApplyValue(state, *dark_value);
+  if (!RuntimeEnabledFeatures::CSSCascadeEnabled())
+    resolver.ApplyCascadedColorValue(state);
+  EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor()));
+
+  To<Longhand>(color_property.GetProperty())
+      .ApplyValue(state, *internal_light_dark);
+  To<Longhand>(scheme_property.GetProperty()).ApplyValue(state, *light_value);
+  if (!RuntimeEnabledFeatures::CSSCascadeEnabled())
+    resolver.ApplyCascadedColorValue(state);
+  EXPECT_EQ(Color::kBlack, style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time_container.h b/third_party/blink/renderer/core/svg/animation/smil_time_container.h
index b29d061c..13b7c0f0 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_time_container.h
+++ b/third_party/blink/renderer/core/svg/animation/smil_time_container.h
@@ -43,7 +43,8 @@
 class SVGElement;
 class SVGSVGElement;
 
-class SMILTimeContainer : public GarbageCollectedFinalized<SMILTimeContainer> {
+class SMILTimeContainer final
+    : public GarbageCollectedFinalized<SMILTimeContainer> {
  public:
   // Sorted list
   using AnimationId = std::pair<WeakMember<SVGElement>, QualifiedName>;
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
index d5c9bd8a..746b4f5 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -198,7 +198,7 @@
   // This represents conditions on elements begin or end list that need to be
   // resolved on runtime, for example
   // <animate begin="otherElement.begin + 8s; button.click" ... />
-  class Condition : public GarbageCollectedFinalized<Condition> {
+  class Condition final : public GarbageCollectedFinalized<Condition> {
    public:
     enum Type { kEventBase, kSyncBase, kAccessKey };
 
diff --git a/third_party/blink/renderer/core/svg/linear_gradient_attributes.h b/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
index f42ab8e..d002ad5 100644
--- a/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
+++ b/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
@@ -92,7 +92,7 @@
 };
 
 // Wrapper object for the LinearGradientAttributes part object.
-class LinearGradientAttributesWrapper
+class LinearGradientAttributesWrapper final
     : public GarbageCollectedFinalized<LinearGradientAttributesWrapper> {
  public:
   LinearGradientAttributesWrapper() = default;
diff --git a/third_party/blink/renderer/core/svg/radial_gradient_attributes.h b/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
index 7f54ba02..90b8711 100644
--- a/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
+++ b/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
@@ -114,7 +114,7 @@
 };
 
 // Wrapper object for the RadialGradientAttributes part object.
-class RadialGradientAttributesWrapper
+class RadialGradientAttributesWrapper final
     : public GarbageCollectedFinalized<RadialGradientAttributesWrapper> {
  public:
   RadialGradientAttributesWrapper() = default;
diff --git a/third_party/blink/renderer/core/svg/svg_document_extensions.h b/third_party/blink/renderer/core/svg/svg_document_extensions.h
index 7972d0af..f14413f 100644
--- a/third_party/blink/renderer/core/svg/svg_document_extensions.h
+++ b/third_party/blink/renderer/core/svg/svg_document_extensions.h
@@ -35,7 +35,7 @@
 class SVGSVGElement;
 class SubtreeLayoutScope;
 
-class SVGDocumentExtensions
+class SVGDocumentExtensions final
     : public GarbageCollectedFinalized<SVGDocumentExtensions> {
  public:
   explicit SVGDocumentExtensions(Document*);
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.h b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
index 4478f9dd..8351a68 100644
--- a/third_party/blink/renderer/core/svg/svg_element_rare_data.h
+++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
@@ -31,7 +31,7 @@
 
 class SVGResourceClient;
 
-class SVGElementRareData
+class SVGElementRareData final
     : public GarbageCollectedFinalized<SVGElementRareData> {
  public:
   SVGElementRareData()
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
index ebf436c..6d745ebb5 100644
--- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
+++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
@@ -18,7 +18,7 @@
 // This class keeps track of SVG resources and pending references to such for a
 // TreeScope. It's per-TreeScope because that matches the lookup scope of an
 // element's id (which is used to identify a resource.)
-class SVGTreeScopeResources
+class SVGTreeScopeResources final
     : public GarbageCollectedFinalized<SVGTreeScopeResources> {
  public:
   explicit SVGTreeScopeResources(TreeScope*);
diff --git a/third_party/blink/renderer/core/workers/worklet_module_responses_map.h b/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
index 2e95cd1..e6d31c5 100644
--- a/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
+++ b/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
@@ -32,7 +32,7 @@
 // across worklet threads. All access to this class should be mutex-guarded,
 // and any data passed in or read out is copied to ensure that this object's
 // internal state can be safely destructed from the main thread.
-class CORE_EXPORT WorkletModuleResponsesMap
+class CORE_EXPORT WorkletModuleResponsesMap final
     : public GarbageCollectedFinalized<WorkletModuleResponsesMap> {
  public:
   WorkletModuleResponsesMap() = default;
diff --git a/third_party/blink/renderer/core/xml/xpath_step.h b/third_party/blink/renderer/core/xml/xpath_step.h
index 7082de8..ec283202 100644
--- a/third_party/blink/renderer/core/xml/xpath_step.h
+++ b/third_party/blink/renderer/core/xml/xpath_step.h
@@ -57,7 +57,7 @@
     kSelfAxis
   };
 
-  class NodeTest : public GarbageCollectedFinalized<NodeTest> {
+  class NodeTest final : public GarbageCollectedFinalized<NodeTest> {
    public:
     enum Kind {
       kTextNodeTest,
diff --git a/third_party/blink/renderer/core/xml/xpath_value.h b/third_party/blink/renderer/core/xml/xpath_value.h
index 3a3e523..cfba3f1 100644
--- a/third_party/blink/renderer/core/xml/xpath_value.h
+++ b/third_party/blink/renderer/core/xml/xpath_value.h
@@ -37,7 +37,7 @@
 
 struct EvaluationContext;
 
-class ValueData : public GarbageCollectedFinalized<ValueData> {
+class ValueData final : public GarbageCollectedFinalized<ValueData> {
  public:
   ValueData() : node_set_(NodeSet::Create()) {}
   explicit ValueData(const NodeSet& node_set)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 129600f6d..2072655 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -101,7 +101,7 @@
   void Trace(blink::Visitor* visitor) { visitor->Trace(related_object); }
 };
 
-class NameSourceRelatedObject
+class NameSourceRelatedObject final
     : public GarbageCollectedFinalized<NameSourceRelatedObject> {
  public:
   WeakMember<AXObject> object;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 0c4ceb5..34d7678 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -268,7 +268,7 @@
   AXObject* CreateFromInlineTextBox(AbstractInlineTextBox*);
 
  private:
-  struct AXEventParams : public GarbageCollectedFinalized<AXEventParams> {
+  struct AXEventParams final : public GarbageCollectedFinalized<AXEventParams> {
     AXEventParams(AXObject* target,
                   ax::mojom::Event event_type,
                   ax::mojom::EventFrom event_from)
@@ -280,7 +280,8 @@
     void Trace(Visitor* visitor) { visitor->Trace(target); }
   };
 
-  struct TreeUpdateParams : public GarbageCollectedFinalized<TreeUpdateParams> {
+  struct TreeUpdateParams final
+      : public GarbageCollectedFinalized<TreeUpdateParams> {
     TreeUpdateParams(Node* node, base::OnceClosure callback)
         : node(node), callback(std::move(callback)) {}
     WeakMember<Node> node;
diff --git a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
index ab7f9ed..deca23b 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -575,13 +575,18 @@
     if (extensions->hasCableAuthentication()) {
       Vector<CableAuthenticationPtr> mojo_data;
       for (auto& data : extensions->cableAuthentication()) {
+        if (data->version() != 1) {
+          continue;
+        }
         CableAuthenticationPtr mojo_cable =
             CableAuthentication::From(data.Get());
         if (mojo_cable) {
           mojo_data.push_back(std::move(mojo_cable));
         }
       }
-      mojo_options->cable_authentication_data = std::move(mojo_data);
+      if (mojo_data.size() > 0) {
+        mojo_options->cable_authentication_data = std::move(mojo_data);
+      }
     }
 #if defined(OS_ANDROID)
     if (extensions->hasUvm()) {
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_error.h b/third_party/blink/renderer/modules/geolocation/geolocation_error.h
index d27b7ab..b6d759a 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation_error.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_error.h
@@ -30,7 +30,8 @@
 
 namespace blink {
 
-class GeolocationError : public GarbageCollectedFinalized<GeolocationError> {
+class GeolocationError final
+    : public GarbageCollectedFinalized<GeolocationError> {
  public:
   enum ErrorCode { kPermissionDenied, kPositionUnavailable };
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_any.h b/third_party/blink/renderer/modules/indexeddb/idb_any.h
index 38dc88f..5af7a5b5 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_any.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_any.h
@@ -53,7 +53,7 @@
 // This allows for lazy conversion to script values (via IDBBindingUtilities),
 // and avoids the need for many dedicated union types.
 
-class MODULES_EXPORT IDBAny : public GarbageCollectedFinalized<IDBAny> {
+class MODULES_EXPORT IDBAny final : public GarbageCollectedFinalized<IDBAny> {
  public:
   static IDBAny* CreateUndefined();
   static IDBAny* CreateNull();
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
index 7c3da873..59614f96 100644
--- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
+++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
@@ -42,9 +42,8 @@
 // All methods are called on the same thread as construction and destruction,
 // i.e. the Main Render thread. (Note that a BindToCurrentLoop is used to
 // guarantee this, since VideoTrackRecorder sends back frames on IO thread.)
-class MODULES_EXPORT MediaRecorderHandler
+class MODULES_EXPORT MediaRecorderHandler final
     : public GarbageCollectedFinalized<MediaRecorderHandler> {
-
  public:
   static MediaRecorderHandler* Create(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
diff --git a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
index 23a41d4..cd6c6d19 100644
--- a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
+++ b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
@@ -27,7 +27,7 @@
 // requests. Only one applyConstraints() request can be processed at a time.
 // ApplyConstraintsProcessor must be created, called and destroyed on the main
 // render thread. There should be only one ApplyConstraintsProcessor per frame.
-class MODULES_EXPORT ApplyConstraintsProcessor
+class MODULES_EXPORT ApplyConstraintsProcessor final
     : public GarbageCollectedFinalized<ApplyConstraintsProcessor> {
  public:
   using MediaDevicesDispatcherCallback = base::RepeatingCallback<
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client.h b/third_party/blink/renderer/modules/mediastream/user_media_client.h
index 83e569cf..389cd48 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client.h
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client.h
@@ -62,7 +62,7 @@
           media_devices_dispatcher);
 
  private:
-  class Request : public GarbageCollectedFinalized<Request> {
+  class Request final : public GarbageCollectedFinalized<Request> {
    public:
     explicit Request(std::unique_ptr<UserMediaRequestInfo> request);
     explicit Request(blink::ApplyConstraintsRequest* request);
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index 6c5f027d..c5a0939 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -263,7 +263,7 @@
       is_processing_user_gesture(is_processing_user_gesture) {}
 
 // Class for storing state of the the processing of getUserMedia requests.
-class UserMediaProcessor::RequestInfo
+class UserMediaProcessor::RequestInfo final
     : public GarbageCollectedFinalized<UserMediaProcessor::RequestInfo> {
  public:
   using ResourcesReady =
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 20350d57..533f068d 100644
--- a/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -97,7 +97,7 @@
 // referenced by |PaymentInstrument| will not be traced through the callback and
 // can be prematurely destroyed.
 // TODO(keishi): Remove this conversion if IDLDictionaryBase situation changes.
-class PaymentInstrumentParameter
+class PaymentInstrumentParameter final
     : public GarbageCollectedFinalized<PaymentInstrumentParameter> {
  public:
   explicit PaymentInstrumentParameter(const PaymentInstrument* instrument)
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index 939d2821..c77b03a0 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -372,7 +372,7 @@
                            GetTrackRemoveStreamAndGCWithPersistentStream);
 
   typedef base::OnceCallback<bool()> BoolFunction;
-  class EventWrapper : public GarbageCollectedFinalized<EventWrapper> {
+  class EventWrapper final : public GarbageCollectedFinalized<EventWrapper> {
    public:
     EventWrapper(Event*, BoolFunction);
     // Returns true if |m_setupFunction| returns true or it is null.
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability_state.h b/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
index e1ee2bf..d9acbd05 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
@@ -28,7 +28,7 @@
 // TODO(crbug.com/780109): Improve encapsulation of PresentationAvailability and
 // this class by moving the multiple URL tracking logic to the former, and
 // consolidating this class's APIs to take repeating callbacks.
-class MODULES_EXPORT PresentationAvailabilityState
+class MODULES_EXPORT PresentationAvailabilityState final
     : public GarbageCollectedFinalized<PresentationAvailabilityState> {
  public:
   explicit PresentationAvailabilityState(mojom::blink::PresentationService*);
@@ -60,7 +60,7 @@
   // Tracks listeners of presentation displays availability for
   // |availability_urls|. Shared with PresentationRequest objects with the same
   // set of URLs.
-  class AvailabilityListener
+  class AvailabilityListener final
       : public GarbageCollectedFinalized<AvailabilityListener> {
    public:
     explicit AvailabilityListener(const Vector<KURL>& availability_urls);
diff --git a/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
index 880e3228..1c39732e 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/presentation/presentation_controller.h"
 
 #include <memory>
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -153,14 +154,11 @@
 
 mojo::Remote<mojom::blink::PresentationService>&
 PresentationController::GetPresentationService() {
-  if (!presentation_service_remote_ && GetFrame() && GetFrame()->Client()) {
-    auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider();
-
+  if (!presentation_service_remote_ && GetFrame()) {
     scoped_refptr<base::SingleThreadTaskRunner> task_runner =
         GetFrame()->GetTaskRunner(TaskType::kPresentation);
-    interface_provider->GetInterface(
+    GetFrame()->GetBrowserInterfaceBroker().GetInterface(
         presentation_service_remote_.BindNewPipeAndPassReceiver(task_runner));
-
     presentation_service_remote_->SetController(
         presentation_controller_receiver_.BindNewPipeAndPassRemote(
             task_runner));
diff --git a/third_party/blink/renderer/modules/presentation/presentation_receiver.cc b/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
index 21d9751..df661cb6 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/presentation/presentation_receiver.h"
 
 #include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -27,16 +28,14 @@
     : ContextLifecycleObserver(frame->GetDocument()),
       connection_list_(MakeGarbageCollected<PresentationConnectionList>(
           frame->GetDocument())) {
-  auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider();
-  interface_provider->GetInterface(
+  frame->GetBrowserInterfaceBroker().GetInterface(
       presentation_service_remote_.BindNewPipeAndPassReceiver());
-
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       frame->GetTaskRunner(TaskType::kPresentation);
 
   // Set the mojo::Remote<T> that remote implementation of PresentationService
-  // will use to interact with the associated PresentationReceiver, in order to
-  // receive updates on new connections becoming available.
+  // will use to interact with the associated PresentationReceiver, in order
+  // to receive updates on new connections becoming available.
   presentation_service_remote_->SetReceiver(
       presentation_receiver_receiver_.BindNewPipeAndPassRemote(task_runner));
 }
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h b/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h
index 5a8a9af..59e5900 100644
--- a/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h
+++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h
@@ -19,7 +19,7 @@
 
 // https://w3c.github.io/wake-lock/#concepts-and-state-record
 // Per-document and per-wake lock type internal data.
-class MODULES_EXPORT WakeLockStateRecord
+class MODULES_EXPORT WakeLockStateRecord final
     : public GarbageCollectedFinalized<WakeLockStateRecord> {
  public:
   WakeLockStateRecord(ExecutionContext*, WakeLockType);
diff --git a/third_party/blink/renderer/modules/webdatabase/database_thread.h b/third_party/blink/renderer/modules/webdatabase/database_thread.h
index 9eeae61fa..60ca9b00 100644
--- a/third_party/blink/renderer/modules/webdatabase/database_thread.h
+++ b/third_party/blink/renderer/modules/webdatabase/database_thread.h
@@ -43,7 +43,7 @@
 class SQLTransactionClient;
 class SQLTransactionCoordinator;
 
-class DatabaseThread : public GarbageCollectedFinalized<DatabaseThread> {
+class DatabaseThread final : public GarbageCollectedFinalized<DatabaseThread> {
  public:
   DatabaseThread();
   ~DatabaseThread();
diff --git a/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h b/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
index dadec74..947bfab 100644
--- a/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
+++ b/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
@@ -39,7 +39,7 @@
 namespace blink {
 class Database;
 
-class InspectorDatabaseResource
+class InspectorDatabaseResource final
     : public GarbageCollectedFinalized<InspectorDatabaseResource> {
  public:
   InspectorDatabaseResource(Database*,
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h b/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
index 35e5be3..bec6d2f 100644
--- a/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
+++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
@@ -44,7 +44,7 @@
 
 class SQLTransactionBackend;
 
-class SQLTransactionCoordinator
+class SQLTransactionCoordinator final
     : public GarbageCollectedFinalized<SQLTransactionCoordinator> {
  public:
   SQLTransactionCoordinator();
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
index d0a92c7..ad09429 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -102,7 +102,7 @@
   std::unique_ptr<FileReaderLoader> loader_;
 };
 
-class WebSocketChannelImpl::Message
+class WebSocketChannelImpl::Message final
     : public GarbageCollectedFinalized<WebSocketChannelImpl::Message> {
  public:
   Message(const std::string&, base::OnceClosure completion_callback);
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index e7f80cc3..f9f94f7f 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1227,6 +1227,9 @@
     "mojo/revocable_strong_binding.h",
     "mojo/string16_mojom_traits.cc",
     "mojo/string16_mojom_traits.h",
+    "p2p/empty_network_manager.cc",
+    "p2p/filtering_network_manager.cc",
+    "p2p/ipc_network_manager.cc",
     "p2p/network_manager_uma.cc",
     "peerconnection/audio_codec_factory.cc",
     "peerconnection/rtc_answer_options_platform.h",
@@ -1251,6 +1254,7 @@
     "peerconnection/rtc_video_encoder_factory.cc",
     "peerconnection/rtc_video_encoder_factory.h",
     "peerconnection/rtc_void_request.h",
+    "peerconnection/stun_field_trial.cc",
     "peerconnection/transmission_encoding_info_handler.cc",
     "peerconnection/transmission_encoding_info_handler.h",
     "peerconnection/video_codec_factory.cc",
@@ -1446,6 +1450,7 @@
     "//crypto",
     "//device/vr/public/mojom:mojom_blink",
     "//gin",
+    "//jingle:webrtc_glue",
     "//media",
     "//media/capture/mojom:video_capture",
     "//mojo/public/cpp/base",
@@ -1806,9 +1811,12 @@
     "mojo/interface_invalidator_test.cc",
     "mojo/kurl_security_origin_test.cc",
     "mojo/string16_mojom_traits_test.cc",
+    "p2p/filtering_network_manager_test.cc",
+    "p2p/ipc_network_manager_test.cc",
     "peerconnection/rtc_stats_test.cc",
     "peerconnection/rtc_video_decoder_adapter_test.cc",
     "peerconnection/rtc_video_encoder_test.cc",
+    "peerconnection/stun_field_trial_test.cc",
     "peerconnection/transmission_encoding_info_handler_test.cc",
     "peerconnection/two_keys_adapter_map_unittest.cc",
     "peerconnection/webrtc_video_track_source_test.cc",
diff --git a/third_party/blink/renderer/platform/bindings/script_state.h b/third_party/blink/renderer/platform/bindings/script_state.h
index b7deb68b..31a15ce 100644
--- a/third_party/blink/renderer/platform/bindings/script_state.h
+++ b/third_party/blink/renderer/platform/bindings/script_state.h
@@ -204,7 +204,7 @@
 // ScriptStateProtectingContext keeps the context associated with the
 // ScriptState alive.  You need to call Clear() once you no longer need the
 // context. Otherwise, the context will leak.
-class ScriptStateProtectingContext
+class ScriptStateProtectingContext final
     : public GarbageCollectedFinalized<ScriptStateProtectingContext> {
  public:
   explicit ScriptStateProtectingContext(ScriptState* script_state)
diff --git a/third_party/blink/renderer/platform/bindings/v8_global_value_map.h b/third_party/blink/renderer/platform/bindings/v8_global_value_map.h
index eb5e19b..ac7c7a2 100644
--- a/third_party/blink/renderer/platform/bindings/v8_global_value_map.h
+++ b/third_party/blink/renderer/platform/bindings/v8_global_value_map.h
@@ -98,17 +98,16 @@
  * A map for safely storing persistent V8 values, based on
  * v8::GlobalValueMap.
  */
-template <typename KeyType,
-          typename ValueType,
-          v8::PersistentContainerCallbackType type>
-class V8GlobalValueMap : public v8::GlobalValueMap<
-                             KeyType,
-                             ValueType,
-                             V8GlobalValueMapTraits<KeyType, ValueType, type>> {
+template <typename KeyType, typename ValueType>
+class V8GlobalValueMap
+    : public v8::GlobalValueMap<
+          KeyType,
+          ValueType,
+          V8GlobalValueMapTraits<KeyType, ValueType, v8::kNotWeak>> {
   DISALLOW_NEW();
 
  public:
-  typedef V8GlobalValueMapTraits<KeyType, ValueType, type> Traits;
+  typedef V8GlobalValueMapTraits<KeyType, ValueType, v8::kNotWeak> Traits;
   explicit V8GlobalValueMap(v8::Isolate* isolate)
       : v8::GlobalValueMap<KeyType, ValueType, Traits>(isolate) {}
   V8GlobalValueMap(v8::Isolate* isolate, const char* label)
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_context_data.h b/third_party/blink/renderer/platform/bindings/v8_per_context_data.h
index 146dbe6b..203cb7c 100644
--- a/third_party/blink/renderer/platform/bindings/v8_per_context_data.h
+++ b/third_party/blink/renderer/platform/bindings/v8_per_context_data.h
@@ -132,13 +132,9 @@
 
   // For each possible type of wrapper, we keep a boilerplate object.
   // The boilerplate is used to create additional wrappers of the same type.
-  typedef V8GlobalValueMap<const WrapperTypeInfo*, v8::Object, v8::kNotWeak>
-      WrapperBoilerplateMap;
-  WrapperBoilerplateMap wrapper_boilerplates_;
+  V8GlobalValueMap<const WrapperTypeInfo*, v8::Object> wrapper_boilerplates_;
 
-  typedef V8GlobalValueMap<const WrapperTypeInfo*, v8::Function, v8::kNotWeak>
-      ConstructorMap;
-  ConstructorMap constructor_map_;
+  V8GlobalValueMap<const WrapperTypeInfo*, v8::Function> constructor_map_;
 
   std::unique_ptr<gin::ContextHolder> context_holder_;
 
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
index c91cbc8..97b2bc31f 100644
--- a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
+++ b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
@@ -262,7 +262,7 @@
   // When taking a V8 context snapshot, we can't keep V8 objects with eternal
   // handles. So we use a special interface map that doesn't use eternal handles
   // instead of the default V8FunctionTemplateMap.
-  V8GlobalValueMap<const WrapperTypeInfo*, v8::FunctionTemplate, v8::kNotWeak>
+  V8GlobalValueMap<const WrapperTypeInfo*, v8::FunctionTemplate>
       interface_template_map_for_v8_context_snapshot_;
 
   std::unique_ptr<StringCache> string_cache_;
diff --git a/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
index 34a5c25..ac60de4 100644
--- a/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
+++ b/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
@@ -40,8 +40,13 @@
 
 Your class may need to have a tracing method. See [Tracing](#Tracing) for details.
 
-If your class needs finalization (i.e. some work needs to be done on destruction), use
-[GarbageCollectedFinalized](#GarbageCollectedFinalized) instead.
+Your class will be automatically finalized as long as it is non-trivially destructible. Non-final classes are
+required to have a virtual destructor.
+
+Note that finalization is done at an arbitrary time after the object becomes unreachable.
+
+Any destructor executed within the finalization period must not touch any other on-heap object, because destructors
+can be executed in any order.
 
 `GarbageCollected<T>` or any class deriving from `GarbageCollected<T>`, directly or indirectly, must be the first
 element in its base class list (called "leftmost derivation rule"). This rule is needed to assure each on-heap object
@@ -75,40 +80,11 @@
 };
 ```
 
-### GarbageCollectedFinalized
-
-If you want to make your class garbage-collected and the class needs finalization, your class needs to inherit from
-`GarbageCollectedFinalized<YourClass>` instead of `GarbageCollected<YourClass>`.
-
-A class is said to *need finalization* when it meets either of the following criteria:
-
-*   It has non-empty destructor; or
-*   It has a member that needs finalization.
-
-```c++
-class YourClass : public GarbageCollectedFinalized<YourClass> {
-public:
-  ~YourClass() { ... } // Non-empty destructor means finalization is needed.
-
-private:
-  scoped_refptr<Something> something_; // scoped_refptr<> has non-empty destructor, so finalization is needed.
-};
-```
-
-Note that finalization is done at an arbitrary time after the object becomes unreachable.
-
-Any destructor executed within the finalization period must not touch any other on-heap object, because destructors
-can be executed in any order.
-
-Because `GarbageCollectedFinalized<T>` is a special case of `GarbageCollected<T>`, all the restrictions that apply
-to `GarbageCollected<T>` classes also apply to `GarbageCollectedFinalized<T>`.
-
 ### GarbageCollectedMixin
 
 A non-leftmost base class of a garbage-collected class may derive from `GarbageCollectedMixin`. If a direct child
-class of `GarbageCollected<T>` or `GarbageCollectedFinalized<T>` has a non-leftmost base class deriving from
-`GarbageCollectedMixin`, the garbage-collected class must declare the `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` macro
-in its class declaration.
+class of `GarbageCollected<T>` has a non-leftmost base class deriving from `GarbageCollectedMixin`, the
+garbage-collected class must declare the `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` macro in its class declaration.
 
 A class deriving from `GarbageCollectedMixin` can be treated similarly as garbage-collected classes. Specifically, it
 can have `Member<T>`s and `WeakMember<T>`s, and a tracing method. A pointer to such a class must be retained in the
@@ -179,7 +155,7 @@
 It is useful for doing cleanups that cannot be done with a destructor.
 
 ```c++
-class YourClass : public GarbageCollectedFinalized<YourClass> {
+class YourClass : public GarbageCollected<YourClass> {
   USING_PRE_FINALIZER(YourClass, Dispose);
 public:
   void Dispose() {
@@ -200,7 +176,7 @@
 It is possible to construct such delegations using virtual methods.
 
 ```c++
-class Parent : public GarbageCollectedFinalized<Parent> {
+class Parent : public GarbageCollected<Parent> {
   USING_PRE_FINALIZER(Parent, Dispose);
  public:
   void Dispose() { DisposeImpl(); }
diff --git a/third_party/blink/renderer/platform/heap/DEPS b/third_party/blink/renderer/platform/heap/DEPS
index 43c7d4f..e1cb1668 100644
--- a/third_party/blink/renderer/platform/heap/DEPS
+++ b/third_party/blink/renderer/platform/heap/DEPS
@@ -11,6 +11,7 @@
     "+base/sampling_heap_profiler/poisson_allocation_sampler.h",
     "+base/synchronization/lock.h",
     "+base/task_runner.h",
+    "+base/template_util.h",
 
     "+third_party/blink/renderer/platform/bindings",
     "+third_party/blink/renderer/platform/instrumentation/histogram.h",
diff --git a/third_party/blink/renderer/platform/heap/finalizer_traits.h b/third_party/blink/renderer/platform/heap/finalizer_traits.h
index 3a2a9a6..93f9497 100644
--- a/third_party/blink/renderer/platform/heap/finalizer_traits.h
+++ b/third_party/blink/renderer/platform/heap/finalizer_traits.h
@@ -5,6 +5,9 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_
 
+#include <type_traits>
+
+#include "base/template_util.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 
 namespace WTF {
@@ -16,18 +19,42 @@
 
 namespace blink {
 
-// The FinalizerTraitImpl specifies how to finalize objects. Objects that
-// inherit from GarbageCollectedFinalized are finalized by calling their
-// |Finalize| method which by default will call the destructor on the object.
+namespace internal {
+
+template <typename T, typename = void>
+struct HasFinalizeGarbageCollectedObject : std::false_type {};
+
+template <typename T>
+struct HasFinalizeGarbageCollectedObject<
+    T,
+    base::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
+    : std::true_type {};
+
+// The FinalizerTraitImpl specifies how to finalize objects.
 template <typename T, bool isGarbageCollectedFinalized>
 struct FinalizerTraitImpl;
 
 template <typename T>
 struct FinalizerTraitImpl<T, true> {
+ private:
   STATIC_ONLY(FinalizerTraitImpl);
+  struct CustomDispatch {
+    static void Call(void* obj) {
+      static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
+    }
+  };
+  struct DestructorDispatch {
+    static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
+  };
+  using FinalizeImpl =
+      std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value,
+                         CustomDispatch,
+                         DestructorDispatch>;
+
+ public:
   static void Finalize(void* obj) {
     static_assert(sizeof(T), "T must be fully defined");
-    static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
+    FinalizeImpl::Call(obj);
   }
 };
 
@@ -39,21 +66,18 @@
   }
 };
 
+}  // namespace internal
+
 // The FinalizerTrait is used to determine if a type requires finalization and
 // what finalization means.
-//
-// By default classes that inherit from GarbageCollectedFinalized need
-// finalization and finalization means calling the |Finalize| method of the
-// object. The FinalizerTrait can be specialized if the default behavior is not
-// desired.
 template <typename T>
 struct FinalizerTrait {
   STATIC_ONLY(FinalizerTrait);
-  static const bool kNonTrivialFinalizer =
-      WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type,
-                                GarbageCollectedFinalized>::value;
+  static constexpr bool kNonTrivialFinalizer =
+      internal::HasFinalizeGarbageCollectedObject<T>::value ||
+      !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
@@ -66,32 +90,32 @@
 template <typename T, typename U, typename V>
 struct FinalizerTrait<LinkedHashSet<T, U, V, HeapAllocator>> {
   STATIC_ONLY(FinalizerTrait);
-  static const bool kNonTrivialFinalizer = true;
+  static constexpr bool kNonTrivialFinalizer = true;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<LinkedHashSet<T, U, V, HeapAllocator>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<LinkedHashSet<T, U, V, HeapAllocator>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
 template <typename T, typename Allocator>
 struct FinalizerTrait<WTF::ListHashSetNode<T, Allocator>> {
   STATIC_ONLY(FinalizerTrait);
-  static const bool kNonTrivialFinalizer =
+  static constexpr bool kNonTrivialFinalizer =
       !std::is_trivially_destructible<T>::value;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<WTF::ListHashSetNode<T, Allocator>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<WTF::ListHashSetNode<T, Allocator>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
 template <typename T, size_t inlineCapacity>
 struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator>> {
   STATIC_ONLY(FinalizerTrait);
-  static const bool kNonTrivialFinalizer =
+  static constexpr bool kNonTrivialFinalizer =
       inlineCapacity && VectorTraits<T>::kNeedsDestruction;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
@@ -101,8 +125,8 @@
   static const bool kNonTrivialFinalizer =
       inlineCapacity && VectorTraits<T>::kNeedsDestruction;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<Deque<T, inlineCapacity, HeapAllocator>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<Deque<T, inlineCapacity, HeapAllocator>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
@@ -112,8 +136,8 @@
   static const bool kNonTrivialFinalizer =
       !std::is_trivially_destructible<typename Table::ValueType>::value;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<HeapHashTableBacking<Table>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<HeapHashTableBacking<Table>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
@@ -122,8 +146,8 @@
   STATIC_ONLY(FinalizerTrait);
   static const bool kNonTrivialFinalizer = Traits::kNeedsDestruction;
   static void Finalize(void* obj) {
-    FinalizerTraitImpl<HeapVectorBacking<T, Traits>,
-                       kNonTrivialFinalizer>::Finalize(obj);
+    internal::FinalizerTraitImpl<HeapVectorBacking<T, Traits>,
+                                 kNonTrivialFinalizer>::Finalize(obj);
   }
 };
 
diff --git a/third_party/blink/renderer/platform/heap/garbage_collected.h b/third_party/blink/renderer/platform/heap/garbage_collected.h
index f83943bf..6c6842d7 100644
--- a/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -182,41 +182,16 @@
 // Defines a 'new' operator that allocates the memory in the heap.  'delete'
 // should not be called on objects that inherit from GarbageCollected.
 //
-// Instances of GarbageCollected will *NOT* get finalized.  Their destructor
-// will not be called.  Therefore, only classes that have trivial destructors
-// with no semantic meaning (including all their subclasses) should inherit from
-// GarbageCollected.  If there are non-trival destructors in a given class or
-// any of its subclasses, GarbageCollectedFinalized should be used which
-// guarantees that the destructor is called on an instance when the garbage
-// collector determines that it is no longer reachable.
+// Instances of GarbageCollected will be finalized if they are non-trivially
+// destructible.
 template <typename T>
 class GarbageCollected;
 
-// Base class for objects allocated in the Blink garbage-collected heap.
-//
-// Defines a 'new' operator that allocates the memory in the heap.  'delete'
-// should not be called on objects that inherit from GarbageCollected.
-//
-// Instances of GarbageCollectedFinalized will have their destructor called when
-// the garbage collector determines that the object is no longer reachable.
+// TODO(bikineev): Remove this class after the clang plugin is updated.
 template <typename T>
 class GarbageCollectedFinalized : public GarbageCollected<T> {
  protected:
-  // finalizeGarbageCollectedObject is called when the object is freed from
-  // the heap.  By default finalization means calling the destructor on the
-  // object.  finalizeGarbageCollectedObject can be overridden to support
-  // calling the destructor of a subclass.  This is useful for objects without
-  // vtables that require explicit dispatching.  The name is intentionally a
-  // bit long to make name conflicts less likely.
-  void FinalizeGarbageCollectedObject() { static_cast<T*>(this)->~T(); }
-
   GarbageCollectedFinalized() = default;
-  ~GarbageCollectedFinalized() = default;
-
-  template <typename U>
-  friend struct HasFinalizer;
-  template <typename U, bool>
-  friend struct FinalizerTraitImpl;
 
   DISALLOW_COPY_AND_ASSIGN(GarbageCollectedFinalized);
 };
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h
index e499332..cca081283 100644
--- a/third_party/blink/renderer/platform/heap/heap.h
+++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -36,6 +36,7 @@
 
 #include "base/macros.h"
 #include "build/build_config.h"
+#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
 #include "third_party/blink/renderer/platform/heap/gc_info.h"
 #include "third_party/blink/renderer/platform/heap/heap_page.h"
 #include "third_party/blink/renderer/platform/heap/process_heap.h"
@@ -172,6 +173,14 @@
   }
 };
 
+template <typename T, typename = int>
+struct IsGarbageCollectedContainer : std::false_type {};
+
+template <typename T>
+struct IsGarbageCollectedContainer<
+    T,
+    typename T::IsGarbageCollectedCollectionTypeMarker> : std::true_type {};
+
 }  // namespace internal
 
 class PLATFORM_EXPORT ThreadHeap {
@@ -533,6 +542,13 @@
 T* MakeGarbageCollected(Args&&... args) {
   static_assert(WTF::IsGarbageCollectedType<T>::value,
                 "T needs to be a garbage collected object");
+  static_assert(std::is_trivially_destructible<T>::value ||
+                    std::has_virtual_destructor<T>::value ||
+                    std::is_final<T>::value ||
+                    internal::IsGarbageCollectedContainer<T>::value ||
+                    internal::HasFinalizeGarbageCollectedObject<T>::value,
+                "Finalized GarbageCollected class should either have a virtual "
+                "destructor or be marked as final.");
   void* memory = T::AllocateObject(sizeof(T));
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
   // Placement new as regular operator new() is deleted.
@@ -553,6 +569,13 @@
 T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
   static_assert(WTF::IsGarbageCollectedType<T>::value,
                 "T needs to be a garbage collected object");
+  static_assert(std::is_trivially_destructible<T>::value ||
+                    std::has_virtual_destructor<T>::value ||
+                    std::is_final<T>::value ||
+                    internal::IsGarbageCollectedContainer<T>::value ||
+                    internal::HasFinalizeGarbageCollectedObject<T>::value,
+                "Finalized GarbageCollected class should either have a virtual "
+                "destructor or be marked as final.");
   void* memory = T::AllocateObject(sizeof(T) + additional_bytes.value);
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
   // Placement new as regular operator new() is deleted.
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator.h b/third_party/blink/renderer/platform/heap/heap_allocator.h
index 53c4111..ba1dab6 100644
--- a/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -491,7 +491,7 @@
                                    KeyTraitsArg,
                                    MappedTraitsArg,
                                    HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
@@ -524,7 +524,7 @@
           typename TraitsArg = HashTraits<ValueArg>>
 class HeapHashSet
     : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
@@ -552,7 +552,7 @@
           typename TraitsArg = HashTraits<ValueArg>>
 class HeapLinkedHashSet
     : public LinkedHashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
   // HeapLinkedHashSet is using custom callbacks for compaction that rely on the
   // fact that the container itself does not move.
@@ -586,7 +586,7 @@
                          inlineCapacity,
                          HashArg,
                          HeapListHashSetAllocator<ValueArg, inlineCapacity>> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
@@ -614,7 +614,7 @@
           typename Traits = HashTraits<Value>>
 class HeapHashCountedSet
     : public HashCountedSet<Value, HashFunctions, Traits, HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
@@ -639,7 +639,7 @@
 
 template <typename T, wtf_size_t inlineCapacity = 0>
 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
@@ -690,7 +690,7 @@
 
 template <typename T, wtf_size_t inlineCapacity = 0>
 class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
-  IS_GARBAGE_COLLECTED_TYPE();
+  IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
   DISALLOW_NEW();
 
   static void CheckType() {
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index 929525f..f57d2729 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -690,7 +690,8 @@
     Persistent<PersistentChain> persistent_chain_;
   };
 
-  class PersistentChain : public GarbageCollectedFinalized<PersistentChain> {
+  class PersistentChain final
+      : public GarbageCollectedFinalized<PersistentChain> {
    public:
     explicit PersistentChain(int count) {
       ref_counted_chain_ = base::AdoptRef(RefCountedChain::Create(count));
@@ -721,7 +722,7 @@
   EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
 }
 
-class TraceCounter : public GarbageCollectedFinalized<TraceCounter> {
+class TraceCounter final : public GarbageCollectedFinalized<TraceCounter> {
  public:
   TraceCounter() : trace_count_(0) {}
 
@@ -755,7 +756,7 @@
   Member<TraceCounter> trace_counter_;
 };
 
-class SimpleFinalizedObject
+class SimpleFinalizedObject final
     : public GarbageCollectedFinalized<SimpleFinalizedObject> {
  public:
   SimpleFinalizedObject() = default;
@@ -887,7 +888,8 @@
   Member<IntWrapper> int_wrapper_;
 };
 
-class LargeHeapObject : public GarbageCollectedFinalized<LargeHeapObject> {
+class LargeHeapObject final
+    : public GarbageCollectedFinalized<LargeHeapObject> {
  public:
   LargeHeapObject() { int_wrapper_ = MakeGarbageCollected<IntWrapper>(23); }
   ~LargeHeapObject() { destructor_calls_++; }
@@ -917,7 +919,7 @@
 // "keep alive" persistent reference that is set & cleared across
 // ref-counting operations.
 //
-class RefCountedAndGarbageCollected
+class RefCountedAndGarbageCollected final
     : public GarbageCollectedFinalized<RefCountedAndGarbageCollected> {
  public:
   RefCountedAndGarbageCollected() : keep_alive_(PERSISTENT_FROM_HERE) {}
@@ -951,7 +953,7 @@
 
 int RefCountedAndGarbageCollected::destructor_calls_ = 0;
 
-class RefCountedAndGarbageCollected2
+class RefCountedAndGarbageCollected2 final
     : public HeapTestOtherSuperClass,
       public GarbageCollectedFinalized<RefCountedAndGarbageCollected2> {
  public:
@@ -1027,7 +1029,7 @@
   WeakMember<Bar> weak_bar_;
 };
 
-class Observable : public GarbageCollectedFinalized<Observable> {
+class Observable final : public GarbageCollectedFinalized<Observable> {
   USING_PRE_FINALIZER(Observable, WillFinalize);
 
  public:
@@ -1051,7 +1053,7 @@
 
 bool Observable::will_finalize_was_called_ = false;
 
-class ObservableWithPreFinalizer
+class ObservableWithPreFinalizer final
     : public GarbageCollectedFinalized<ObservableWithPreFinalizer> {
   USING_PRE_FINALIZER(ObservableWithPreFinalizer, Dispose);
 
@@ -1210,7 +1212,7 @@
 
 class SuperClass;
 
-class PointsBack : public GarbageCollectedFinalized<PointsBack> {
+class PointsBack final : public GarbageCollectedFinalized<PointsBack> {
  public:
   PointsBack() : back_pointer_(nullptr) { ++alive_count_; }
   ~PointsBack() { --alive_count_; }
@@ -1258,7 +1260,7 @@
 };
 
 int SuperClass::alive_count_ = 0;
-class SubData : public GarbageCollectedFinalized<SubData> {
+class SubData final : public GarbageCollectedFinalized<SubData> {
  public:
   SubData() { ++alive_count_; }
   ~SubData() { --alive_count_; }
@@ -1377,7 +1379,8 @@
 
 namespace blink {
 
-class OneKiloByteObject : public GarbageCollectedFinalized<OneKiloByteObject> {
+class OneKiloByteObject final
+    : public GarbageCollectedFinalized<OneKiloByteObject> {
  public:
   ~OneKiloByteObject() { destructor_calls_++; }
   char* Data() { return data_; }
@@ -1408,7 +1411,7 @@
   DynamicallySizedObject() = default;
 };
 
-class FinalizationAllocator
+class FinalizationAllocator final
     : public GarbageCollectedFinalized<FinalizationAllocator> {
  public:
   FinalizationAllocator(Persistent<IntWrapper>* wrapper) : wrapper_(wrapper) {}
@@ -1428,7 +1431,7 @@
   Persistent<IntWrapper>* wrapper_;
 };
 
-class PreFinalizerBackingShrinkForbidden
+class PreFinalizerBackingShrinkForbidden final
     : public GarbageCollectedFinalized<PreFinalizerBackingShrinkForbidden> {
   USING_PRE_FINALIZER(PreFinalizerBackingShrinkForbidden, Dispose);
 
@@ -1485,7 +1488,7 @@
   PreciselyCollectGarbage();
 }
 
-class PreFinalizerVectorBackingExpandForbidden
+class PreFinalizerVectorBackingExpandForbidden final
     : public GarbageCollectedFinalized<
           PreFinalizerVectorBackingExpandForbidden> {
   USING_PRE_FINALIZER(PreFinalizerVectorBackingExpandForbidden, Dispose);
@@ -1515,7 +1518,7 @@
   TestSupportingGC::PreciselyCollectGarbage();
 }
 
-class PreFinalizerHashTableBackingExpandForbidden
+class PreFinalizerHashTableBackingExpandForbidden final
     : public GarbageCollectedFinalized<
           PreFinalizerHashTableBackingExpandForbidden> {
   USING_PRE_FINALIZER(PreFinalizerHashTableBackingExpandForbidden, Dispose);
@@ -2369,7 +2372,7 @@
 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
 typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak;
 
-class Container : public GarbageCollected<Container> {
+class Container final : public GarbageCollected<Container> {
  public:
   HeapHashMap<Member<IntWrapper>, Member<IntWrapper>> map;
   HeapHashSet<Member<IntWrapper>> set;
@@ -5318,7 +5321,7 @@
 }
 
 template <typename T>
-class TraceIfNeededTester
+class TraceIfNeededTester final
     : public GarbageCollectedFinalized<TraceIfNeededTester<T>> {
  public:
   TraceIfNeededTester() = default;
@@ -5492,7 +5495,7 @@
   ThreadState::Current()->CollectAllGarbageForTesting();
 }
 
-class NonNodeAllocatingNodeInDestructor
+class NonNodeAllocatingNodeInDestructor final
     : public GarbageCollectedFinalized<NonNodeAllocatingNodeInDestructor> {
  public:
   ~NonNodeAllocatingNodeInDestructor() {
@@ -6065,7 +6068,8 @@
   PreciselyCollectGarbage();
 }
 
-struct HeapHashMapWrapper : GarbageCollectedFinalized<HeapHashMapWrapper> {
+struct HeapHashMapWrapper final
+    : GarbageCollectedFinalized<HeapHashMapWrapper> {
   HeapHashMapWrapper() {
     for (int i = 0; i < 100; ++i) {
       map_.insert(MakeGarbageCollected<IntWrapper>(i),
diff --git a/third_party/blink/renderer/platform/heap/heap_thread_test.cc b/third_party/blink/renderer/platform/heap/heap_thread_test.cc
index 0eeb71c..0d411f4 100644
--- a/third_party/blink/renderer/platform/heap/heap_thread_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_thread_test.cc
@@ -69,7 +69,6 @@
 class Object : public GarbageCollected<Object> {
  public:
   Object() {}
-  ~Object() {}
   void Trace(blink::Visitor* visitor) {}
 };
 
@@ -171,7 +170,8 @@
 
 class MarkingSameThreadCheckTester : public AlternatingThreadTester {
  private:
-  class MainThreadObject : public GarbageCollectedFinalized<MainThreadObject> {
+  class MainThreadObject final
+      : public GarbageCollectedFinalized<MainThreadObject> {
    public:
     void Trace(blink::Visitor* visitor) { visitor->Trace(set_); }
     void AddToSet(Object* object) { set_.insert(42, object); }
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
index 0e682e5..caae9d9 100644
--- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -1930,7 +1930,7 @@
   driver.FinishGC();
 }
 
-class Destructed : public GarbageCollectedFinalized<Destructed> {
+class Destructed final : public GarbageCollectedFinalized<Destructed> {
  public:
   ~Destructed() { n_destructed++; }
 
@@ -1941,7 +1941,7 @@
 
 size_t Destructed::n_destructed = 0;
 
-class Wrapper : public GarbageCollectedFinalized<Wrapper> {
+class Wrapper final : public GarbageCollectedFinalized<Wrapper> {
  public:
   using HashType = HeapLinkedHashSet<Member<Destructed>>;
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 38087a07..c9de5d29 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -570,7 +570,8 @@
       auto_load_images_(true),
       images_enabled_(true),
       allow_stale_resources_(false),
-      image_fetched_(false) {
+      image_fetched_(false),
+      should_log_request_as_invalid_in_imported_document_(false) {
   stale_while_revalidate_enabled_ =
       RuntimeEnabledFeatures::StaleWhileRevalidateEnabledByRuntimeFlag();
   InstanceCounters::IncrementCounter(InstanceCounters::kResourceFetcherCounter);
@@ -944,6 +945,13 @@
                                            ResourceClient* client) {
   base::AutoReset<bool> r(&is_in_request_resource_, true);
 
+  if (should_log_request_as_invalid_in_imported_document_) {
+    DCHECK(properties_->IsDetached());
+    // We don't expect the fetcher to be used, so count such unexpected use.
+    UMA_HISTOGRAM_ENUMERATION("HTMLImport.UnexpectedRequest",
+                              factory.GetType());
+  }
+
   // If detached, we do very early return here to skip all processing below.
   if (properties_->IsDetached()) {
     return ResourceForBlockedRequest(
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 3525e71..dfbd91bf 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -126,6 +126,7 @@
   }
   // This must be called right after construction.
   void SetResourceLoadObserver(ResourceLoadObserver* observer) {
+    DCHECK(!IsDetached());
     DCHECK(!resource_load_observer_);
     resource_load_observer_ = observer;
   }
@@ -265,6 +266,10 @@
                                speculative_preload_type, is_link_preload);
   }
 
+  void SetShouldLogRequestAsInvalidInImportedDocument() {
+    should_log_request_as_invalid_in_imported_document_ = true;
+  }
+
  private:
   friend class ResourceCacheValidationSuppressor;
   enum class StopFetchingTarget {
@@ -413,12 +418,14 @@
   // This is not in the bit field below because we want to use AutoReset.
   bool is_in_request_resource_ = false;
 
-  // 27 bits left
+  // 26 bits left
   bool auto_load_images_ : 1;
   bool images_enabled_ : 1;
   bool allow_stale_resources_ : 1;
   bool image_fetched_ : 1;
   bool stale_while_revalidate_enabled_ : 1;
+  // for https://crbug.com/961614
+  bool should_log_request_as_invalid_in_imported_document_ : 1;
 
   static constexpr uint32_t kKeepaliveInflightBytesQuota = 64 * 1024;
 
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc b/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
index 2e63321..25ce7e4c 100644
--- a/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
+++ b/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
@@ -91,7 +91,7 @@
 
 // This class is a limited MIME parser used to parse the MIME headers of MHTML
 // files.
-class MIMEHeader : public GarbageCollectedFinalized<MIMEHeader> {
+class MIMEHeader final : public GarbageCollectedFinalized<MIMEHeader> {
  public:
   MIMEHeader();
 
diff --git a/third_party/blink/renderer/platform/p2p/DEPS b/third_party/blink/renderer/platform/p2p/DEPS
new file mode 100644
index 0000000..51f66cb
--- /dev/null
+++ b/third_party/blink/renderer/platform/p2p/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+    "+media/base/media_permission.h",
+    "+jingle/glue/utils.h",
+    "+net/base/ip_address.h",
+    "+net/base/network_change_notifier.h",
+    "+net/base/network_interfaces.h",
+]
diff --git a/content/renderer/p2p/empty_network_manager.cc b/third_party/blink/renderer/platform/p2p/empty_network_manager.cc
similarity index 78%
rename from content/renderer/p2p/empty_network_manager.cc
rename to third_party/blink/renderer/platform/p2p/empty_network_manager.cc
index 121b518..9422a0d64 100644
--- a/content/renderer/p2p/empty_network_manager.cc
+++ b/third_party/blink/renderer/platform/p2p/empty_network_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/p2p/empty_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/empty_network_manager.h"
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -10,36 +10,36 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "third_party/blink/public/platform/modules/p2p/network_manager_uma.h"
 
-namespace content {
+namespace blink {
 
 EmptyNetworkManager::EmptyNetworkManager(rtc::NetworkManager* network_manager)
     : network_manager_(network_manager) {
   DCHECK(network_manager);
-  thread_checker_.DetachFromThread();
+  DETACH_FROM_THREAD(thread_checker_);
   set_enumeration_permission(ENUMERATION_BLOCKED);
   network_manager_->SignalNetworksChanged.connect(
       this, &EmptyNetworkManager::OnNetworksChanged);
 }
 
 EmptyNetworkManager::~EmptyNetworkManager() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void EmptyNetworkManager::StartUpdating() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   ++start_count_;
   network_manager_->StartUpdating();
 }
 
 void EmptyNetworkManager::StopUpdating() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   network_manager_->StopUpdating();
   --start_count_;
   DCHECK_GE(start_count_, 0);
 }
 
 void EmptyNetworkManager::GetNetworks(NetworkList* networks) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   networks->clear();
 }
 
@@ -50,7 +50,7 @@
 }
 
 void EmptyNetworkManager::OnNetworksChanged() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (!start_count_)
     return;
@@ -62,4 +62,4 @@
   SignalNetworksChanged();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/p2p/filtering_network_manager.cc b/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
similarity index 91%
rename from content/renderer/p2p/filtering_network_manager.cc
rename to third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
index 4dead8a..71efbae 100644
--- a/content/renderer/p2p/filtering_network_manager.cc
+++ b/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/p2p/filtering_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/filtering_network_manager.h"
 
 #include <utility>
 
@@ -12,7 +12,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/base/media_permission.h"
 
-namespace content {
+namespace blink {
 
 FilteringNetworkManager::FilteringNetworkManager(
     rtc::NetworkManager* network_manager,
@@ -21,7 +21,7 @@
     : network_manager_(network_manager),
       media_permission_(media_permission),
       requesting_origin_(requesting_origin) {
-  thread_checker_.DetachFromThread();
+  DETACH_FROM_THREAD(thread_checker_);
   set_enumeration_permission(ENUMERATION_BLOCKED);
 
   // If the feature is not enabled, just return ALLOWED as it's requested.
@@ -34,7 +34,7 @@
 }
 
 FilteringNetworkManager::~FilteringNetworkManager() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // This helps to catch the case if permission never comes back.
   if (!start_updating_time_.is_null())
     ReportMetrics(false);
@@ -51,7 +51,7 @@
 }
 
 void FilteringNetworkManager::StartUpdating() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(started_permission_check_);
 
   if (start_updating_time_.is_null()) {
@@ -75,14 +75,14 @@
 }
 
 void FilteringNetworkManager::StopUpdating() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   network_manager_->StopUpdating();
   DCHECK_GT(start_count_, 0);
   --start_count_;
 }
 
 void FilteringNetworkManager::GetNetworks(NetworkList* networks) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   networks->clear();
 
   if (enumeration_permission() == ENUMERATION_ALLOWED)
@@ -93,7 +93,7 @@
 
 webrtc::MdnsResponderInterface* FilteringNetworkManager::GetMdnsResponder()
     const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (enumeration_permission() == ENUMERATION_ALLOWED)
     return nullptr;
@@ -102,7 +102,7 @@
 }
 
 void FilteringNetworkManager::CheckPermission() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!started_permission_check_);
 
   started_permission_check_ = true;
@@ -121,7 +121,7 @@
 }
 
 void FilteringNetworkManager::OnPermissionStatus(bool granted) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_GT(pending_permission_checks_, 0);
   VLOG(1) << "FilteringNetworkManager received permission status: "
           << (granted ? "granted" : "denied");
@@ -139,7 +139,7 @@
 }
 
 void FilteringNetworkManager::OnNetworksChanged() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   pending_network_update_ = false;
 
   // Update the default local addresses.
@@ -202,6 +202,8 @@
     ReportMetrics(true);
 
   // Post a task to avoid reentrancy.
+  //
+  // TODO(crbug.com/787254): Use Frame-based TaskRunner here.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::BindOnce(&FilteringNetworkManager::SendNetworksChangedSignal,
@@ -214,4 +216,4 @@
   SignalNetworksChanged();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/p2p/filtering_network_manager_unittest.cc b/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
similarity index 97%
rename from content/renderer/p2p/filtering_network_manager_unittest.cc
rename to third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
index 9888bd5..0732a2b 100644
--- a/content/renderer/p2p/filtering_network_manager_unittest.cc
+++ b/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/p2p/filtering_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/filtering_network_manager.h"
 
 #include <stddef.h>
 
@@ -15,10 +15,10 @@
 #include "base/stl_util.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/p2p/empty_network_manager.h"
 #include "media/base/media_permission.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/p2p/empty_network_manager.h"
 #include "third_party/webrtc/rtc_base/ip_address.h"
 
 using NetworkList = rtc::NetworkManager::NetworkList;
@@ -147,7 +147,7 @@
 
 }  // namespace
 
-namespace content {
+namespace blink {
 
 class FilteringNetworkManagerTest : public testing::Test,
                                     public sigslot::has_slots<> {
@@ -174,8 +174,8 @@
           base_network_manager_.get(), GURL(), media_permission_.get());
       network_manager_->Initialize();
     } else {
-      network_manager_ =
-          std::make_unique<EmptyNetworkManager>(base_network_manager_.get());
+      network_manager_ = std::make_unique<blink::EmptyNetworkManager>(
+          base_network_manager_.get());
     }
     network_manager_->SignalNetworksChanged.connect(
         this, &FilteringNetworkManagerTest::OnNetworksChanged);
@@ -487,4 +487,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/p2p/ipc_network_manager.cc b/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
similarity index 90%
rename from content/renderer/p2p/ipc_network_manager.cc
rename to third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
index 9d3b263c..52d7d120 100644
--- a/content/renderer/p2p/ipc_network_manager.cc
+++ b/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
@@ -2,26 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/p2p/ipc_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/ipc_network_manager.h"
 
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "base/bind.h"
-#include "base/command_line.h"
 #include "base/location.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/sys_byteorder.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "content/public/common/content_switches.h"
 #include "jingle/glue/utils.h"
 #include "net/base/ip_address.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_interfaces.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/webrtc/rtc_base/socket_address.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
@@ -29,24 +29,24 @@
     net::NetworkChangeNotifier::ConnectionType type) {
   switch (type) {
     case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
-        return rtc::ADAPTER_TYPE_UNKNOWN;
+      return rtc::ADAPTER_TYPE_UNKNOWN;
     case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
-        return rtc::ADAPTER_TYPE_ETHERNET;
+      return rtc::ADAPTER_TYPE_ETHERNET;
     case net::NetworkChangeNotifier::CONNECTION_WIFI:
-        return rtc::ADAPTER_TYPE_WIFI;
+      return rtc::ADAPTER_TYPE_WIFI;
     case net::NetworkChangeNotifier::CONNECTION_2G:
     case net::NetworkChangeNotifier::CONNECTION_3G:
     case net::NetworkChangeNotifier::CONNECTION_4G:
-        return rtc::ADAPTER_TYPE_CELLULAR;
+      return rtc::ADAPTER_TYPE_CELLULAR;
     default:
-        return rtc::ADAPTER_TYPE_UNKNOWN;
+      return rtc::ADAPTER_TYPE_UNKNOWN;
   }
 }
 
 }  // namespace
 
 IpcNetworkManager::IpcNetworkManager(
-    NetworkListManager* network_list_manager,
+    blink::NetworkListManager* network_list_manager,
     std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder)
     : network_list_manager_(network_list_manager),
       mdns_responder_(std::move(mdns_responder)) {
@@ -148,12 +148,11 @@
   }
   set_default_local_addresses(ipv4_default, ipv6_default);
 
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAllowLoopbackInPeerConnection)) {
+  if (Platform::Current()->AllowsLoopbackInPeerConnection()) {
     std::string name_v4("loopback_ipv4");
     rtc::IPAddress ip_address_v4(INADDR_LOOPBACK);
-    rtc::Network* network_v4 = new rtc::Network(
-        name_v4, name_v4, ip_address_v4, 32, rtc::ADAPTER_TYPE_UNKNOWN);
+    rtc::Network* network_v4 = new rtc::Network(name_v4, name_v4, ip_address_v4,
+                                                32, rtc::ADAPTER_TYPE_UNKNOWN);
     network_v4->set_default_local_address_provider(this);
     network_v4->set_mdns_responder_provider(this);
     network_v4->AddIP(ip_address_v4);
@@ -197,4 +196,4 @@
   SignalNetworksChanged();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/p2p/ipc_network_manager_unittest.cc b/third_party/blink/renderer/platform/p2p/ipc_network_manager_test.cc
similarity index 94%
rename from content/renderer/p2p/ipc_network_manager_unittest.cc
rename to third_party/blink/renderer/platform/p2p/ipc_network_manager_test.cc
index e85e4b9..152dd782 100644
--- a/content/renderer/p2p/ipc_network_manager_unittest.cc
+++ b/third_party/blink/renderer/platform/p2p/ipc_network_manager_test.cc
@@ -2,29 +2,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/p2p/ipc_network_manager.h"
+#include "third_party/blink/public/platform/modules/p2p/ipc_network_manager.h"
 
 #include <algorithm>
 #include <memory>
 
-#include "content/renderer/p2p/network_list_manager.h"
 #include "net/base/ip_address.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_interfaces.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/p2p/network_list_manager.h"
 #include "third_party/webrtc/rtc_base/mdns_responder_interface.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
-class MockP2PSocketDispatcher : public NetworkListManager {
+class MockP2PSocketDispatcher : public blink::NetworkListManager {
  public:
   void AddNetworkListObserver(
-      NetworkListObserver* network_list_observer) override {}
+      blink::NetworkListObserver* network_list_observer) override {}
 
   void RemoveNetworkListObserver(
-      NetworkListObserver* network_list_observer) override {}
+      blink::NetworkListObserver* network_list_observer) override {}
 
   ~MockP2PSocketDispatcher() override {}
 };
@@ -198,4 +198,4 @@
   EXPECT_EQ(mdns_responder, networks[1]->GetMdnsResponder());
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/DEPS b/third_party/blink/renderer/platform/peerconnection/DEPS
index e64c7ff..c422df2 100644
--- a/third_party/blink/renderer/platform/peerconnection/DEPS
+++ b/third_party/blink/renderer/platform/peerconnection/DEPS
@@ -8,6 +8,8 @@
     "+third_party/blink/renderer/platform/webrtc",
 
     # Dependencies.
+    "+base/strings/string_number_conversions.h",
+    "+base/strings/string_split.h",
     "+base/threading/thread_restrictions.h",
     "+media/base",
     "+media/media_buildflags.h",
diff --git a/content/renderer/media/webrtc/stun_field_trial.cc b/third_party/blink/renderer/platform/peerconnection/stun_field_trial.cc
similarity index 93%
rename from content/renderer/media/webrtc/stun_field_trial.cc
rename to third_party/blink/renderer/platform/peerconnection/stun_field_trial.cc
index 183d8e8..738ddd5 100644
--- a/content/renderer/media/webrtc/stun_field_trial.cc
+++ b/third_party/blink/renderer/platform/peerconnection/stun_field_trial.cc
@@ -2,12 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/stun_field_trial.h"
+#include "third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h"
 
 #include <math.h>
 
-#include "base/bind.h"
-#include "base/location.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
@@ -26,7 +24,7 @@
 
 using stunprober::StunProber;
 
-namespace content {
+namespace blink {
 
 namespace {
 
@@ -40,8 +38,8 @@
 };
 
 // This needs to match "NatType" in histograms.xml.
-const char* const NatTypeNames[] =
-    {"NoNAT", "UnknownNAT", "SymNAT", "NonSymNAT"};
+const char* const NatTypeNames[] = {"NoNAT", "UnknownNAT", "SymNAT",
+                                    "NonSymNAT"};
 static_assert(base::size(NatTypeNames) == NAT_TYPE_MAX,
               "NatType enums must match names");
 
@@ -91,7 +89,7 @@
 StunProberTrial::~StunProberTrial() {}
 
 void StunProberTrial::SaveHistogramData() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   NatType nat_type = NAT_TYPE_UNKNOWN;
   int interval_ms = 0;
   int count = 0;
@@ -238,7 +236,7 @@
 }
 
 void StunProberTrial::OnNetworksChanged() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DVLOG(1) << "Starting stun trial with params: " << param_line_;
   rtc::NetworkManager::NetworkList networks;
   network_manager_->GetNetworks(&networks);
@@ -277,7 +275,7 @@
 
 void StunProberTrial::OnFinished(StunProber* prober,
                                  StunProber::Status result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (result == StunProber::SUCCESS)
     ++finished_probers_;
 
@@ -287,7 +285,7 @@
 
 void StunProberTrial::OnPrepared(StunProber* prober,
                                  StunProber::Status result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (result == StunProber::SUCCESS)
     ++ready_probers_;
 
@@ -295,14 +293,15 @@
     // TODO(guoweis) estimated_execution_time() is the same for all probers. It
     // could be moved up to the StunProberTrial class once the DNS resolution
     // part is moved up too.
-    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
-                                probers_.front()->estimated_execution_time()),
+    timer_.Start(FROM_HERE,
+                 base::TimeDelta::FromMilliseconds(
+                     probers_.front()->estimated_execution_time()),
                  this, &StunProberTrial::OnTimer);
   }
 }
 
 void StunProberTrial::OnTimer() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   probers_[started_probers_]->Start(this);
   started_probers_++;
 
@@ -310,4 +309,4 @@
     timer_.Stop();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/webrtc/stun_field_trial_unittest.cc b/third_party/blink/renderer/platform/peerconnection/stun_field_trial_test.cc
similarity index 90%
rename from content/renderer/media/webrtc/stun_field_trial_unittest.cc
rename to third_party/blink/renderer/platform/peerconnection/stun_field_trial_test.cc
index 67c3962a..719c30e7 100644
--- a/content/renderer/media/webrtc/stun_field_trial_unittest.cc
+++ b/third_party/blink/renderer/platform/peerconnection/stun_field_trial_test.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/stun_field_trial.h"
+#include "third_party/blink/public/platform/modules/peerconnection/stun_field_trial.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/webrtc/rtc_base/socket_address.h"
 
-namespace content {
+namespace blink {
 
 TEST(StunProbeTrial, VerifyParameterParsing) {
   StunProberTrial::Param params;
@@ -38,4 +38,4 @@
   EXPECT_FALSE(StunProberTrial::ParseParameters(param_line, &params));
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/allocator/allocator.h b/third_party/blink/renderer/platform/wtf/allocator/allocator.h
index bb5e450..709c28b 100644
--- a/third_party/blink/renderer/platform/wtf/allocator/allocator.h
+++ b/third_party/blink/renderer/platform/wtf/allocator/allocator.h
@@ -60,6 +60,15 @@
  private:                                   \
   friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
 
+#define IS_GARBAGE_COLLECTED_CONTAINER_TYPE()         \
+  IS_GARBAGE_COLLECTED_TYPE();                        \
+                                                      \
+ public:                                              \
+  using IsGarbageCollectedCollectionTypeMarker = int; \
+                                                      \
+ private:                                             \
+  friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
+
 #if defined(__clang__)
 #define ANNOTATE_STACK_ALLOCATED \
   __attribute__((annotate("blink_stack_allocated")))
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-features=OutOfBlinkCors b/third_party/blink/web_tests/FlagExpectations/enable-features=OutOfBlinkCors
index dc21015..4c1966a 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-features=OutOfBlinkCors
+++ b/third_party/blink/web_tests/FlagExpectations/enable-features=OutOfBlinkCors
@@ -23,3 +23,12 @@
 crbug.com/870173 virtual/omt-worker-fetch/external/wpt/resource-timing/cors-preflight.any.html [ Pass ]
 crbug.com/870173 virtual/omt-worker-fetch/external/wpt/resource-timing/cors-preflight.any.worker.html [ Pass ]
 crbug.com/870173 virtual/omt-worker-fetch/http/tests/workers/worker-redirect.html [ Pass ]
+
+# The fetch-request-xhr.https.html fails on some checks, but has an expectation
+# file to ignore text diffs. It also fails on the same checks even with
+# OOR-CORS, but with different texts. Just mark them as Failure.
+crbug.com/870173 external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ]
+crbug.com/870173 virtual/cache-storage-parallel/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ]
+crbug.com/870173 virtual/cache-storage-sequence/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ]
+crbug.com/870173 virtual/omt-service-worker-startup/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ]
+crbug.com/870173 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index f516a69..0833848b 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3214,6 +3214,8 @@
 crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-underline-001.html [ Failure ]
 crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-vertical-002.html [ Failure ]
 
+crbug.com/1002514 external/wpt/web-share/share-sharePromise-internal-slot.https.html [ Failure Crash ]
+
 # ====== New tests from wpt-importer added here ======
 crbug.com/626703 [ Win7 ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.10 ] virtual/omt-worker-fetch/external/wpt/resource-timing/resource_timing_buffer_full_eventually.html [ Timeout ]
@@ -6207,9 +6209,6 @@
 crbug.com/1000768 [ Linux ] external/wpt/web-share/idlharness.https.window.html [ Pass Failure ]
 crbug.com/1000768 [ Linux ] external/wpt/storage/idlharness.https.any.html [ Pass Failure ]
 
-# Partial fix to avoid a regression on eval(string) with Trusted Types enabled in Chrome 77.
-crbug.com/992424 external/wpt/trusted-types/block-eval.tentative.html [ Failure ]
-
 # Sheriff 2019-09-06
 crbug.com/998399 [ Linux ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https.html [ Pass Timeout ]
 
@@ -6218,3 +6217,6 @@
 crbug.com/1001816 external/wpt/css/css-masking/clip-path/clip-path-inline-003.html [ Pass Failure ]
 crbug.com/1001814 external/wpt/css/css-masking/clip-path/clip-path-inline-002.html [ Pass Failure ]
 crbug.com/1001936 external/wpt/css/css-masking/clip-path/clip-path-inline-001.html [ Pass Failure ]
+
+# Sheriff 2019-09-10
+crbug.com/1002527 [ Debug ] fast/text/large-text-composed-char.html [ Pass Crash ]
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations
index 0b122d3..2d51ecd 100644
--- a/third_party/blink/web_tests/WebDriverExpectations
+++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -178,3 +178,6 @@
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/default_values.py>>test_desired [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+
+# Sheriff 2019-09-10
+crbug.com/1000734 [ Linux ] external/wpt/webdriver/tests/take_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/inherit-overwrites.html b/third_party/blink/web_tests/external/wpt/css/css-lists/inherit-overwrites.html
new file mode 100644
index 0000000..d1f8072
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/inherit-overwrites.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Inheritance replaces existing value of counter properties</title>
+<link rel="help" href="https://drafts.csswg.org/css-lists/#property-index">
+<meta name="assert" content="Inheritance replaces existing value of counter properties.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #container {
+    counter-reset: first 1;
+    counter-increment: second 2;
+    counter-set: third 3;
+  }
+  .target {
+    counter-reset: fourth 4;
+    counter-increment: fifth 5;
+    counter-set: sixth 6;
+  }
+</style>
+</head>
+<body>
+<div id="container">
+  <div id="target"></div>
+</div>
+<script>
+'use strict';
+const container = document.getElementById('container');
+
+// 'counter-set' can be added.
+for (let property of ['counter-reset', 'counter-increment']) {
+  test(() => {
+    const target = document.createElement('div');
+    target.classList += 'target';
+    container.appendChild(target);
+    target.style[property] = 'inherit';
+    assert_equals(getComputedStyle(target)[property], getComputedStyle(container)[property]);
+  }, 'Inheritance of ' + property + ' replaces existing value');
+}
+
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-computed.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-computed.html
new file mode 100644
index 0000000..fc9ddb3d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-computed.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Motion Path Module Level 1: getComputedStyle().offsetAnchor</title>
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-anchor-property">
+<meta name="assert" content="offset-anchor is 'auto' or a computed position.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<style>
+  #target {
+    font-size: 40px;
+  }
+</style>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("offset-anchor", "auto");
+
+test_computed_value("offset-anchor", "left bottom", "0% 100%");
+test_computed_value("offset-anchor", "center center", "50% 50%");
+test_computed_value("offset-anchor", "right center", "100% 50%");
+test_computed_value("offset-anchor", "center top", "50% 0%");
+test_computed_value("offset-anchor", "center bottom", "50% 100%");
+test_computed_value("offset-anchor", "calc(20% - 5em) center", "calc(20% - 200px) 50%");
+test_computed_value("offset-anchor", "right 4em", "100% 160px");
+test_computed_value("offset-anchor", "10px 20%");
+test_computed_value("offset-anchor", "left -10px top -20%", "-10px -20%");
+test_computed_value("offset-anchor", "right 10% bottom 20em", "90% calc(100% - 800px)");
+test_computed_value("offset-anchor", "top 10px right -20%", "120% 10px");
+test_computed_value("offset-anchor", "left 10% bottom 20em", "10% calc(100% - 800px)");
+test_computed_value('offset-anchor', 'calc(10px - 0.5em) calc(10px + 0.5em)', '-10px 30px');
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-distance-computed.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-distance-computed.html
new file mode 100644
index 0000000..e9de1ef2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-distance-computed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Motion Path Module Level 1: getComputedStyle().offsetDistance</title>
+<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-distance-property">
+<meta name="assert" content="offset-distance is a computed '<length-percentage>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<style>
+  #target {
+    font-size: 40px;
+  }
+</style>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("offset-distance", "10px");
+test_computed_value("offset-distance", "20%");
+test_computed_value("offset-distance", "calc(40% - 30px)");
+test_computed_value("offset-distance", "0", "0px");
+test_computed_value('offset-distance', 'calc(10px - 0.5em)', '-10px');
+test_computed_value('offset-distance', 'calc(10px + 0.5em)', '30px');
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed-expected.txt
new file mode 100644
index 0000000..6138a7e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS Property offset-path value 'none' computes to 'none'
+PASS Property offset-path value 'ray(0rad closest-side)' computes to 'ray(0deg closest-side)'
+PASS Property offset-path value 'ray(0.25turn closest-corner contain)' computes to 'ray(90deg closest-corner contain)'
+PASS Property offset-path value 'ray(200grad farthest-side)' computes to 'ray(180deg farthest-side)'
+PASS Property offset-path value 'ray(270deg farthest-corner contain)' computes to 'ray(270deg farthest-corner contain)'
+PASS Property offset-path value 'ray(-720deg sides)' computes to 'ray(-720deg sides)'
+FAIL Property offset-path value 'ray(calc(180deg - 45deg) farthest-side)' computes to 'ray(calc(135deg) farthest-side)' assert_equals: expected "ray(calc(135deg) farthest-side)" but got "ray(135deg farthest-side)"
+PASS Property offset-path value 'path("m 20 0 h -100")' computes to 'path("M 20 0 H -80")'
+PASS Property offset-path value 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z")' computes to 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z")'
+PASS Property offset-path value 'path("m 10 20 q 30 60 40 50 q 100 70 90 80")' computes to 'path("M 10 20 Q 40 80 50 70 Q 150 140 140 150")'
+PASS Property offset-path value 'path("M 0 0 L 100 100 m 0 100 l 100 0 Z l 160 20 Z")' computes to 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 260 220 Z")'
+PASS Property offset-path value 'path("m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120")' computes to 'path("M 10 20 L 30 50 Z L 60 80 Z M 80 100 L 170 160 Z T 150 220")'
+PASS Property offset-path value 'path("m 10 170 h 90 v 30 m 0 0 s 1 2 3 4 z c 9 8 7 6 5 4")' computes to 'path("M 10 170 H 100 V 200 M 100 200 S 101 202 103 204 Z C 109 208 107 206 105 204")'
+PASS Property offset-path value 'path("m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50")' computes to 'path("M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120")'
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed.html
new file mode 100644
index 0000000..95210dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-path-computed.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Motion Path Module Level 1: getComputedStyle().offsetPath</title>
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-path-property">
+<meta name="assert" content="offset-path has absolute path commands.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("offset-path", "none");
+
+test_computed_value("offset-path", "ray(0rad closest-side)", "ray(0deg closest-side)");
+test_computed_value("offset-path", "ray(0.25turn closest-corner contain)", "ray(90deg closest-corner contain)");
+test_computed_value("offset-path", "ray(200grad farthest-side)", "ray(180deg farthest-side)");
+test_computed_value("offset-path", "ray(270deg farthest-corner contain)");
+test_computed_value("offset-path", "ray(-720deg sides)");
+test_computed_value("offset-path", "ray(calc(180deg - 45deg) farthest-side)", "ray(calc(135deg) farthest-side)");
+
+test_computed_value("offset-path", 'path("m 20 0 h -100")', 'path("M 20 0 H -80")');
+test_computed_value("offset-path", 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z")');
+test_computed_value("offset-path", 'path("m 10 20 q 30 60 40 50 q 100 70 90 80")', 'path("M 10 20 Q 40 80 50 70 Q 150 140 140 150")');
+test_computed_value("offset-path", 'path("M 0 0 L 100 100 m 0 100 l 100 0 Z l 160 20 Z")', 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 260 220 Z")');
+test_computed_value("offset-path", 'path("m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120")', 'path("M 10 20 L 30 50 Z L 60 80 Z M 80 100 L 170 160 Z T 150 220")');
+test_computed_value("offset-path", 'path("m 10 170 h 90 v 30 m 0 0 s 1 2 3 4 z c 9 8 7 6 5 4")', 'path("M 10 170 H 100 V 200 M 100 200 S 101 202 103 204 Z C 109 208 107 206 105 204")');
+test_computed_value("offset-path", 'path("m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50")', 'path("M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120")');
+
+// url, shape and geometry-box paths are not yet supported by implementations.
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-position-computed.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-position-computed.html
new file mode 100644
index 0000000..1cbdbdb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-position-computed.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Motion Path Module Level 1: getComputedStyle().offsetPosition</title>
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-position-property">
+<meta name="assert" content="offset-position is 'auto' or a computed position.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<style>
+  #target {
+    font-size: 40px;
+  }
+</style>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("offset-position", "auto");
+
+test_computed_value("offset-position", "left bottom", "0% 100%");
+test_computed_value("offset-position", "center center", "50% 50%");
+test_computed_value("offset-position", "right center", "100% 50%");
+test_computed_value("offset-position", "center top", "50% 0%");
+test_computed_value("offset-position", "center bottom", "50% 100%");
+test_computed_value("offset-position", "calc(5em + 20%) center", "calc(20% + 200px) 50%");
+test_computed_value("offset-position", "right 3em", "100% 120px");
+test_computed_value("offset-position", "10px 20%");
+test_computed_value("offset-position", "left -10px top -20%", "-10px -20%");
+test_computed_value("offset-position", "right 10% bottom 5em", "90% calc(100% - 200px)");
+test_computed_value("offset-position", "top 10px right -20%", "120% 10px");
+test_computed_value("offset-position", "left 10% bottom 2em", "10% calc(100% - 80px)");
+test_computed_value('offset-position', 'calc(10px - 0.5em) calc(10px + 0.5em)', '-10px 30px');
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.html b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.html
index 21db280..3e3cfcb 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.html
@@ -22,6 +22,10 @@
   { fragment: '#element##directive', expect_position: 'element' },
 ];
 
+test(t => {
+  assert_equals(typeof(window.location.selector), 'object', 'window.location.selector is defined');
+}, 'Scroll to text is feature detectable via window.location.selector');
+
 for (const test_case of test_cases) {
   promise_test(t => new Promise(resolve => {
     let channel = new BroadcastChannel('scroll-to-text-fragment');
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html
index cd4f582..f7d71325 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html
@@ -21,9 +21,7 @@
 
   test(t => {
     let a = 0;
-    assert_throws(new EvalError(), _ => {
-      eval(p.createScript('a="Hello transformed string"'));
-    });
+    eval(p.createScript('a="Hello transformed string"'));
     assert_equals(a, 0);
   }, "eval with TrustedScript throws (script-src blocks).");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-eval-reporting-no-unsafe-eval.tentative.https.html b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-eval-reporting-no-unsafe-eval.tentative.https.html
index f60bb9fe..dc86536 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-eval-reporting-no-unsafe-eval.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-eval-reporting-no-unsafe-eval.tentative.https.html
@@ -89,7 +89,6 @@
         .then(promise_violation("script-src"))
         .then(promise_flush());
     expect_throws(_ => eval('script_run_beacon="should not run"'));
-    // TODO(ssanfilippo) This should throw, but doesn't yet. See crbug.com/992424.
     eval(scriptyPolicy.createScript('script_run_beacon="i ran"'));
     flush();
     assert_not_equals(script_run_beacon, 'i ran'); // Code did not run.
diff --git a/third_party/blink/web_tests/presentation/resources/presentation-service-mock.js b/third_party/blink/web_tests/presentation/resources/presentation-service-mock.js
index 16b5bfa..be7ecd5 100644
--- a/third_party/blink/web_tests/presentation/resources/presentation-service-mock.js
+++ b/third_party/blink/web_tests/presentation/resources/presentation-service-mock.js
@@ -15,7 +15,7 @@
     this.receiverConnectionRequest_ = null;
 
     this.interceptor_ = new MojoInterfaceInterceptor(
-        blink.mojom.PresentationService.name);
+        blink.mojom.PresentationService.name, "context", true);
     this.interceptor_.oninterfacerequest =
         e => this.bindingSet_.addBinding(this, e.handle);
     this.interceptor_.start();
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013-ref.html b/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013-ref.html
new file mode 100644
index 0000000..6aaf27d
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013-ref.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf8">
+<title>CSS content-size: content-size changes</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="http://tabatkins.github.io/specs/css-content-size/">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid black;
+}
+#border > div {
+  width: 77px;
+  height: 88px;
+}
+</style>
+
+<div id=border><div id=target></div></div>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013.html b/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013.html
new file mode 100644
index 0000000..296b6b9
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-content-size/content-size-013.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>CSS content-size: content-size changes.</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="http://tabatkins.github.io/specs/css-content-size/">
+<link rel="match" href="content-size-013-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid black;
+}
+#border > div {
+  contain: size;
+  content-size: 55px 66px;
+}
+</style>
+
+<div id=border><div id=target></div></div>
+
+<script>
+function changeStyle() {
+  document.getElementById("target").style = "content-size: 77px 88px;";
+  requestAnimationFrame(takeScreenshot);
+}
+
+onload = () => requestAnimationFrame(() => requestAnimationFrame(changeStyle));
+
+</script>
+</html>
diff --git a/tools/android/elf_compression/README.md b/tools/android/elf_compression/README.md
index 9f3a4d6..ed068a2 100644
--- a/tools/android/elf_compression/README.md
+++ b/tools/android/elf_compression/README.md
@@ -37,6 +37,5 @@
 ## Testing
 To run tests:
 
-    test/compression_script_test.py
+    test/run_tests.py
 
-The test simply verifies that the sample library is not broken after applying the script.
diff --git a/tools/android/elf_compression/compress_section.py b/tools/android/elf_compression/compress_section.py
index f0039391..8980f6c2 100755
--- a/tools/android/elf_compression/compress_section.py
+++ b/tools/android/elf_compression/compress_section.py
@@ -26,7 +26,21 @@
 
 import argparse
 import logging
+import os
+import pathlib
+import subprocess
 import sys
+import tempfile
+
+import compression
+import elf_headers
+
+COMPRESSED_SECTION_NAME = '.compressed_library_data'
+ADDRESS_ALIGN = 0x1000
+
+# src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy
+OBJCOPY_PATH = pathlib.Path(__file__).resolve().parents[3].joinpath(
+    'third_party/llvm-build/Release+Asserts/bin/llvm-objcopy')
 
 
 def _SetupLogging():
@@ -51,12 +65,75 @@
   parser.add_argument(
       '-r',
       '--right_range',
-      help='End (inclusive) of the target part of the library',
+      help='End (exclusive) of the target part of the library',
       type=int,
       required=True)
   return parser.parse_args()
 
 
+def _FileRangeToVirtualAddressRange(data, l, r):
+  """Returns virtual address range corresponding to given file range.
+
+  Since we have to resolve them by their virtual address, parsing of LOAD
+  segments is required here.
+  """
+  elf = elf_headers.ElfHeader(data)
+  for phdr in elf.GetPhdrs():
+    if phdr.p_type == elf_headers.ProgramHeader.Type.PT_LOAD.value:
+      # Current version of the prototype only supports ranges which are fully
+      # contained inside one LOAD segment. It should cover most of the common
+      # cases.
+      if phdr.p_offset >= r or phdr.p_offset + phdr.p_filesz <= l:
+        # Range doesn't overlap.
+        continue
+      if phdr.p_offset > l or phdr.p_offset + phdr.p_filesz < r:
+        # Range overlap with LOAD segment but isn't fully covered by it.
+        raise RuntimeError('Range is not contained within one LOAD segment')
+      l_virt = phdr.p_vaddr + (l - phdr.p_offset)
+      r_virt = phdr.p_vaddr + (r - phdr.p_offset)
+      return l_virt, r_virt
+  raise RuntimeError('Specified range is outside of all LOAD segments.')
+
+
+def _CopyRangeIntoCompressedSection(data, l, r):
+  """Adds a new section containing compressed version of provided range."""
+  virtual_l, virtual_r = _FileRangeToVirtualAddressRange(data, l, r)
+  # LOAD segments borders are being rounded to the page size so we have to
+  # shrink [l, r) so corresponding virtual addresses are aligned.
+  if virtual_l % ADDRESS_ALIGN != 0:
+    l += ADDRESS_ALIGN - (virtual_l % ADDRESS_ALIGN)
+  r -= virtual_r % ADDRESS_ALIGN
+  if l >= r:
+    raise RuntimeError('Range collapsed after aligning by page size')
+
+  compressed_range = compression.CompressData(data[l:r])
+
+  with tempfile.TemporaryDirectory() as tmpdir:
+    # The easiest way to add a new section is to use objcopy, but it requires
+    # for all of the data to be stored in files.
+    objcopy_input_file = os.path.join(tmpdir, 'input')
+    objcopy_data_file = os.path.join(tmpdir, 'data')
+    objcopy_output_file = os.path.join(tmpdir, 'output')
+
+    with open(objcopy_input_file, 'wb') as f:
+      f.write(data)
+    with open(objcopy_data_file, 'wb') as f:
+      f.write(compressed_range)
+
+    objcopy_args = [
+        OBJCOPY_PATH, objcopy_input_file, objcopy_output_file, '--add-section',
+        '{}={}'.format(COMPRESSED_SECTION_NAME, objcopy_data_file)
+    ]
+    run_result = subprocess.run(
+        objcopy_args, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
+    if run_result.returncode != 0:
+      raise RuntimeError('objcopy failed with status code {}: {}'.format(
+          run_result.returncode, run_result.stderr))
+
+    with open(objcopy_output_file, 'rb') as f:
+      data[:] = bytearray(f.read())
+
+
 def main():
   _SetupLogging()
   args = _ParseArguments()
@@ -65,6 +142,8 @@
     data = f.read()
     data = bytearray(data)
 
+  _CopyRangeIntoCompressedSection(data, args.left_range, args.right_range)
+
   with open(args.output, 'wb') as f:
     f.write(data)
   return 0
diff --git a/tools/android/elf_compression/compression.py b/tools/android/elf_compression/compression.py
new file mode 100644
index 0000000..dbf996a5
--- /dev/null
+++ b/tools/android/elf_compression/compression.py
@@ -0,0 +1,16 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""This file contains compression algorithms for the library's data.
+
+The point of entry is CompressData method which is used by the main script
+to compress its data. Because of that the compression algorithm may be changed
+easily without modifying any of the main script.
+"""
+
+
+def CompressData(data):
+  # For the prototyping purposes the compression function is simplified to make
+  # debugging easier.
+  # TODO(https://crbug.com/998082): write a compression function.
+  return data
diff --git a/tools/android/elf_compression/elf_headers.py b/tools/android/elf_compression/elf_headers.py
new file mode 100644
index 0000000..f8ab8dad
--- /dev/null
+++ b/tools/android/elf_compression/elf_headers.py
@@ -0,0 +1,240 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""This library contains 64 bit ELF headers access and modification methods.
+
+This library implements classes representing various ELF structures.
+For more detailed description of ELF headers and fields refer to the ELF
+standard: http://www.skyfree.org/linux/references/ELF_Format.pdf and to the
+64 bit update: https://uclibc.org/docs/elf-64-gen.pdf.
+
+This library was created because the script required precise manipulations of
+file offsets. I.e: move the headers segment to the end of the file.
+No package, capable of doing this kind of manipulations was found, so the
+creation of this library was deemed necessary.
+
+The point of entry is ElfHeader class that provides methods for accessing
+additional parts of the ELF file.
+"""
+
+import enum
+import logging
+
+
+class ElfEntry(object):
+  """Base class for ELF headers.
+
+  Provides methods for populating fields.
+  """
+
+  def __init__(self, byte_order, fields=None):
+    """ElfEntry constructor.
+
+    Args:
+      byte_order: str. Either 'little' for little endian or 'big' for big
+        endian.
+      fields: List[Tuple[str, int]]. An ordered list of pairs of
+        (attribute name, size in bytes). This list will be used for parsing
+        data and automatically setting up those fields.
+    """
+    if fields is None:
+      self._fields = []
+    else:
+      self._fields = fields
+    self.byte_order = byte_order
+
+  def ParseBytes(self, data, offset):
+    """Parses Entry fields from data starting at offset using _fields.
+
+    Args:
+        data: bytes.
+        offset: int. The start point of parsing.
+    """
+    current_offset = offset
+    for field_name, field_size in self._fields:
+      value = int.from_bytes(
+          data[current_offset:current_offset + field_size],
+          byteorder=self.byte_order)
+      setattr(self, field_name, value)
+      current_offset += field_size
+
+  def ApplyKwargs(self, **kwargs):
+    """Set the fields from kwargs matching the _fields array entries."""
+    for field_name, _ in self._fields:
+      if field_name not in kwargs:
+        logging.error('field_name %s not found in kwargs', field_name)
+        continue
+      setattr(self, field_name, kwargs[field_name])
+
+  @classmethod
+  def FromBytes(cls, byte_order, data, offset):
+    """Static wrapper around ParseBytes method.
+
+    Args:
+      byte_order: str. Either 'little' for little endian or 'big' for big
+        endian.
+      data: bytes.
+      offset: int. The start point of parsing.
+    """
+    obj = cls(byte_order)
+    obj.ParseBytes(data, offset)
+    return obj
+
+
+class ProgramHeader(ElfEntry):
+  """This class represent PhdrEntry from ELF standard."""
+
+  class Type(enum.IntEnum):
+    PT_NULL = 0
+    PT_LOAD = 1
+    PT_DYNAMIC = 2
+    PT_INTERP = 3
+    PT_NOTE = 4
+    PT_SHLIB = 5
+    PT_PHDR = 6
+
+  def __init__(self, byte_order):
+    """ProgramHeader constructor.
+
+    Args:
+      byte_order: str.
+    """
+    # We have to set them here to avoid attribute-error from pylint.
+    self.p_type = None
+    self.p_flags = None
+    self.p_offset = None
+    self.p_vaddr = None
+    self.p_paddr = None
+    self.p_filesz = None
+    self.p_memsz = None
+    self.p_align = None
+    fields = [
+        ('p_type', 4),
+        ('p_flags', 4),
+        ('p_offset', 8),
+        ('p_vaddr', 8),
+        ('p_paddr', 8),
+        ('p_filesz', 8),
+        ('p_memsz', 8),
+        ('p_align', 8),
+    ]
+    super(ProgramHeader, self).__init__(byte_order, fields)
+
+
+class ElfHeader(ElfEntry):
+  """This class represents ELFHdr from the ELF standard.
+
+  On its initialization it determines the bitness and endianness of the binary.
+  """
+
+  class EiClass(enum.IntEnum):
+    ELFCLASS32 = 1
+    ELFCLASS64 = 2
+
+  class EiData(enum.IntEnum):
+    ELFDATALSB = 1
+    ELFDATAMSB = 2
+
+  class EType(enum.IntEnum):
+    ET_NONE = 0
+    ET_REL = 1
+    ET_EXEC = 2
+    ET_DYN = 3
+    ET_CORE = 4
+
+  _EI_CLASS_OFFSET = 4
+  _EI_DATA_OFFSET = 5
+
+  def _GetEiClass(self, data):
+    """Returns the value of ei_class."""
+    return data[self._EI_CLASS_OFFSET]
+
+  def _GetEiData(self, data):
+    """Returns the value of ei_data."""
+    return data[self._EI_DATA_OFFSET]
+
+  def _ValidateBitness(self, data):
+    """Verifies that library supports file's bitness."""
+    if self._GetEiClass(data) != ElfHeader.EiClass.ELFCLASS64:
+      raise RuntimeError('only 64 bit objects are supported')
+
+  def _ReadByteOrder(self, data):
+    """Reads and returns the file's byte order."""
+    ei_data = data[self._EI_DATA_OFFSET]
+    if ei_data == ElfHeader.EiData.ELFDATALSB:
+      return 'little'
+    elif ei_data == ElfHeader.EiData.ELFDATAMSB:
+      return 'big'
+    raise RuntimeError('Failed to parse ei_data')
+
+  def _ParsePhdrs(self, data):
+    current_offset = self.e_phoff
+    for _ in range(0, self.e_phnum):
+      self.phdrs.append(
+          ProgramHeader.FromBytes(self.byte_order, data, current_offset))
+      current_offset += self.e_phentsize
+
+  def __init__(self, data):
+    """ElfHeader constructor.
+
+    Args:
+      data: bytearray.
+    """
+    # We have to set them here to avoid attribute-error from pylint.
+    self.ei_magic = None
+    self.ei_class = None
+    self.ei_data = None
+    self.ei_version = None
+    self.ei_osabi = None
+    self.ei_abiversion = None
+    self.ei_pad = None
+    self.e_type = None
+    self.e_machine = None
+    self.e_version = None
+    self.e_entry = None
+    self.e_phoff = None
+    self.e_shoff = None
+    self.e_flags = None
+    self.e_ehsize = None
+    self.e_phentsize = None
+    self.e_phnum = None
+    self.e_shentsize = None
+    self.e_shnum = None
+    self.e_shstrndx = None
+    fields = [
+        ('ei_magic', 4),
+        ('ei_class', 1),
+        ('ei_data', 1),
+        ('ei_version', 1),
+        ('ei_osabi', 1),
+        ('ei_abiversion', 1),
+        ('ei_pad', 7),
+        ('e_type', 2),
+        ('e_machine', 2),
+        ('e_version', 4),
+        ('e_entry', 8),
+        ('e_phoff', 8),
+        ('e_shoff', 8),
+        ('e_flags', 4),
+        ('e_ehsize', 2),
+        ('e_phentsize', 2),
+        ('e_phnum', 2),
+        ('e_shentsize', 2),
+        ('e_shnum', 2),
+        ('e_shstrndx', 2),
+    ]
+
+    self._ValidateBitness(data)
+    byte_order = self._ReadByteOrder(data)
+    super(ElfHeader, self).__init__(byte_order, fields)
+
+    self.ParseBytes(data, 0)
+    if self.e_type != ElfHeader.EType.ET_DYN:
+      raise RuntimeError('Only shared libraries are supported')
+
+    self.phdrs = []
+    self._ParsePhdrs(data)
+
+  def GetPhdrs(self):
+    """Returns the list of file's program headers."""
+    return self.phdrs
diff --git a/tools/android/elf_compression/test/compression_script_test.py b/tools/android/elf_compression/test/compression_script_test.py
index 9f0d0f6..61e9fe4 100755
--- a/tools/android/elf_compression/test/compression_script_test.py
+++ b/tools/android/elf_compression/test/compression_script_test.py
@@ -8,6 +8,7 @@
 """
 
 import os
+import pathlib
 import subprocess
 import tempfile
 import unittest
@@ -18,11 +19,8 @@
 SCRIPT_PATH = '../compress_section.py'
 
 # src/third_party/llvm-build/Release+Asserts/bin/clang++
-LLVM_CLANG_PATH = os.path.abspath(
-    os.path.join(
-        os.path.dirname(__file__), os.path.pardir, os.path.pardir,
-        os.path.pardir, os.path.pardir, 'third_party', 'llvm-build',
-        'Release+Asserts', 'bin', 'clang++'))
+LLVM_CLANG_PATH = pathlib.Path(__file__).resolve().parents[4].joinpath(
+    'third_party/llvm-build/Release+Asserts/bin/clang++')
 
 # The array that we are trying to cut out of the file have those bytes at
 # its start and end. This is done to simplify the test code to not perform
@@ -54,7 +52,7 @@
     with open(library_path, 'rb') as f:
       data = f.read()
     l = data.find(MAGIC_BEGIN)
-    r = data.find(MAGIC_END) + len(MAGIC_END) - 1
+    r = data.find(MAGIC_END) + len(MAGIC_END)
     return l, r
 
   def _BuildLibrary(self):
@@ -118,7 +116,7 @@
 
     patched_library_path = self._RunScript(library_path)
     opener_output = self._RunOpener(opener_path, patched_library_path)
-    self.assertEqual(opener_output, '55\n')
+    self.assertEqual(opener_output, '1046506\n')
 
 
 if __name__ == '__main__':
diff --git a/tools/android/elf_compression/test/elf_headers_test.py b/tools/android/elf_compression/test/elf_headers_test.py
new file mode 100755
index 0000000..b75a3a0b
--- /dev/null
+++ b/tools/android/elf_compression/test/elf_headers_test.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import os
+import pathlib
+import sys
+import unittest
+
+sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
+import elf_headers
+
+ELF_HEADER_TEST_LIBRARY = 'testdata/lib.so'
+
+
+class ElfHeaderTest(unittest.TestCase):
+
+  def setUp(self):
+    super(ElfHeaderTest, self).setUp()
+    script_dir = os.path.dirname(os.path.abspath(__file__))
+    self.library_path = os.path.join(script_dir, ELF_HEADER_TEST_LIBRARY)
+
+  def testElfHeaderParsing(self):
+    with open(self.library_path, 'rb') as f:
+      data = f.read()
+    elf = elf_headers.ElfHeader(data)
+    # Validating all of the ELF header fields.
+    self.assertEqual(elf.e_type, elf_headers.ElfHeader.EType.ET_DYN)
+    self.assertEqual(elf.e_entry, 0x1040)
+    self.assertEqual(elf.e_phoff, 64)
+    self.assertEqual(elf.e_shoff, 14136)
+    self.assertEqual(elf.e_flags, 0)
+    self.assertEqual(elf.e_ehsize, 64)
+    self.assertEqual(elf.e_phentsize, 56)
+    self.assertEqual(elf.e_phnum, 8)
+    self.assertEqual(elf.e_shentsize, 64)
+    self.assertEqual(elf.e_shnum, 26)
+    self.assertEqual(elf.e_shstrndx, 25)
+    # Validating types and amounts of all segments excluding GNU specific ones.
+    phdrs = elf.GetPhdrs()
+    self.assertEqual(len(phdrs), 8)
+
+    phdr_types = [
+        elf_headers.ProgramHeader.Type.PT_LOAD,
+        elf_headers.ProgramHeader.Type.PT_LOAD,
+        elf_headers.ProgramHeader.Type.PT_LOAD,
+        elf_headers.ProgramHeader.Type.PT_LOAD,
+        elf_headers.ProgramHeader.Type.PT_DYNAMIC,
+        None,
+        None,
+        None,
+    ]
+    for i in range(0, len(phdrs)):
+      if phdr_types[i] is not None:
+        self.assertEqual(phdrs[i].p_type, phdr_types[i])
+
+    # Validating all of the fields of the first segment.
+    load_phdr = phdrs[0]
+    self.assertEqual(load_phdr.p_offset, 0x0)
+    self.assertEqual(load_phdr.p_vaddr, 0x0)
+    self.assertEqual(load_phdr.p_paddr, 0x0)
+    self.assertEqual(load_phdr.p_filesz, 0x468)
+    self.assertEqual(load_phdr.p_memsz, 0x468)
+    self.assertEqual(load_phdr.p_flags, 0b100)
+    self.assertEqual(load_phdr.p_align, 0x1000)
+    # Validating offsets of the second segment
+    load_phdr = phdrs[1]
+    self.assertEqual(load_phdr.p_offset, 0x1000)
+    self.assertEqual(load_phdr.p_vaddr, 0x1000)
+    self.assertEqual(load_phdr.p_paddr, 0x1000)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/android/elf_compression/test/libtest.cc b/tools/android/elf_compression/test/libtest.cc
index fd6f429..c28198c 100644
--- a/tools/android/elf_compression/test/libtest.cc
+++ b/tools/android/elf_compression/test/libtest.cc
@@ -11,12 +11,7 @@
 #include <numeric>
 #include <vector>
 
-// The first and last 4 values are randomly chosen bytes to be used by test as
-// "magic" values indicating the beginning and the end of the array. This array
-// needs to be an exported symbol to avoid compiler optimization which is why it
-// is not declared as "const".
-unsigned char array[18] = {151, 155, 125, 68, 1,  2,   3,  4,   5,
-                           6,   7,   8,   9,  10, 236, 55, 136, 224};
+#include "libtest_array.h"  // NOLINT(build/include)
 
 extern "C" {
 int GetSum();
@@ -25,8 +20,8 @@
 int GetSum() {
   // We are using some c++ features here to better simulate a c++ library and
   // cause more code reach to catch potential memory errors.
-  std::vector<int> sum_array(&array[4], &array[4] + 10);
+  std::vector<int> sum_array(std::begin(array), std::end(array));
   int sum = std::accumulate(sum_array.begin(), sum_array.end(), 0);
-  // sum should be equal to 55.
+  // sum should be equal to 1046506.
   return sum;
 }
diff --git a/tools/android/elf_compression/test/libtest_array.h b/tools/android/elf_compression/test/libtest_array.h
new file mode 100644
index 0000000..721f6c31
--- /dev/null
+++ b/tools/android/elf_compression/test/libtest_array.h
@@ -0,0 +1,580 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This header file contains an array for testing compression script.
+//
+// Script shrinks the given data range so it is page aligned which requires the
+// size of array to at least 2 * 4096 to guarantee that the range won't be
+// empty after the shrinking.
+// Another requirement is for array to not be lazily initialized by zeroes
+// since that would result in it occupying no actual size in the file and
+// being placed in .bss section. As a result all of the array elements have
+// to be declared explicitly to prevent compiler from optimizing continuous
+// row of zeroes.
+
+#ifndef TOOLS_ANDROID_ELF_COMPRESSION_TEST_LIBTEST_ARRAY_H_
+#define TOOLS_ANDROID_ELF_COMPRESSION_TEST_LIBTEST_ARRAY_H_
+
+// The first and last 4 bytes of array are hardcoded in the testing script to
+// be able to locate the array in memory so they should be changed with care.
+// To improve readability those bytes are declared here.
+constexpr unsigned char kMagicPrefix[] = {151, 155, 125, 68};
+constexpr unsigned char kMagicSuffix[] = {236, 55, 136, 224};
+
+// Disabling clang-format on the array since it tries to put each number at the
+// separate line which is not needed in this case.
+// clang-format off
+unsigned char array[8192] = {
+    kMagicPrefix[0], kMagicPrefix[1], kMagicPrefix[2], kMagicPrefix[3],
+    88,  2,   71,  243, 203, 204, 83,  235, 153, 204, 231, 242, 135, 143, 154,
+    147, 156, 221, 159, 188, 255, 135, 149, 96,  18,  240, 23,  60,  34,  97,
+    255, 255, 15,  187, 25,  48,  175, 54,  237, 124, 170, 211, 49,  113, 2,
+    122, 73,  252, 107, 233, 16,  149, 51,  164, 64,  211, 109, 253, 207, 94,
+    237, 58,  158, 140, 146, 133, 49,  26,  191, 221, 35,  14,  253, 160, 72,
+    197, 84,  157, 139, 192, 46,  142, 5,   30,  57,  105, 210, 33,  31,  214,
+    190, 206, 174, 107, 217, 26,  134, 88,  212, 164, 238, 31,  150, 155, 41,
+    231, 76,  121, 87,  192, 63,  97,  219, 69,  13,  110, 231, 28,  2,   238,
+    34,  241, 162, 222, 236, 246, 163, 61,  7,   175, 209, 251, 97,  60,  206,
+    179, 65,  97,  14,  29,  101, 230, 114, 73,  205, 163, 77,  27,  69,  77,
+    139, 191, 109, 187, 204, 61,  108, 0,   195, 223, 168, 60,  181, 236, 91,
+    164, 72,  200, 101, 253, 72,  131, 145, 161, 144, 125, 181, 198, 197, 246,
+    122, 79,  236, 176, 84,  122, 224, 207, 143, 20,  179, 192, 83,  78,  157,
+    40,  88,  184, 6,   65,  166, 74,  173, 103, 224, 5,   44,  113, 90,  128,
+    241, 40,  250, 208, 134, 117, 78,  148, 36,  141, 57,  181, 4,   230, 3,
+    47,  249, 120, 94,  33,  202, 201, 24,  67,  182, 150, 84,  208, 187, 88,
+    74,  204, 133, 161, 2,   181, 116, 198, 135, 207, 12,  87,  36,  50,  76,
+    44,  160, 143, 66,  55,  115, 27,  233, 11,  106, 31,  122, 119, 194, 125,
+    202, 12,  234, 83,  21,  124, 0,   247, 26,  206, 139, 233, 252, 222, 20,
+    69,  66,  141, 116, 186, 120, 24,  100, 178, 222, 3,   234, 104, 11,  107,
+    197, 32,  220, 179, 82,  4,   92,  110, 161, 9,   43,  138, 131, 241, 239,
+    74,  164, 103, 245, 100, 82,  30,  134, 121, 47,  214, 0,   139, 18,  210,
+    115, 93,  208, 45,  97,  131, 254, 50,  182, 152, 246, 64,  242, 12,  1,
+    10,  112, 67,  82,  92,  148, 105, 183, 168, 242, 87,  197, 94,  251, 156,
+    31,  41,  188, 150, 92,  41,  124, 211, 144, 181, 69,  250, 178, 36,  30,
+    182, 0,   207, 132, 36,  0,   107, 126, 91,  210, 2,   7,   248, 224, 228,
+    3,   209, 223, 15,  95,  18,  159, 53,  114, 22,  225, 130, 233, 204, 138,
+    171, 209, 123, 13,  215, 97,  113, 214, 220, 161, 251, 233, 190, 51,  96,
+    155, 248, 25,  205, 185, 192, 126, 49,  195, 132, 224, 46,  51,  247, 47,
+    238, 164, 136, 241, 181, 16,  69,  50,  44,  253, 102, 92,  29,  100, 126,
+    222, 68,  247, 91,  205, 215, 106, 121, 29,  166, 200, 163, 239, 141, 172,
+    101, 59,  152, 214, 27,  36,  1,   229, 193, 230, 164, 251, 148, 215, 188,
+    211, 113, 243, 85,  81,  48,  244, 204, 172, 128, 92,  86,  202, 178, 227,
+    85,  0,   56,  204, 233, 203, 164, 100, 222, 109, 251, 6,   249, 63,  68,
+    7,   22,  140, 11,  251, 129, 245, 85,  61,  216, 112, 34,  87,  30,  244,
+    35,  58,  127, 58,  179, 234, 96,  36,  83,  1,   19,  116, 201, 141, 95,
+    205, 130, 197, 105, 18,  0,   216, 41,  36,  206, 245, 165, 128, 116, 34,
+    154, 114, 159, 3,   46,  217, 150, 102, 39,  163, 82,  37,  187, 254, 106,
+    175, 209, 52,  88,  93,  196, 252, 15,  169, 19,  187, 250, 1,   240, 218,
+    230, 255, 130, 84,  246, 241, 134, 67,  22,  109, 59,  121, 208, 242, 149,
+    86,  74,  67,  59,  65,  114, 134, 13,  137, 209, 225, 239, 252, 149, 97,
+    27,  109, 194, 37,  15,  130, 55,  75,  98,  167, 253, 181, 188, 199, 208,
+    189, 122, 210, 166, 176, 47,  79,  129, 191, 200, 30,  34,  6,   32,  247,
+    202, 200, 37,  193, 112, 168, 176, 232, 123, 225, 134, 167, 193, 187, 125,
+    48,  222, 226, 124, 55,  108, 32,  61,  181, 35,  113, 111, 6,   91,  151,
+    36,  3,   119, 253, 73,  170, 183, 111, 131, 36,  59,  106, 40,  54,  107,
+    8,   208, 14,  176, 156, 205, 192, 226, 93,  135, 106, 129, 201, 70,  211,
+    166, 15,  141, 205, 88,  76,  90,  23,  200, 66,  9,   47,  195, 211, 37,
+    144, 186, 248, 210, 65,  39,  147, 216, 235, 49,  223, 111, 206, 116, 25,
+    131, 137, 203, 47,  94,  157, 144, 159, 202, 21,  42,  146, 166, 121, 190,
+    52,  224, 26,  153, 60,  206, 175, 228, 17,  108, 247, 219, 160, 188, 75,
+    92,  81,  226, 17,  214, 225, 219, 84,  42,  214, 37,  246, 40,  43,  11,
+    179, 193, 235, 17,  175, 99,  1,   225, 162, 207, 189, 186, 168, 137, 220,
+    232, 74,  28,  61,  122, 79,  144, 173, 191, 165, 43,  16,  148, 53,  146,
+    236, 64,  219, 159, 70,  181, 221, 18,  109, 125, 105, 224, 245, 84,  62,
+    237, 12,  153, 159, 173, 189, 185, 11,  169, 117, 228, 229, 104, 229, 167,
+    165, 82,  156, 100, 119, 214, 214, 83,  83,  81,  189, 170, 115, 90,  120,
+    182, 29,  97,  161, 84,  153, 84,  149, 188, 13,  254, 78,  26,  123, 125,
+    6,   191, 26,  254, 19,  56,  41,  133, 209, 98,  222, 218, 183, 230, 63,
+    186, 3,   195, 211, 146, 2,   31,  53,  211, 0,   213, 245, 35,  255, 173,
+    205, 221, 61,  227, 47,  48,  237, 154, 177, 150, 152, 221, 189, 227, 129,
+    16,  145, 186, 88,  82,  28,  211, 23,  109, 59,  245, 102, 31,  21,  207,
+    235, 131, 24,  33,  63,  49,  187, 27,  203, 80,  66,  59,  113, 224, 255,
+    39,  248, 153, 171, 30,  231, 2,   184, 24,  87,  0,   153, 244, 57,  78,
+    223, 188, 196, 239, 117, 98,  142, 86,  16,  188, 2,   68,  180, 173, 252,
+    128, 78,  99,  125, 226, 236, 158, 169, 109, 129, 225, 127, 164, 34,  243,
+    93,  135, 64,  206, 188, 130, 11,  85,  235, 68,  30,  129, 71,  89,  150,
+    4,   170, 158, 149, 51,  102, 23,  139, 185, 154, 168, 66,  167, 120, 147,
+    57,  83,  47,  30,  24,  33,  209, 117, 52,  62,  78,  59,  10,  223, 192,
+    43,  33,  88,  2,   3,   146, 82,  240, 240, 252, 169, 229, 250, 148, 131,
+    22,  79,  195, 179, 50,  37,  140, 112, 117, 191, 57,  123, 104, 185, 166,
+    135, 153, 12,  221, 71,  80,  67,  111, 103, 230, 206, 188, 13,  242, 109,
+    59,  233, 173, 244, 18,  213, 42,  29,  42,  204, 135, 151, 63,  237, 168,
+    224, 186, 127, 210, 153, 193, 218, 127, 6,   63,  230, 192, 105, 148, 83,
+    150, 209, 105, 216, 86,  116, 124, 207, 78,  92,  0,   3,   74,  168, 253,
+    185, 210, 42,  225, 54,  155, 71,  31,  224, 90,  70,  143, 25,  240, 216,
+    207, 29,  9,   77,  37,  29,  109, 143, 234, 148, 195, 44,  142, 151, 20,
+    234, 10,  240, 81,  15,  64,  82,  175, 132, 111, 76,  121, 240, 231, 78,
+    4,   5,   9,   185, 170, 68,  107, 182, 216, 75,  77,  86,  96,  72,  140,
+    193, 24,  81,  110, 70,  46,  24,  234, 16,  220, 181, 114, 32,  177, 107,
+    221, 107, 246, 248, 20,  249, 105, 69,  242, 70,  88,  177, 45,  90,  64,
+    149, 31,  125, 81,  37,  54,  3,   120, 138, 161, 29,  195, 197, 35,  226,
+    75,  243, 44,  8,   222, 29,  181, 140, 29,  116, 18,  104, 250, 40,  115,
+    0,   57,  90,  239, 59,  230, 113, 105, 104, 176, 74,  74,  237, 105, 240,
+    197, 220, 97,  47,  114, 193, 241, 169, 19,  105, 17,  240, 0,   19,  151,
+    149, 27,  46,  13,  174, 11,  74,  241, 201, 50,  225, 52,  11,  134, 89,
+    22,  13,  87,  179, 97,  117, 182, 201, 27,  201, 188, 62,  73,  3,   165,
+    196, 112, 229, 140, 230, 178, 137, 28,  105, 54,  126, 61,  119, 169, 181,
+    144, 225, 119, 161, 108, 172, 205, 72,  150, 152, 196, 115, 121, 1,   44,
+    143, 8,   34,  108, 2,   107, 56,  171, 69,  182, 0,   188, 30,  47,  66,
+    237, 189, 194, 99,  173, 232, 140, 219, 193, 223, 162, 57,  130, 148, 242,
+    199, 88,  188, 253, 146, 179, 1,   243, 109, 126, 144, 140, 21,  110, 201,
+    11,  5,   150, 197, 50,  207, 85,  123, 242, 213, 117, 92,  118, 68,  38,
+    168, 12,  131, 104, 65,  105, 250, 31,  11,  208, 51,  156, 253, 197, 245,
+    245, 182, 60,  159, 21,  181, 236, 245, 157, 125, 31,  219, 34,  20,  130,
+    155, 47,  120, 96,  40,  197, 110, 13,  8,   6,   115, 130, 221, 97,  237,
+    210, 130, 241, 174, 176, 87,  77,  199, 12,  23,  4,   224, 144, 239, 194,
+    225, 87,  48,  80,  77,  139, 73,  168, 145, 213, 123, 150, 35,  38,  16,
+    15,  24,  73,  191, 7,   23,  123, 211, 16,  167, 55,  230, 125, 161, 21,
+    120, 50,  131, 28,  6,   85,  190, 73,  12,  141, 55,  74,  97,  144, 114,
+    190, 165, 140, 114, 195, 55,  243, 156, 71,  161, 235, 20,  124, 115, 9,
+    236, 51,  138, 168, 38,  76,  188, 9,   150, 214, 197, 77,  181, 14,  167,
+    23,  131, 67,  11,  46,  211, 203, 60,  16,  70,  107, 67,  220, 239, 71,
+    120, 89,  218, 39,  134, 225, 125, 167, 229, 173, 179, 101, 72,  178, 86,
+    38,  185, 167, 143, 253, 99,  162, 196, 248, 71,  99,  4,   192, 63,  136,
+    151, 229, 5,   219, 89,  88,  118, 225, 124, 31,  52,  195, 204, 99,  157,
+    26,  148, 233, 96,  212, 82,  153, 188, 195, 53,  223, 189, 125, 140, 253,
+    192, 241, 65,  170, 103, 227, 68,  30,  228, 237, 163, 66,  154, 134, 58,
+    224, 117, 201, 146, 179, 32,  13,  212, 207, 146, 157, 244, 33,  66,  92,
+    255, 110, 4,   36,  248, 67,  139, 198, 43,  154, 149, 32,  212, 123, 18,
+    135, 206, 164, 74,  85,  75,  6,   167, 213, 159, 254, 170, 150, 8,   216,
+    3,   28,  138, 113, 184, 69,  155, 162, 16,  38,  228, 133, 126, 164, 209,
+    243, 96,  215, 1,   187, 210, 130, 84,  228, 16,  91,  137, 195, 178, 126,
+    0,   106, 183, 92,  202, 51,  162, 207, 179, 104, 111, 105, 39,  137, 36,
+    182, 237, 179, 138, 54,  104, 237, 251, 68,  185, 113, 177, 201, 242, 202,
+    34,  236, 243, 153, 165, 136, 176, 116, 249, 29,  16,  45,  120, 165, 51,
+    103, 10,  150, 106, 223, 242, 200, 5,   48,  210, 201, 158, 102, 238, 187,
+    251, 71,  244, 9,   187, 229, 125, 176, 84,  223, 100, 211, 240, 193, 155,
+    110, 96,  182, 75,  229, 93,  137, 1,   63,  137, 235, 131, 100, 13,  174,
+    66,  206, 25,  116, 94,  181, 107, 20,  9,   69,  108, 28,  56,  49,  182,
+    126, 38,  68,  239, 114, 92,  160, 0,   250, 59,  7,   12,  176, 12,  169,
+    76,  71,  94,  154, 151, 113, 46,  223, 78,  116, 116, 128, 57,  120, 153,
+    120, 96,  205, 65,  45,  88,  133, 110, 21,  83,  205, 37,  175, 66,  159,
+    82,  203, 203, 220, 152, 148, 19,  6,   1,   19,  159, 88,  73,  151, 77,
+    211, 103, 198, 181, 140, 90,  3,   169, 222, 119, 171, 207, 185, 90,  152,
+    101, 101, 43,  142, 197, 243, 211, 211, 159, 254, 168, 74,  207, 91,  45,
+    122, 233, 104, 191, 22,  136, 100, 191, 240, 248, 166, 63,  101, 39,  41,
+    46,  88,  10,  47,  173, 27,  153, 100, 237, 172, 162, 30,  218, 228, 106,
+    210, 100, 158, 191, 195, 148, 64,  146, 231, 48,  150, 173, 5,   77,  156,
+    166, 234, 203, 50,  58,  78,  20,  183, 244, 239, 5,   163, 9,   196, 207,
+    15,  171, 61,  76,  252, 72,  122, 170, 161, 81,  3,   157, 28,  96,  114,
+    110, 234, 213, 183, 230, 206, 49,  187, 120, 161, 152, 19,  104, 223, 204,
+    97,  36,  103, 151, 224, 40,  204, 93,  128, 92,  155, 105, 183, 21,  104,
+    121, 179, 240, 141, 130, 111, 57,  57,  205, 130, 35,  246, 155, 91,  122,
+    146, 40,  234, 56,  166, 132, 118, 138, 56,  205, 213, 199, 144, 162, 245,
+    126, 195, 1,   1,   54,  109, 145, 123, 7,   150, 193, 69,  92,  83,  39,
+    54,  94,  183, 22,  85,  201, 243, 76,  165, 2,   116, 201, 85,  253, 7,
+    23,  173, 31,  96,  53,  18,  213, 178, 193, 235, 235, 171, 15,  227, 193,
+    118, 126, 194, 189, 89,  109, 20,  8,   19,  247, 25,  180, 52,  223, 211,
+    168, 186, 196, 255, 83,  135, 130, 246, 3,   113, 82,  165, 202, 9,   135,
+    41,  89,  70,  213, 180, 46,  247, 151, 230, 208, 153, 51,  190, 250, 54,
+    26,  82,  75,  141, 11,  36,  19,  82,  177, 173, 1,   235, 64,  30,  9,
+    36,  91,  19,  206, 104, 105, 163, 160, 115, 21,  194, 194, 61,  52,  51,
+    6,   107, 218, 181, 172, 60,  122, 240, 35,  104, 117, 144, 32,  44,  168,
+    40,  69,  133, 107, 179, 1,   119, 21,  138, 152, 30,  185, 51,  21,  26,
+    17,  242, 106, 23,  142, 200, 122, 44,  91,  150, 14,  190, 110, 120, 126,
+    153, 21,  2,   152, 18,  30,  113, 144, 153, 162, 251, 46,  63,  40,  97,
+    34,  59,  180, 41,  211, 151, 65,  23,  233, 111, 139, 50,  69,  89,  134,
+    80,  170, 11,  228, 208, 95,  76,  126, 83,  106, 53,  200, 149, 89,  34,
+    140, 61,  191, 73,  160, 41,  127, 17,  234, 33,  189, 136, 6,   74,  154,
+    41,  69,  40,  150, 36,  141, 43,  168, 137, 88,  160, 166, 217, 255, 10,
+    148, 206, 147, 196, 231, 167, 150, 181, 94,  204, 192, 78,  151, 247, 125,
+    6,   43,  8,   140, 199, 209, 66,  151, 246, 164, 3,   151, 172, 129, 158,
+    56,  171, 158, 77,  223, 85,  73,  167, 90,  160, 60,  149, 174, 157, 105,
+    82,  120, 120, 106, 107, 67,  74,  221, 173, 227, 79,  52,  75,  47,  128,
+    137, 94,  14,  92,  195, 113, 150, 75,  183, 50,  178, 20,  186, 138, 153,
+    158, 207, 125, 75,  103, 86,  197, 12,  104, 88,  13,  152, 237, 50,  103,
+    118, 132, 126, 52,  139, 250, 115, 254, 243, 188, 106, 113, 245, 149, 50,
+    227, 129, 102, 61,  114, 236, 32,  212, 118, 130, 99,  170, 106, 14,  203,
+    248, 148, 243, 81,  69,  14,  68,  161, 38,  123, 65,  32,  226, 167, 17,
+    61,  224, 110, 34,  168, 110, 241, 37,  235, 57,  124, 161, 194, 134, 213,
+    46,  246, 134, 84,  153, 205, 114, 109, 129, 88,  201, 247, 211, 162, 235,
+    22,  111, 227, 161, 27,  156, 5,   199, 237, 119, 130, 98,  143, 225, 204,
+    121, 157, 24,  206, 102, 137, 68,  163, 49,  94,  134, 73,  51,  248, 44,
+    188, 81,  192, 201, 117, 170, 136, 56,  78,  10,  253, 64,  247, 233, 154,
+    220, 229, 96,  82,  103, 178, 40,  8,   48,  130, 54,  201, 148, 159, 34,
+    23,  164, 206, 106, 24,  57,  193, 139, 239, 213, 51,  183, 255, 53,  155,
+    10,  60,  92,  129, 86,  160, 128, 110, 103, 145, 123, 77,  117, 179, 145,
+    83,  208, 153, 102, 156, 243, 162, 189, 137, 154, 104, 117, 41,  177, 202,
+    148, 123, 101, 243, 23,  23,  50,  30,  107, 137, 162, 236, 208, 236, 186,
+    220, 35,  225, 26,  226, 90,  33,  149, 175, 26,  147, 109, 114, 30,  44,
+    189, 197, 137, 201, 223, 25,  102, 95,  76,  227, 54,  197, 128, 187, 137,
+    241, 26,  32,  46,  207, 137, 90,  202, 55,  145, 71,  215, 50,  112, 211,
+    192, 239, 239, 50,  206, 190, 31,  230, 106, 187, 0,   154, 229, 211, 190,
+    169, 163, 199, 159, 169, 135, 228, 64,  19,  137, 103, 227, 85,  27,  42,
+    101, 193, 224, 57,  171, 135, 184, 146, 226, 172, 72,  227, 115, 42,  28,
+    102, 158, 166, 196, 178, 79,  255, 99,  128, 31,  218, 178, 68,  191, 20,
+    231, 15,  49,  238, 31,  204, 24,  59,  64,  186, 239, 125, 26,  133, 42,
+    76,  121, 169, 7,   28,  28,  175, 74,  127, 44,  38,  171, 1,   201, 173,
+    139, 183, 56,  21,  52,  96,  201, 184, 142, 82,  230, 82,  189, 205, 248,
+    142, 92,  244, 173, 219, 169, 145, 38,  104, 69,  97,  222, 166, 181, 125,
+    255, 10,  150, 236, 100, 82,  162, 148, 73,  21,  193, 6,   167, 87,  100,
+    119, 254, 114, 121, 1,   159, 158, 243, 22,  91,  197, 231, 0,   164, 23,
+    222, 187, 113, 23,  161, 153, 191, 188, 255, 42,  104, 168, 205, 21,  16,
+    196, 23,  75,  33,  138, 195, 32,  96,  218, 175, 92,  201, 68,  241, 150,
+    210, 145, 240, 217, 243, 77,  38,  149, 163, 53,  202, 169, 178, 79,  18,
+    96,  255, 7,   12,  202, 6,   130, 240, 141, 6,   6,   79,  138, 84,  212,
+    146, 77,  139, 28,  92,  21,  227, 192, 66,  74,  116, 99,  27,  52,  63,
+    12,  108, 70,  224, 197, 158, 94,  214, 240, 110, 78,  71,  98,  225, 161,
+    223, 87,  78,  220, 121, 50,  150, 56,  102, 238, 4,   200, 140, 193, 103,
+    164, 150, 253, 68,  3,   172, 125, 237, 104, 155, 139, 247, 108, 49,  64,
+    2,   10,  114, 52,  20,  166, 8,   99,  76,  209, 93,  102, 252, 48,  93,
+    90,  123, 98,  216, 234, 161, 6,   14,  230, 77,  62,  205, 72,  115, 13,
+    157, 210, 87,  136, 182, 251, 102, 206, 201, 38,  155, 143, 20,  5,   19,
+    215, 215, 147, 127, 13,  40,  181, 77,  96,  124, 141, 163, 57,  133, 209,
+    154, 131, 195, 99,  54,  241, 118, 13,  150, 134, 238, 173, 200, 150, 246,
+    72,  207, 191, 45,  209, 45,  154, 176, 206, 243, 143, 221, 114, 20,  84,
+    176, 148, 183, 215, 107, 113, 108, 6,   156, 218, 157, 147, 245, 154, 138,
+    45,  83,  5,   67,  177, 108, 79,  132, 231, 53,  17,  141, 7,   218, 133,
+    234, 245, 174, 219, 2,   49,  123, 193, 246, 97,  164, 63,  255, 36,  132,
+    189, 177, 187, 244, 90,  43,  238, 113, 153, 89,  91,  195, 112, 117, 209,
+    183, 168, 192, 66,  157, 64,  106, 203, 45,  28,  17,  216, 143, 246, 192,
+    239, 225, 219, 5,   192, 0,   130, 190, 248, 2,   229, 99,  192, 25,  110,
+    200, 118, 245, 151, 199, 76,  239, 146, 213, 138, 249, 96,  56,  93,  52,
+    181, 158, 51,  84,  92,  75,  172, 216, 190, 174, 126, 70,  244, 246, 194,
+    84,  50,  192, 225, 145, 229, 183, 219, 132, 228, 115, 52,  110, 38,  254,
+    170, 241, 212, 4,   75,  50,  7,   9,   235, 159, 254, 208, 170, 26,  163,
+    15,  136, 3,   224, 150, 82,  102, 206, 248, 219, 58,  132, 91,  205, 71,
+    44,  61,  48,  250, 235, 172, 46,  36,  254, 58,  99,  30,  195, 174, 66,
+    192, 17,  202, 60,  97,  24,  196, 110, 239, 148, 210, 70,  179, 221, 101,
+    1,   35,  114, 99,  138, 134, 87,  255, 63,  8,   38,  221, 109, 69,  103,
+    49,  109, 129, 219, 124, 31,  24,  89,  187, 87,  119, 43,  178, 202, 221,
+    7,   246, 106, 131, 31,  89,  151, 85,  80,  182, 53,  41,  204, 25,  154,
+    33,  224, 166, 161, 70,  55,  23,  212, 75,  173, 48,  249, 3,   107, 76,
+    21,  162, 57,  147, 205, 207, 163, 128, 144, 104, 242, 214, 245, 91,  1,
+    97,  128, 2,   109, 60,  163, 67,  208, 201, 249, 124, 42,  144, 115, 89,
+    227, 76,  20,  158, 76,  32,  43,  245, 225, 82,  17,  216, 23,  147, 44,
+    63,  10,  127, 58,  120, 103, 129, 147, 130, 24,  62,  194, 83,  154, 151,
+    81,  155, 96,  99,  171, 34,  228, 129, 244, 43,  129, 211, 126, 59,  114,
+    46,  184, 110, 253, 58,  80,  153, 52,  224, 197, 46,  181, 192, 98,  23,
+    88,  185, 200, 204, 162, 84,  82,  139, 2,   154, 237, 163, 109, 24,  59,
+    68,  147, 71,  71,  30,  160, 76,  230, 47,  97,  238, 98,  140, 7,   157,
+    136, 68,  192, 247, 153, 150, 73,  223, 240, 167, 226, 59,  237, 183, 185,
+    45,  202, 70,  44,  65,  210, 207, 33,  67,  239, 249, 32,  208, 102, 138,
+    67,  155, 0,   163, 108, 119, 56,  95,  246, 94,  117, 161, 162, 119, 250,
+    109, 140, 121, 213, 66,  107, 199, 121, 198, 36,  186, 55,  112, 138, 3,
+    115, 115, 205, 67,  90,  25,  202, 71,  212, 175, 96,  8,   108, 197, 89,
+    222, 151, 75,  114, 202, 229, 229, 93,  177, 73,  139, 61,  145, 79,  69,
+    228, 235, 0,   48,  138, 70,  73,  180, 206, 4,   104, 159, 101, 217, 7,
+    2,   241, 19,  74,  195, 165, 168, 226, 8,   85,  225, 55,  118, 90,  203,
+    117, 65,  158, 120, 252, 190, 138, 62,  250, 169, 78,  69,  139, 152, 23,
+    111, 44,  118, 76,  75,  1,   52,  239, 10,  32,  98,  207, 126, 84,  110,
+    40,  67,  143, 70,  43,  2,   175, 76,  51,  169, 76,  167, 49,  41,  70,
+    66,  59,  88,  89,  233, 37,  34,  181, 24,  36,  21,  209, 231, 130, 28,
+    236, 200, 121, 248, 25,  222, 181, 161, 58,  106, 43,  48,  38,  50,  202,
+    227, 125, 242, 35,  197, 102, 130, 191, 99,  189, 172, 237, 107, 111, 209,
+    41,  199, 19,  254, 47,  103, 21,  220, 158, 77,  243, 159, 215, 170, 34,
+    83,  186, 91,  162, 49,  35,  249, 220, 61,  55,  32,  156, 38,  149, 72,
+    189, 232, 92,  6,   159, 227, 199, 53,  74,  50,  142, 39,  160, 107, 116,
+    167, 23,  177, 141, 35,  56,  232, 24,  233, 243, 250, 176, 48,  204, 116,
+    39,  246, 59,  82,  118, 206, 233, 96,  143, 79,  205, 100, 202, 124, 180,
+    212, 141, 141, 120, 188, 241, 161, 50,  241, 166, 136, 62,  107, 80,  234,
+    169, 226, 139, 233, 39,  97,  123, 210, 75,  111, 104, 45,  173, 176, 168,
+    48,  54,  193, 244, 107, 88,  34,  1,   6,   248, 102, 47,  188, 210, 90,
+    64,  16,  114, 14,  117, 9,   5,   110, 173, 51,  19,  135, 11,  252, 66,
+    40,  55,  17,  95,  150, 26,  161, 241, 227, 35,  98,  30,  125, 230, 217,
+    196, 206, 5,   213, 205, 206, 115, 248, 194, 39,  216, 240, 235, 104, 15,
+    253, 157, 177, 50,  192, 39,  151, 220, 90,  23,  138, 85,  217, 131, 114,
+    118, 9,   4,   13,  18,  64,  136, 215, 127, 169, 156, 237, 139, 112, 248,
+    146, 226, 202, 114, 243, 59,  250, 120, 97,  146, 41,  249, 90,  70,  57,
+    130, 92,  21,  149, 24,  20,  183, 252, 162, 163, 75,  254, 22,  114, 13,
+    17,  131, 22,  27,  83,  248, 174, 40,  111, 247, 236, 248, 17,  198, 233,
+    105, 66,  247, 89,  128, 59,  14,  139, 20,  191, 9,   15,  170, 172, 154,
+    26,  35,  75,  195, 177, 28,  45,  132, 195, 218, 157, 166, 237, 105, 40,
+    123, 225, 249, 186, 140, 105, 93,  189, 254, 8,   174, 198, 151, 191, 150,
+    234, 76,  151, 24,  174, 35,  0,   63,  138, 27,  86,  102, 67,  61,  203,
+    7,   88,  167, 138, 55,  91,  193, 49,  74,  170, 164, 215, 125, 135, 46,
+    212, 116, 13,  42,  146, 151, 248, 192, 194, 170, 188, 90,  174, 253, 63,
+    229, 116, 193, 176, 93,  194, 128, 72,  91,  47,  228, 146, 132, 26,  35,
+    234, 119, 241, 48,  80,  48,  255, 168, 68,  217, 165, 196, 255, 151, 101,
+    101, 105, 104, 58,  229, 139, 24,  122, 112, 56,  144, 84,  210, 30,  116,
+    199, 210, 71,  186, 253, 216, 150, 40,  168, 88,  155, 169, 76,  152, 241,
+    147, 125, 13,  171, 45,  113, 103, 66,  57,  243, 70,  63,  234, 49,  227,
+    156, 82,  135, 121, 13,  208, 120, 34,  46,  36,  188, 110, 184, 33,  151,
+    48,  146, 145, 135, 36,  1,   209, 246, 58,  149, 135, 192, 88,  8,   8,
+    177, 87,  109, 192, 81,  222, 135, 173, 73,  123, 105, 50,  192, 67,  184,
+    110, 20,  125, 254, 210, 183, 175, 105, 161, 41,  50,  216, 16,  190, 120,
+    140, 29,  67,  131, 212, 216, 247, 102, 136, 239, 198, 26,  161, 108, 166,
+    183, 107, 47,  40,  121, 85,  89,  34,  55,  252, 51,  42,  207, 55,  109,
+    89,  23,  131, 227, 61,  225, 83,  149, 132, 68,  47,  22,  179, 226, 225,
+    156, 93,  85,  39,  164, 127, 243, 137, 205, 82,  231, 180, 15,  129, 207,
+    143, 104, 167, 98,  164, 61,  225, 89,  143, 213, 32,  205, 106, 198, 169,
+    88,  250, 146, 26,  59,  202, 52,  52,  211, 220, 28,  35,  224, 147, 209,
+    209, 36,  118, 60,  38,  47,  118, 105, 192, 51,  71,  172, 169, 90,  132,
+    76,  177, 66,  133, 84,  50,  187, 29,  192, 49,  124, 37,  214, 110, 146,
+    34,  63,  173, 182, 91,  195, 125, 138, 1,   12,  162, 165, 161, 65,  148,
+    76,  104, 226, 232, 185, 100, 32,  160, 129, 18,  50,  242, 19,  221, 109,
+    176, 197, 170, 103, 203, 48,  110, 1,   58,  66,  216, 177, 189, 202, 15,
+    16,  173, 56,  163, 89,  201, 14,  150, 126, 7,   251, 251, 125, 93,  131,
+    242, 30,  180, 89,  46,  142, 70,  101, 183, 10,  170, 209, 42,  167, 101,
+    159, 38,  209, 82,  232, 230, 7,   195, 47,  196, 127, 154, 226, 198, 108,
+    43,  164, 214, 243, 221, 131, 222, 29,  127, 138, 159, 179, 161, 13,  173,
+    94,  178, 227, 179, 180, 184, 164, 244, 189, 169, 80,  4,   222, 78,  171,
+    216, 123, 126, 220, 32,  55,  212, 37,  86,  152, 188, 80,  50,  51,  75,
+    100, 211, 236, 103, 39,  199, 17,  1,   195, 32,  68,  164, 57,  254, 133,
+    128, 0,   93,  148, 21,  169, 126, 45,  15,  151, 244, 145, 161, 251, 202,
+    187, 60,  216, 230, 222, 218, 242, 115, 238, 126, 77,  107, 223, 128, 167,
+    180, 74,  149, 227, 143, 57,  138, 6,   155, 27,  103, 70,  97,  238, 144,
+    26,  41,  108, 66,  95,  140, 50,  65,  153, 180, 190, 149, 144, 88,  100,
+    92,  208, 150, 151, 55,  189, 31,  31,  125, 148, 46,  132, 114, 141, 59,
+    81,  65,  23,  152, 149, 83,  66,  41,  231, 211, 182, 52,  48,  154, 151,
+    111, 82,  13,  41,  95,  8,   90,  100, 231, 186, 212, 188, 127, 65,  208,
+    66,  69,  197, 200, 253, 82,  184, 218, 153, 121, 81,  142, 239, 224, 101,
+    198, 69,  151, 169, 35,  236, 242, 216, 172, 155, 85,  187, 76,  224, 34,
+    156, 92,  106, 7,   45,  161, 67,  134, 254, 112, 195, 88,  247, 155, 123,
+    207, 31,  5,   55,  122, 8,   203, 123, 86,  182, 219, 164, 64,  191, 113,
+    173, 68,  90,  140, 78,  116, 197, 253, 100, 171, 58,  95,  235, 13,  6,
+    77,  55,  97,  150, 155, 58,  67,  206, 249, 122, 189, 4,   4,   253, 49,
+    82,  206, 104, 64,  120, 240, 45,  16,  18,  154, 104, 220, 51,  34,  188,
+    65,  176, 14,  102, 142, 230, 195, 190, 241, 86,  224, 49,  137, 175, 211,
+    128, 21,  113, 56,  164, 132, 164, 90,  122, 41,  213, 234, 28,  107, 145,
+    208, 51,  27,  254, 168, 82,  212, 225, 38,  66,  56,  51,  172, 216, 82,
+    54,  217, 144, 214, 87,  116, 79,  28,  7,   74,  213, 71,  189, 71,  191,
+    111, 236, 161, 71,  205, 234, 125, 214, 55,  168, 0,   203, 107, 176, 184,
+    205, 42,  217, 168, 127, 164, 143, 132, 192, 42,  142, 155, 171, 76,  155,
+    129, 35,  148, 164, 40,  24,  29,  166, 21,  107, 156, 46,  243, 79,  84,
+    165, 68,  57,  241, 132, 158, 137, 71,  53,  242, 65,  143, 123, 4,   79,
+    146, 34,  8,   219, 24,  94,  126, 183, 9,   34,  8,   59,  13,  203, 53,
+    68,  236, 23,  187, 176, 240, 251, 135, 192, 60,  182, 117, 152, 246, 73,
+    218, 158, 190, 110, 157, 62,  237, 131, 230, 137, 95,  223, 114, 24,  254,
+    98,  25,  116, 154, 208, 166, 173, 90,  90,  148, 170, 174, 27,  107, 226,
+    233, 251, 26,  192, 167, 173, 193, 20,  138, 50,  160, 248, 171, 240, 91,
+    188, 42,  136, 108, 41,  117, 150, 61,  248, 207, 96,  130, 108, 167, 68,
+    71,  175, 66,  37,  105, 231, 81,  58,  230, 54,  30,  146, 247, 178, 90,
+    194, 3,   72,  206, 184, 248, 41,  166, 171, 4,   76,  136, 145, 62,  237,
+    242, 98,  110, 196, 5,   103, 232, 94,  180, 159, 10,  198, 121, 248, 118,
+    199, 123, 107, 229, 234, 146, 187, 219, 224, 250, 73,  50,  148, 210, 58,
+    37,  190, 109, 200, 4,   241, 199, 78,  207, 142, 73,  65,  95,  71,  26,
+    38,  127, 214, 55,  80,  106, 86,  199, 112, 34,  130, 97,  85,  235, 245,
+    19,  245, 34,  78,  188, 201, 213, 53,  102, 173, 212, 119, 156, 89,  161,
+    177, 95,  135, 181, 0,   63,  192, 245, 143, 214, 197, 89,  242, 28,  212,
+    210, 23,  151, 16,  133, 237, 58,  39,  33,  79,  5,   72,  210, 10,  3,
+    29,  142, 170, 206, 88,  180, 167, 154, 115, 187, 34,  183, 53,  240, 44,
+    43,  101, 62,  176, 69,  209, 207, 174, 246, 218, 57,  204, 155, 35,  239,
+    213, 41,  46,  123, 153, 136, 85,  50,  29,  212, 2,   160, 34,  195, 138,
+    11,  192, 81,  130, 57,  91,  185, 196, 89,  94,  193, 202, 94,  178, 225,
+    118, 76,  193, 84,  171, 247, 216, 169, 33,  182, 205, 218, 136, 12,  196,
+    88,  239, 47,  48,  228, 112, 223, 216, 150, 119, 230, 161, 69,  229, 122,
+    202, 172, 96,  11,  216, 228, 105, 63,  175, 243, 37,  81,  138, 131, 252,
+    161, 50,  186, 69,  89,  237, 101, 145, 210, 85,  159, 68,  90,  74,  133,
+    10,  62,  41,  98,  253, 65,  231, 62,  117, 236, 127, 26,  229, 117, 139,
+    104, 118, 20,  1,   141, 230, 77,  191, 169, 80,  228, 173, 201, 4,   188,
+    153, 149, 186, 12,  106, 180, 163, 246, 28,  113, 29,  84,  123, 17,  48,
+    129, 140, 130, 121, 189, 126, 149, 213, 255, 86,  31,  228, 198, 155, 41,
+    73,  183, 112, 189, 134, 218, 0,   172, 228, 199, 71,  174, 161, 193, 247,
+    112, 153, 96,  14,  81,  88,  109, 170, 54,  196, 104, 206, 213, 211, 167,
+    226, 252, 132, 174, 162, 186, 135, 115, 234, 21,  197, 209, 69,  196, 124,
+    39,  127, 85,  224, 57,  179, 114, 250, 33,  170, 30,  185, 226, 6,   149,
+    91,  213, 97,  246, 215, 162, 49,  31,  145, 157, 210, 113, 229, 28,  24,
+    34,  74,  37,  26,  203, 215, 2,   18,  156, 37,  31,  154, 219, 97,  25,
+    161, 47,  85,  92,  31,  165, 9,   146, 88,  201, 69,  137, 129, 2,   114,
+    110, 58,  156, 80,  118, 96,  213, 79,  194, 48,  61,  103, 107, 177, 19,
+    97,  142, 235, 51,  161, 227, 188, 162, 119, 194, 150, 229, 75,  67,  36,
+    199, 184, 110, 84,  31,  80,  178, 163, 208, 70,  94,  7,   141, 170, 233,
+    13,  113, 35,  74,  123, 221, 98,  204, 229, 1,   162, 28,  71,  198, 98,
+    160, 45,  29,  215, 194, 251, 193, 69,  136, 117, 218, 94,  9,   189, 218,
+    35,  82,  171, 247, 245, 118, 30,  29,  95,  209, 94,  214, 0,   221, 176,
+    23,  153, 176, 50,  102, 32,  86,  13,  237, 241, 37,  4,   193, 180, 254,
+    104, 203, 118, 188, 14,  251, 224, 139, 195, 154, 136, 251, 65,  173, 230,
+    77,  23,  249, 149, 171, 189, 176, 237, 109, 94,  233, 41,  50,  27,  140,
+    32,  125, 234, 160, 4,   138, 180, 206, 159, 253, 38,  241, 234, 177, 46,
+    247, 237, 10,  123, 60,  116, 130, 182, 164, 238, 137, 40,  13,  139, 62,
+    102, 144, 200, 189, 122, 22,  49,  237, 16,  238, 52,  203, 9,   226, 205,
+    24,  94,  227, 197, 242, 186, 207, 21,  251, 133, 139, 184, 228, 16,  9,
+    92,  175, 72,  60,  208, 5,   177, 172, 64,  194, 166, 122, 60,  88,  129,
+    252, 231, 167, 138, 35,  192, 26,  215, 171, 185, 36,  83,  208, 179, 234,
+    19,  193, 64,  254, 253, 179, 73,  64,  178, 23,  124, 96,  81,  160, 191,
+    140, 30,  71,  3,   119, 39,  47,  83,  127, 157, 137, 165, 210, 24,  213,
+    212, 247, 189, 228, 45,  138, 56,  79,  126, 202, 252, 111, 149, 169, 126,
+    96,  25,  124, 136, 57,  172, 186, 253, 216, 147, 168, 93,  57,  58,  23,
+    171, 43,  203, 54,  241, 202, 13,  66,  238, 24,  33,  114, 0,   109, 77,
+    63,  173, 175, 240, 70,  90,  109, 132, 244, 228, 95,  65,  208, 137, 199,
+    192, 42,  41,  174, 97,  251, 161, 37,  136, 201, 94,  70,  134, 5,   207,
+    105, 6,   224, 13,  8,   115, 130, 15,  236, 142, 191, 75,  148, 134, 35,
+    5,   9,   241, 7,   101, 215, 60,  9,   45,  84,  77,  3,   154, 106, 228,
+    31,  25,  78,  29,  157, 67,  168, 30,  254, 233, 136, 115, 187, 237, 224,
+    222, 18,  91,  82,  238, 248, 201, 149, 134, 135, 76,  56,  217, 119, 86,
+    122, 199, 54,  53,  43,  52,  43,  122, 234, 180, 154, 0,   171, 145, 25,
+    230, 205, 178, 189, 200, 200, 224, 98,  206, 241, 129, 156, 202, 226, 254,
+    132, 192, 162, 229, 140, 220, 241, 145, 233, 91,  209, 91,  240, 175, 103,
+    46,  94,  252, 174, 69,  26,  246, 131, 63,  178, 227, 165, 105, 86,  87,
+    145, 2,   186, 137, 196, 54,  149, 232, 203, 244, 120, 193, 214, 63,  86,
+    168, 236, 162, 189, 246, 45,  142, 109, 192, 77,  198, 177, 110, 120, 232,
+    220, 49,  232, 231, 86,  179, 104, 144, 164, 215, 224, 187, 67,  244, 45,
+    69,  67,  116, 133, 82,  121, 121, 159, 126, 56,  147, 130, 144, 255, 64,
+    230, 229, 165, 232, 0,   154, 53,  57,  97,  121, 178, 248, 122, 11,  121,
+    16,  78,  198, 44,  143, 94,  253, 240, 98,  198, 105, 84,  104, 244, 168,
+    232, 236, 247, 52,  242, 119, 56,  33,  22,  254, 63,  69,  138, 59,  4,
+    249, 165, 111, 166, 105, 186, 106, 62,  164, 188, 109, 163, 150, 80,  102,
+    42,  25,  233, 112, 161, 174, 178, 229, 54,  218, 17,  118, 148, 149, 52,
+    232, 199, 208, 50,  157, 11,  235, 191, 68,  218, 21,  68,  136, 6,   124,
+    160, 98,  237, 156, 145, 5,   60,  109, 138, 194, 12,  127, 86,  102, 176,
+    25,  154, 99,  232, 30,  105, 65,  110, 171, 234, 234, 193, 248, 14,  135,
+    17,  197, 151, 122, 55,  96,  188, 154, 142, 82,  103, 26,  151, 246, 50,
+    209, 167, 233, 82,  220, 46,  115, 54,  103, 61,  69,  132, 64,  160, 79,
+    44,  121, 27,  69,  122, 129, 216, 252, 129, 234, 17,  126, 111, 152, 97,
+    169, 149, 44,  34,  78,  46,  34,  23,  154, 204, 72,  223, 222, 73,  189,
+    167, 194, 125, 121, 62,  249, 97,  227, 20,  57,  123, 0,   9,   198, 126,
+    137, 190, 151, 233, 220, 29,  223, 91,  247, 198, 74,  37,  23,  195, 222,
+    166, 100, 71,  143, 205, 136, 204, 5,   117, 144, 182, 57,  31,  71,  116,
+    58,  245, 21,  227, 197, 227, 172, 31,  139, 114, 86,  43,  84,  11,  197,
+    95,  239, 229, 62,  206, 86,  181, 109, 53,  52,  82,  68,  129, 108, 201,
+    230, 254, 125, 104, 111, 225, 53,  138, 45,  212, 11,  244, 116, 249, 163,
+    68,  33,  144, 142, 5,   72,  46,  160, 138, 199, 48,  212, 60,  152, 124,
+    188, 243, 139, 171, 216, 171, 25,  22,  107, 88,  221, 63,  159, 181, 156,
+    151, 240, 97,  179, 106, 120, 13,  183, 174, 249, 68,  222, 233, 140, 112,
+    144, 171, 179, 225, 125, 223, 162, 205, 169, 121, 227, 110, 115, 70,  25,
+    2,   124, 118, 188, 221, 180, 140, 221, 177, 10,  120, 131, 247, 246, 251,
+    161, 85,  213, 203, 65,  146, 53,  122, 234, 90,  240, 69,  36,  51,  112,
+    139, 155, 9,   231, 25,  245, 86,  17,  66,  218, 91,  210, 20,  198, 66,
+    15,  45,  103, 207, 185, 141, 123, 192, 158, 20,  143, 159, 94,  126, 201,
+    85,  91,  227, 192, 36,  237, 21,  102, 17,  166, 138, 242, 7,   204, 83,
+    16,  102, 167, 167, 176, 244, 139, 213, 183, 183, 145, 110, 97,  214, 36,
+    1,   120, 221, 117, 240, 144, 100, 184, 149, 12,  202, 172, 108, 0,   239,
+    72,  106, 38,  58,  10,  79,  169, 82,  208, 172, 128, 252, 169, 47,  7,
+    45,  143, 135, 174, 139, 158, 12,  192, 197, 200, 238, 164, 244, 24,  121,
+    88,  221, 138, 2,   61,  231, 97,  68,  194, 173, 86,  164, 104, 144, 63,
+    250, 224, 212, 59,  250, 191, 56,  200, 235, 204, 1,   133, 68,  50,  69,
+    85,  49,  184, 17,  15,  246, 67,  236, 11,  1,   189, 189, 164, 35,  137,
+    234, 35,  75,  42,  156, 141, 32,  32,  202, 194, 48,  223, 119, 198, 123,
+    210, 49,  136, 249, 172, 23,  85,  134, 86,  232, 215, 216, 87,  75,  13,
+    88,  103, 38,  129, 42,  50,  195, 129, 121, 16,  100, 189, 153, 128, 20,
+    152, 183, 161, 26,  239, 88,  146, 207, 249, 36,  100, 103, 17,  177, 223,
+    219, 241, 188, 55,  176, 245, 103, 36,  43,  50,  19,  134, 72,  90,  138,
+    147, 194, 229, 113, 3,   126, 78,  95,  242, 231, 198, 80,  78,  77,  18,
+    251, 155, 10,  224, 23,  184, 184, 80,  103, 150, 52,  215, 74,  170, 54,
+    233, 34,  28,  116, 154, 175, 8,   7,   189, 31,  234, 183, 207, 88,  86,
+    112, 49,  71,  52,  160, 111, 255, 125, 17,  140, 110, 239, 212, 217, 118,
+    67,  33,  222, 136, 14,  94,  186, 60,  174, 141, 240, 6,   160, 246, 139,
+    25,  36,  212, 195, 148, 158, 232, 202, 147, 135, 239, 132, 19,  1,   181,
+    64,  119, 108, 12,  187, 156, 239, 171, 123, 112, 204, 66,  6,   65,  152,
+    132, 55,  58,  53,  62,  212, 172, 84,  134, 30,  89,  214, 197, 79,  231,
+    86,  131, 88,  7,   149, 177, 115, 196, 131, 213, 11,  182, 28,  251, 183,
+    174, 44,  225, 28,  211, 94,  44,  153, 112, 41,  179, 170, 230, 131, 120,
+    254, 204, 79,  71,  107, 151, 166, 236, 170, 78,  197, 64,  152, 44,  203,
+    56,  227, 34,  43,  204, 38,  63,  189, 176, 67,  160, 2,   220, 101, 38,
+    122, 87,  94,  102, 13,  74,  25,  99,  92,  187, 143, 95,  249, 210, 71,
+    42,  209, 179, 20,  168, 190, 80,  197, 231, 248, 141, 99,  24,  30,  109,
+    97,  9,   39,  61,  241, 128, 55,  122, 139, 185, 131, 142, 228, 141, 87,
+    43,  90,  159, 143, 246, 202, 229, 118, 149, 158, 220, 77,  125, 159, 166,
+    165, 7,   157, 74,  39,  229, 83,  88,  10,  49,  183, 51,  86,  161, 129,
+    240, 21,  188, 197, 14,  31,  53,  119, 182, 114, 89,  35,  0,   4,   19,
+    201, 209, 61,  158, 167, 228, 83,  22,  255, 12,  116, 184, 249, 20,  184,
+    74,  169, 147, 107, 11,  58,  228, 83,  143, 96,  192, 29,  240, 9,   81,
+    1,   255, 176, 165, 219, 202, 149, 99,  246, 187, 229, 24,  12,  206, 238,
+    147, 107, 124, 253, 216, 35,  155, 77,  36,  253, 140, 93,  241, 207, 175,
+    51,  225, 39,  150, 137, 251, 26,  62,  24,  96,  219, 194, 181, 78,  109,
+    179, 15,  147, 224, 68,  99,  201, 171, 122, 6,   169, 105, 145, 22,  11,
+    233, 98,  42,  253, 14,  146, 70,  229, 100, 236, 62,  227, 100, 214, 164,
+    188, 76,  67,  82,  81,  221, 51,  206, 222, 193, 150, 217, 155, 25,  87,
+    87,  60,  59,  121, 50,  149, 104, 201, 98,  70,  139, 247, 110, 162, 52,
+    53,  5,   211, 215, 134, 253, 166, 255, 34,  141, 86,  37,  80,  143, 64,
+    39,  174, 72,  115, 124, 128, 116, 157, 19,  19,  186, 237, 213, 205, 167,
+    20,  67,  63,  154, 100, 17,  248, 3,   182, 251, 215, 90,  158, 228, 35,
+    28,  133, 178, 123, 37,  126, 5,   248, 203, 241, 158, 116, 168, 88,  86,
+    235, 220, 115, 26,  95,  95,  41,  101, 169, 162, 18,  56,  112, 185, 29,
+    150, 242, 232, 103, 182, 227, 92,  30,  144, 52,  12,  221, 213, 187, 80,
+    107, 42,  138, 212, 49,  92,  171, 15,  37,  121, 35,  220, 126, 215, 104,
+    161, 174, 159, 60,  195, 224, 139, 194, 229, 108, 208, 253, 126, 34,  218,
+    228, 35,  69,  250, 244, 30,  195, 65,  90,  217, 151, 234, 64,  99,  183,
+    106, 179, 159, 117, 214, 248, 125, 137, 10,  254, 59,  1,   181, 175, 100,
+    216, 145, 84,  199, 93,  32,  21,  13,  149, 131, 129, 154, 130, 114, 230,
+    146, 46,  45,  79,  39,  41,  204, 66,  39,  116, 0,   220, 127, 59,  138,
+    193, 97,  63,  175, 141, 228, 118, 177, 75,  241, 81,  201, 144, 208, 5,
+    205, 175, 142, 172, 124, 57,  125, 123, 229, 176, 11,  170, 205, 216, 85,
+    187, 60,  239, 36,  232, 158, 43,  175, 181, 220, 213, 249, 150, 152, 150,
+    24,  158, 234, 72,  237, 98,  187, 32,  62,  142, 63,  83,  238, 11,  54,
+    166, 61,  74,  57,  182, 115, 58,  118, 5,   122, 220, 230, 206, 55,  82,
+    102, 95,  81,  115, 230, 194, 86,  43,  118, 61,  16,  73,  52,  100, 57,
+    131, 51,  125, 148, 36,  84,  20,  163, 92,  198, 166, 129, 241, 129, 114,
+    243, 70,  250, 140, 172, 0,   198, 237, 103, 166, 44,  226, 221, 83,  37,
+    167, 10,  156, 53,  235, 202, 183, 223, 192, 15,  172, 155, 253, 132, 171,
+    102, 250, 26,  219, 110, 79,  92,  177, 125, 169, 255, 188, 67,  93,  141,
+    157, 42,  161, 197, 154, 208, 140, 32,  191, 152, 135, 137, 23,  186, 117,
+    71,  235, 92,  164, 56,  177, 58,  51,  135, 32,  196, 143, 185, 238, 23,
+    110, 145, 72,  85,  91,  187, 153, 7,   226, 111, 44,  41,  190, 34,  184,
+    235, 50,  8,   182, 2,   248, 41,  19,  44,  139, 198, 193, 69,  172, 139,
+    89,  216, 231, 118, 116, 92,  76,  130, 140, 240, 164, 193, 103, 47,  12,
+    144, 34,  172, 183, 203, 132, 242, 19,  202, 112, 135, 33,  9,   253, 96,
+    129, 0,   232, 24,  16,  188, 63,  178, 0,   174, 120, 158, 8,   171, 152,
+    59,  198, 243, 21,  46,  61,  216, 167, 83,  34,  210, 22,  51,  113, 137,
+    231, 250, 50,  208, 196, 68,  191, 110, 29,  25,  158, 220, 200, 74,  66,
+    144, 99,  167, 9,   104, 55,  95,  126, 5,   61,  232, 112, 166, 84,  88,
+    82,  163, 85,  161, 217, 228, 204, 225, 186, 129, 138, 212, 81,  132, 2,
+    225, 85,  173, 63,  208, 122, 152, 127, 146, 241, 67,  74,  213, 32,  41,
+    22,  125, 68,  200, 208, 46,  208, 20,  14,  244, 39,  11,  89,  159, 206,
+    37,  217, 33,  55,  68,  132, 31,  11,  132, 37,  230, 164, 84,  98,  176,
+    226, 247, 24,  212, 161, 109, 36,  15,  218, 102, 157, 227, 60,  137, 182,
+    90,  29,  56,  19,  82,  76,  5,   224, 26,  128, 152, 105, 101, 33,  145,
+    184, 165, 129, 174, 174, 236, 162, 97,  65,  172, 216, 148, 156, 64,  52,
+    71,  199, 13,  128, 183, 241, 204, 114, 92,  54,  167, 94,  127, 121, 143,
+    17,  171, 81,  192, 69,  219, 173, 136, 219, 121, 130, 111, 30,  230, 228,
+    191, 153, 95,  54,  34,  241, 184, 199, 176, 142, 85,  90,  168, 189, 135,
+    103, 3,   107, 28,  230, 245, 184, 232, 107, 125, 117, 120, 199, 110, 19,
+    213, 156, 146, 31,  196, 186, 17,  71,  143, 241, 217, 196, 196, 125, 40,
+    151, 195, 150, 60,  232, 117, 171, 104, 158, 167, 36,  95,  209, 103, 53,
+    54,  233, 85,  121, 115, 53,  209, 141, 130, 124, 88,  138, 220, 175, 183,
+    139, 153, 45,  197, 111, 209, 29,  29,  221, 235, 105, 87,  154, 19,  31,
+    235, 196, 126, 34,  54,  5,   8,   222, 200, 62,  80,  38,  110, 91,  134,
+    251, 46,  3,   210, 1,   187, 197, 47,  109, 161, 181, 151, 75,  245, 220,
+    53,  52,  174, 221, 17,  148, 161, 82,  157, 182, 32,  148, 45,  165, 128,
+    218, 116, 224, 17,  13,  133, 232, 21,  51,  112, 190, 37,  29,  46,  45,
+    68,  24,  5,   29,  137, 237, 133, 74,  85,  84,  234, 157, 249, 51,  173,
+    234, 136, 6,   200, 208, 108, 63,  100, 18,  103, 38,  193, 242, 150, 153,
+    102, 86,  126, 148, 121, 174, 172, 228, 247, 23,  217, 89,  2,   67,  224,
+    99,  145, 101, 22,  127, 248, 202, 169, 53,  12,  228, 126, 195, 35,  231,
+    140, 254, 155, 70,  193, 92,  78,  11,  78,  127, 32,  63,  159, 26,  28,
+    125, 219, 200, 176, 213, 250, 170, 172, 121, 13,  30,  102, 191, 179, 236,
+    161, 84,  79,  16,  64,  31,  20,  186, 167, 47,  151, 75,  94,  110, 121,
+    54,  248, 228, 253, 71,  1,   16,  70,  135, 235, 44,  20,  127, 255, 229,
+    237, 52,  11,  162, 70,  206, 208, 140, 37,  123, 235, 71,  205, 142, 42,
+    85,  239, 252, 189, 80,  252, 181, 209, 52,  98,  97,  136, 44,  133, 184,
+    79,  56,  29,  73,  46,  5,   38,  76,  125, 180, 114, 211, 154, 126, 190,
+    225, 202, 169, 145, 228, 82,  25,  251, 62,  135, 37,  175, 145, 5,   190,
+    158, 21,  69,  178, 175, 234, 156, 124, 118, 80,  181, 158, 165, 131, 39,
+    17,  200, 86,  109, 118, 78,  128, 23,  131, 161, 93,  101, 236, 82,  69,
+    49,  71,  55,  221, 222, 137, 20,  82,  67,  142, 231, 95,  156, 55,  230,
+    244, 240, 57,  154, 203, 246, 190, 145, 111, 124, 60,  170, 42,  126, 191,
+    176, 142, 116, 28,  152, 106, 154, 214, 45,  196, 86,  223, 10,  193, 239,
+    187, 151, 121, 76,  79,  84,  224, 171, 227, 141, 56,  207, 201, 84,  39,
+    166, 68,  72,  0,   99,  85,  130, 67,  9,   16,  229, 241, 164, 144, 58,
+    81,  8,   247, 233, 118, 141, 68,  149, 210, 141, 27,  7,   101, 205, 244,
+    223, 169, 9,   15,  35,  77,  120, 94,  109, 69,  47,  245, 180, 127, 194,
+    157, 93,  103, 205, 12,  39,  117, 234, 67,  158, 185, 40,  210, 24,  207,
+    247, 75,  150, 87,  214, 67,  67,  142, 219, 110, 82,  81,  83,  238, 149,
+    210, 107, 249, 241, 151, 240, 23,  72,  128, 185, 164, 149, 29,  112, 135,
+    192, 176, 165, 209, 171, 147, 193, 54,  206, 213, 0,   178, 193, 193, 163,
+    226, 205, 253, 170, 251, 208, 29,  154, 18,  33,  62,  136, 241, 58,  208,
+    245, 219, 70,  7,   133, 2,   234, 211, 175, 230, 142, 9,   135, 9,   35,
+    45,  152, 145, 82,  171, 13,  2,   52,  190, 223, 177, 37,  89,  138, 55,
+    155, 127, 47,  67,  210, 13,  189, 44,  245, 199, 32,  20,  92,  27,  61,
+    252, 46,  206, 58,  119, 140, 208, 18,  191, 63,  226, 175, 135, 223, 63,
+    178, 195, 89,  72,  0,   47,  105, 251, 131, 240, 131, 104, 215, 29,  192,
+    164, 157, 66,  149, 39,  168, 193, 113, 233, 29,  166, 241, 95,  83,  169,
+    31,  5,   104, 104, 139, 164, 203, 14,  153, 145, 85,  99,  60,  153, 205,
+    192, 101, 158, 191, 38,  149, 153, 9,   147, 66,  12,  45,  251, 169, 174,
+    138, 41,  99,  227, 121, 41,  8,   3,   15,  62,  124, 19,  136, 135, 104,
+    174, 111, 254, 53,  16,  43,  119, 42,  97,  31,  139, 228, 116, 195, 105,
+    249, 57,  17,  98,  163, 213, 209, 99,  81,  56,  190, 150, 239, 105, 246,
+    165, 74,  13,  159, 6,   100, 102, 56,  202, 1,   106, 137, 182, 141, 100,
+    10,  132, 224, 136, 119, 167, 222, 230, 43,  193, 248, 174, 39,  227, 75,
+    43,  65,  169, 94,  118, 212, 60,  161, 240, 84,  66,  244, 42,  83,  153,
+    218, 200, 97,  102, 208, 153, 207, 67,  19,  197, 70,  229, 61,  208, 255,
+    86,  112, 222, 181, 169, 61,  209, 175, 198, 37,  165, 29,  148, 19,  49,
+    53,  253, 231, 75,  135, 188, 249, 147, 90,  250, 148, 182, 125, 109, 80,
+    61,  142, 244, 90,  177, 184, 56,  47,  56,  47,  67,  72,  157, 47,  206,
+    79,  144, 6,   9,   219, 75,  73,  197, 78,  113, 170, 153, 75,  39,  29,
+    99,  178, 93,  20,  92,  50,  173, 87,  44,  146, 120, 65,  76,  121, 233,
+    253, 124, 43,  247, 124, 224, 99,  176, 208, 1,   255, 83,  199, 173, 57,
+    47,  144, 193, 60,  68,  212, 122, 230, 160, 140, 215, 68,  20,  187, 241,
+    205, 16,  36,  17,  177, 182, 227, 6,   23,  41,  102, 247, 93,  136, 234,
+    228, 136, 4,   1,   130, 187, 191, 28,  104, 250, 249, 98,  25,  254, 198,
+    169, 75,  181, 199, 71,  122, 35,  47,  242, 153, 151, 107, 174, 67,  183,
+    18,  89,  156, 190, 252, 85,  172, 110, 95,  56,  31,  21,  92,  54,  104,
+    177, 40,  96,  169, 51,  73,  203, 201, 26,  199, 59,  21,  197, 199, 128,
+    161, 25,  176, 92,  3,   70,  33,  167, 2,
+    kMagicSuffix[0], kMagicSuffix[1], kMagicSuffix[2], kMagicSuffix[3]
+};
+// clang-format on
+
+#endif  // TOOLS_ANDROID_ELF_COMPRESSION_TEST_LIBTEST_ARRAY_H_
diff --git a/tools/android/elf_compression/test/run_tests.py b/tools/android/elf_compression/test/run_tests.py
new file mode 100755
index 0000000..bb816aa3
--- /dev/null
+++ b/tools/android/elf_compression/test/run_tests.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import unittest
+
+TESTS = [
+    'compression_script_test',
+    'elf_headers_test',
+]
+
+if __name__ == '__main__':
+  suite = unittest.TestSuite()
+  suite.addTests(unittest.defaultTestLoader.loadTestsFromNames(TESTS))
+  unittest.TextTestRunner().run(suite)
diff --git a/tools/android/elf_compression/test/testdata/lib.c b/tools/android/elf_compression/test/testdata/lib.c
new file mode 100644
index 0000000..1e2e8e4
--- /dev/null
+++ b/tools/android/elf_compression/test/testdata/lib.c
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a source code of lib.so file located in this directory. This file
+// serves as a testdata for testing elf_headers.py. We need to store .so
+// precompiled and not build it on demand since we can't rely on resulting ELF
+// structure not changing between different compilations or due to change in
+// clang version.
+//
+// The library was build with the following command:
+//    clang lib.c -shared -fPIC -O2 -o lib.so
+//
+// This library is intentionally very small to both ensure the speed of the test
+// and to not add huge binary file into source control system.
+
+int array[3] = {1, 2, 3};
+
+int GetSum() {
+  return array[0] + array[1] + array[2];
+}
diff --git a/tools/android/elf_compression/test/testdata/lib.so b/tools/android/elf_compression/test/testdata/lib.so
new file mode 100755
index 0000000..e207f1f
--- /dev/null
+++ b/tools/android/elf_compression/test/testdata/lib.so
Binary files differ
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 6729517..260cb7a 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -2708,6 +2708,7 @@
   <int value="20" label="Disabled"/>
   <int value="21" label="Already provisioned"/>
   <int value="22" label="Unsupported account type"/>
+  <int value="23" label="Account is not present in Chrome"/>
 </enum>
 
 <enum name="ArcSdkVersionUpgradeType">
@@ -18012,7 +18013,8 @@
   <int value="598" label="RendererCodeIntegrityEnabled"/>
   <int value="599" label="DeviceLoginScreenLargeCursorEnabled"/>
   <int value="600" label="DomainsToCheckForMalwareOfUploadedContent"/>
-  <int value="601" label="HSTSPolicyBlocklist"/>
+  <int value="601" label="HSTSPolicyBypassList"/>
+  <int value="602" label="ReportDeviceOsUpdateStatus"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -24615,6 +24617,8 @@
   <int value="3027" label="PointerLockUnadjustedMovement"/>
   <int value="3028" label="CreateObjectBlob"/>
   <int value="3029" label="QuotaRead"/>
+  <int value="3030" label="DelegateFocus"/>
+  <int value="3031" label="DelegateFocusNotFirstInFlatTree"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -59856,7 +59860,7 @@
   <int value="18" label="kSafeBrowsingIncidentsSent"/>
   <int value="19" label="kSwReporterPromptVersion"/>
   <int value="20" label="kSwReporterPromptReason"/>
-  <int value="21" label="kGoogleServicesUsername"/>
+  <int value="21" label="kGoogleServicesUsername (Obsolete 9/2019)"/>
   <int value="22" label="kSwReporterPromptSeed"/>
   <int value="23" label="kGoogleServicesAccountId"/>
   <int value="24" label="kGoogleServicesLastAccountId"/>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 045d10a..9072a298 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -270,7 +270,7 @@
 crbug.com/954948 [ android-webview ] rendering.mobile/cnn_mobile_pinch_2018 [ Skip ]
 crbug.com/966637 [ android-pixel-2 android-webview ] rendering.mobile/google_news_mobile_2018 [ Skip ]
 crbug.com/967809 [ android-webview ] rendering.mobile/microsoft_video_city [ Skip ]
-crbug.com/1000473 [ android-webview ] rendering.mobile/balls_svg_animations [ Skip ]
+crbug.com/1000473 [ android ] rendering.mobile/balls_svg_animations [ Skip ]
 
 # Benchmark: rasterize_and_record_micro.top_25
 crbug.com/764543 rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
@@ -339,8 +339,6 @@
 crbug.com/959418 [ chromeos ] system_health.memory_desktop/long_running:tools:gmail-background [ Skip ]
 crbug.com/959418 [ chromeos ] system_health.memory_desktop/load:games:spychase:2018 [ Skip ]
 crbug.com/959418 [ chromeos ] system_health.memory_desktop/long_running:tools:gmail-foreground [ Skip ]
-crbug.com/999004 [ linux ] system_health.memory_desktop/load:news:bbc:2018 [ Skip ]
-crbug.com/999004 [ mac ] system_health.memory_desktop/load:news:bbc:2018 [ Skip ]
 
 # Benchmark: system_health.memory_mobile
 crbug.com/914390 [ android-nexus-5 ] system_health.memory_mobile/browse:chrome:newtab [ Skip ]
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 66c6bb7..2dc0a86 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -18,6 +18,7 @@
 #include "base/debug/leak_annotations.h"
 #include "base/memory/protected_memory_cfi.h"
 #include "base/no_destructor.h"
+#include "base/numerics/ranges.h"
 #include "base/optional.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -869,8 +870,7 @@
     end_offset = text.size();
   } else {
     end_offset = obj->UnicodeToUTF16OffsetInText(end_offset);
-    end_offset = std::max(start_offset,
-                          std::min(end_offset, static_cast<int>(text.size())));
+    end_offset = base::ClampToRange(int{text.size()}, start_offset, end_offset);
   }
 
   DCHECK_GE(start_offset, 0);
@@ -900,7 +900,7 @@
   int32_t text_length = text.length();
 
   offset = obj->UnicodeToUTF16OffsetInText(offset);
-  int32_t limited_offset = std::max(0, std::min(text_length, offset));
+  int32_t limited_offset = base::ClampToRange(offset, 0, text_length);
 
   uint32_t code_point;
   base::ReadUnicodeCharacter(text.c_str(), text_length + 1, &limited_offset,
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index bdf5b47..70139ee1 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -7,6 +7,7 @@
 #include <unordered_map>
 #include <utility>
 
+#include "base/numerics/ranges.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/accessibility/ax_action_data.h"
@@ -487,9 +488,9 @@
       int scroll_y_max =
           GetData().GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
       int scroll_x =
-          std::max(scroll_x_min, std::min(data.target_point.x(), scroll_x_max));
+          base::ClampToRange(data.target_point.x(), scroll_x_min, scroll_x_max);
       int scroll_y =
-          std::max(scroll_y_min, std::min(data.target_point.y(), scroll_y_max));
+          base::ClampToRange(data.target_point.y(), scroll_y_min, scroll_y_max);
 
       ReplaceIntAttribute(node_->id(), ax::mojom::IntAttribute::kScrollX,
                           scroll_x);
diff --git a/ui/base/ime/linux/composition_text_util_pango.cc b/ui/base/ime/linux/composition_text_util_pango.cc
index 71c8ad3..cf75310 100644
--- a/ui/base/ime/linux/composition_text_util_pango.cc
+++ b/ui/base/ime/linux/composition_text_util_pango.cc
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include "base/i18n/char_iterator.h"
+#include "base/numerics/ranges.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/base/ime/composition_text.h"
@@ -40,7 +41,7 @@
   char16_offsets.push_back(length);
 
   size_t cursor_offset =
-      char16_offsets[std::max(0, std::min(char_length, cursor_position))];
+      char16_offsets[base::ClampToRange(cursor_position, 0, char_length)];
 
   composition->selection = gfx::Range(cursor_offset);
 
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc
index 069a7ca..4329d18a 100644
--- a/ui/base/ime/win/tsf_text_store.cc
+++ b/ui/base/ime/win/tsf_text_store.cc
@@ -11,6 +11,7 @@
 
 #include <algorithm>
 
+#include "base/numerics/ranges.h"
 #include "base/win/scoped_variant.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/base/ime/win/tsf_input_scope.h"
@@ -461,9 +462,9 @@
   const LONG composition_start = static_cast<LONG>(composition_start_);
   const LONG buffer_size = static_cast<LONG>(string_buffer_document_.size());
   *acp_result_start =
-      std::min(std::max(composition_start, acp_test_start), buffer_size);
+      base::ClampToRange(acp_test_start, composition_start, buffer_size);
   *acp_result_end =
-      std::min(std::max(composition_start, acp_test_end), buffer_size);
+      base::ClampToRange(acp_test_end, composition_start, buffer_size);
   return S_OK;
 }
 
diff --git a/ui/base/mpris/BUILD.gn b/ui/base/mpris/BUILD.gn
index 3177b41..f75dd8c6 100644
--- a/ui/base/mpris/BUILD.gn
+++ b/ui/base/mpris/BUILD.gn
@@ -16,6 +16,7 @@
   deps = [
     "//base",
     "//build:branding_buildflags",
+    "//components/dbus/properties",
     "//components/dbus/thread_linux",
     "//dbus",
   ]
diff --git a/ui/base/mpris/mpris_service_impl.cc b/ui/base/mpris/mpris_service_impl.cc
index 648a0bc..12af8d0 100644
--- a/ui/base/mpris/mpris_service_impl.cc
+++ b/ui/base/mpris/mpris_service_impl.cc
@@ -9,25 +9,27 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/singleton.h"
 #include "base/process/process.h"
-#include "base/unguessable_token.h"
-#include "base/values.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
 #include "build/branding_buildflags.h"
+#include "components/dbus/properties/dbus_properties.h"
+#include "components/dbus/properties/success_barrier_callback.h"
 #include "components/dbus/thread_linux/dbus_thread_linux.h"
 #include "dbus/bus.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
-#include "dbus/values_util.h"
 #include "ui/base/mpris/mpris_service_observer.h"
 
 namespace mpris {
 
 namespace {
 
-constexpr int kDebounceTimeoutMilliseconds = 50;
-constexpr int kNumMethodsToExport = 14;
+constexpr int kNumMethodsToExport = 11;
 
 }  // namespace
 
@@ -38,9 +40,7 @@
 
 MprisServiceImpl::MprisServiceImpl()
     : service_name_(std::string(kMprisAPIServiceNamePrefix) +
-                    std::to_string(base::Process::Current().Pid())) {
-  InitializeProperties();
-}
+                    base::NumberToString(base::Process::Current().Pid())) {}
 
 MprisServiceImpl::~MprisServiceImpl() {
   if (bus_) {
@@ -66,57 +66,54 @@
 }
 
 void MprisServiceImpl::SetCanGoNext(bool value) {
-  SetPropertyInternal(media_player2_player_properties_, "CanGoNext",
-                      base::Value(value));
+  properties_->SetProperty(kMprisAPIPlayerInterfaceName, "CanGoNext",
+                           DbusBoolean(value));
 }
 
 void MprisServiceImpl::SetCanGoPrevious(bool value) {
-  SetPropertyInternal(media_player2_player_properties_, "CanGoPrevious",
-                      base::Value(value));
+  properties_->SetProperty(kMprisAPIPlayerInterfaceName, "CanGoPrevious",
+                           DbusBoolean(value));
 }
 
 void MprisServiceImpl::SetCanPlay(bool value) {
-  SetPropertyInternal(media_player2_player_properties_, "CanPlay",
-                      base::Value(value));
+  properties_->SetProperty(kMprisAPIPlayerInterfaceName, "CanPlay",
+                           DbusBoolean(value));
 }
 
 void MprisServiceImpl::SetCanPause(bool value) {
-  SetPropertyInternal(media_player2_player_properties_, "CanPause",
-                      base::Value(value));
+  properties_->SetProperty(kMprisAPIPlayerInterfaceName, "CanPause",
+                           DbusBoolean(value));
 }
 
 void MprisServiceImpl::SetPlaybackStatus(PlaybackStatus value) {
-  base::Value status;
-  switch (value) {
-    case PlaybackStatus::kPlaying:
-      status = base::Value("Playing");
-      break;
-    case PlaybackStatus::kPaused:
-      status = base::Value("Paused");
-      break;
-    case PlaybackStatus::kStopped:
-      status = base::Value("Stopped");
-      break;
-  }
-  SetPropertyInternal(media_player2_player_properties_, "PlaybackStatus",
-                      status);
+  auto status = [&]() {
+    switch (value) {
+      case PlaybackStatus::kPlaying:
+        return DbusString("Playing");
+      case PlaybackStatus::kPaused:
+        return DbusString("Paused");
+      case PlaybackStatus::kStopped:
+        return DbusString("Stopped");
+    }
+  };
+  properties_->SetProperty(kMprisAPIPlayerInterfaceName, "PlaybackStatus",
+                           status());
 }
 
 void MprisServiceImpl::SetTitle(const base::string16& value) {
-  SetMetadataPropertyInternal("xesam:title", base::Value(value));
+  SetMetadataPropertyInternal(
+      "xesam:title", MakeDbusVariant(DbusString(base::UTF16ToUTF8(value))));
 }
 
 void MprisServiceImpl::SetArtist(const base::string16& value) {
-  // xesam:artist is actually supposed to be a list of strings, but base::Value
-  // only supports lists of base::Value, which makes this difficult to correctly
-  // propagate to |AddPropertiesToWriter()|. Instead, we'll only track the
-  // string in |media_player2_player_properties_| and special-case within
-  // |AddPropertiesToWriter()|.
-  SetMetadataPropertyInternal("xesam:artist", base::Value(value));
+  SetMetadataPropertyInternal(
+      "xesam:artist",
+      MakeDbusVariant(MakeDbusArray(DbusString(base::UTF16ToUTF8(value)))));
 }
 
 void MprisServiceImpl::SetAlbum(const base::string16& value) {
-  SetMetadataPropertyInternal("xesam:album", base::Value(value));
+  SetMetadataPropertyInternal(
+      "xesam:album", MakeDbusVariant(DbusString(base::UTF16ToUTF8(value))));
 }
 
 std::string MprisServiceImpl::GetServiceName() const {
@@ -125,35 +122,41 @@
 
 void MprisServiceImpl::InitializeProperties() {
   // org.mpris.MediaPlayer2 interface properties.
-  media_player2_properties_["CanQuit"] = base::Value(false);
-  media_player2_properties_["CanRaise"] = base::Value(false);
-  media_player2_properties_["HasTrackList"] = base::Value(false);
+  auto set_property = [&](const std::string& property_name, auto&& value) {
+    properties_->SetProperty(kMprisAPIInterfaceName, property_name,
+                             std::move(value), false);
+  };
+  set_property("CanQuit", DbusBoolean(false));
+  set_property("CanRaise", DbusBoolean(false));
+  set_property("HasTrackList", DbusBoolean(false));
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-  media_player2_properties_["Identity"] = base::Value("Chrome");
+  set_property("Identity", DbusString("Chrome"));
 #else
-  media_player2_properties_["Identity"] = base::Value("Chromium");
+  set_property("Identity", DbusString("Chromium"));
 #endif
-  media_player2_properties_["SupportedUriSchemes"] =
-      base::Value(base::Value::Type::LIST);
-  media_player2_properties_["SupportedMimeTypes"] =
-      base::Value(base::Value::Type::LIST);
+  set_property("SupportedUriSchemes", DbusArray<DbusString>());
+  set_property("SupportedMimeTypes", DbusArray<DbusString>());
 
   // org.mpris.MediaPlayer2.Player interface properties.
-  media_player2_player_properties_["PlaybackStatus"] = base::Value("Stopped");
-  media_player2_player_properties_["Rate"] = base::Value(1.0);
-  media_player2_player_properties_["Metadata"] =
-      base::Value(base::Value::DictStorage());
-  media_player2_player_properties_["Volume"] = base::Value(1.0);
-  media_player2_player_properties_["Position"] = base::Value(0);
-  media_player2_player_properties_["MinimumRate"] = base::Value(1.0);
-  media_player2_player_properties_["MaximumRate"] = base::Value(1.0);
-  media_player2_player_properties_["CanGoNext"] = base::Value(false);
-  media_player2_player_properties_["CanGoPrevious"] = base::Value(false);
-  media_player2_player_properties_["CanPlay"] = base::Value(false);
-  media_player2_player_properties_["CanPause"] = base::Value(false);
-  media_player2_player_properties_["CanSeek"] = base::Value(false);
-  media_player2_player_properties_["CanControl"] = base::Value(true);
+  auto set_player_property = [&](const std::string& property_name,
+                                 auto&& value) {
+    properties_->SetProperty(kMprisAPIPlayerInterfaceName, property_name,
+                             std::move(value), false);
+  };
+  set_player_property("PlaybackStatus", DbusString("Stopped"));
+  set_player_property("Rate", DbusDouble(1.0));
+  set_player_property("Metadata", DbusDictionary());
+  set_player_property("Volume", DbusDouble(1.0));
+  set_player_property("Position", DbusInt64(0));
+  set_player_property("MinimumRate", DbusDouble(1.0));
+  set_player_property("MaximumRate", DbusDouble(1.0));
+  set_player_property("CanGoNext", DbusBoolean(false));
+  set_player_property("CanGoPrevious", DbusBoolean(false));
+  set_player_property("CanPlay", DbusBoolean(false));
+  set_player_property("CanPause", DbusBoolean(false));
+  set_player_property("CanSeek", DbusBoolean(false));
+  set_player_property("CanControl", DbusBoolean(false));
 }
 
 void MprisServiceImpl::InitializeDbusInterface() {
@@ -170,6 +173,17 @@
       bus_->GetExportedObject(dbus::ObjectPath(kMprisAPIObjectPath));
   int num_methods_attempted_to_export = 0;
 
+  // kNumMethodsToExport calls for method export, 1 call for properties
+  // initialization.
+  barrier_ = SuccessBarrierCallback(
+      kNumMethodsToExport + 1,
+      base::BindOnce(&MprisServiceImpl::OnInitialized, base::Unretained(this)));
+
+  properties_ = std::make_unique<DbusProperties>(exported_object_, barrier_);
+  properties_->RegisterInterface(kMprisAPIInterfaceName);
+  properties_->RegisterInterface(kMprisAPIPlayerInterfaceName);
+  InitializeProperties();
+
   // Helper lambdas for exporting methods while keeping track of the number of
   // exported methods.
   auto export_method =
@@ -217,45 +231,28 @@
   export_unhandled_method(kMprisAPIPlayerInterfaceName, "SetPosition");
   export_unhandled_method(kMprisAPIPlayerInterfaceName, "OpenUri");
 
-  // Set up org.freedesktop.DBus.Properties interface.
-  // https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
-  export_method(dbus::kPropertiesInterface, dbus::kPropertiesGetAll,
-                base::BindRepeating(&MprisServiceImpl::GetAllProperties,
-                                    base::Unretained(this)));
-  export_method(dbus::kPropertiesInterface, dbus::kPropertiesGet,
-                base::BindRepeating(&MprisServiceImpl::GetProperty,
-                                    base::Unretained(this)));
-  export_unhandled_method(dbus::kPropertiesInterface, dbus::kPropertiesSet);
-
   DCHECK_EQ(kNumMethodsToExport, num_methods_attempted_to_export);
 }
 
 void MprisServiceImpl::OnExported(const std::string& interface_name,
                                   const std::string& method_name,
                                   bool success) {
-  if (!success) {
-    service_failed_to_start_ = true;
-    return;
+  barrier_.Run(success);
+}
+
+void MprisServiceImpl::OnInitialized(bool success) {
+  if (success) {
+    bus_->RequestOwnership(service_name_,
+                           dbus::Bus::ServiceOwnershipOptions::REQUIRE_PRIMARY,
+                           base::BindRepeating(&MprisServiceImpl::OnOwnership,
+                                               base::Unretained(this)));
   }
-
-  num_methods_exported_++;
-
-  // Still waiting for more methods to finish exporting.
-  if (num_methods_exported_ < kNumMethodsToExport)
-    return;
-
-  bus_->RequestOwnership(service_name_,
-                         dbus::Bus::ServiceOwnershipOptions::REQUIRE_PRIMARY,
-                         base::BindRepeating(&MprisServiceImpl::OnOwnership,
-                                             base::Unretained(this)));
 }
 
 void MprisServiceImpl::OnOwnership(const std::string& service_name,
                                    bool success) {
-  if (!success) {
-    service_failed_to_start_ = true;
+  if (!success)
     return;
-  }
 
   service_ready_ = true;
 
@@ -317,228 +314,16 @@
   response_sender.Run(dbus::Response::FromMethodCall(method_call));
 }
 
-// org.freedesktop.DBus.Properties.GetAll(in STRING interface_name,
-//                                        out DICT<STRING,VARIANT> props);
-void MprisServiceImpl::GetAllProperties(
-    dbus::MethodCall* method_call,
-    dbus::ExportedObject::ResponseSender response_sender) {
-  dbus::MessageReader reader(method_call);
-  std::string interface;
-  if (!reader.PopString(&interface)) {
-    response_sender.Run(nullptr);
-    return;
-  }
-
-  std::unique_ptr<dbus::Response> response =
-      dbus::Response::FromMethodCall(method_call);
-  dbus::MessageWriter writer(response.get());
-
-  if (interface == kMprisAPIInterfaceName) {
-    AddPropertiesToWriter(&writer, media_player2_properties_);
-  } else if (interface == kMprisAPIPlayerInterfaceName) {
-    AddPropertiesToWriter(&writer, media_player2_player_properties_);
-  } else if (interface == dbus::kPropertiesInterface) {
-    // There are no properties to give for this interface.
-    PropertyMap empty_properties_map;
-    AddPropertiesToWriter(&writer, empty_properties_map);
-  } else {
-    // The given interface is not supported, so return a null response.
-    response_sender.Run(nullptr);
-    return;
-  }
-
-  response_sender.Run(std::move(response));
-}
-
-// org.freedesktop.DBus.Properties.Get(in STRING interface_name,
-//                                     in STRING property_name,
-//                                     out VARIANT value);
-void MprisServiceImpl::GetProperty(
-    dbus::MethodCall* method_call,
-    dbus::ExportedObject::ResponseSender response_sender) {
-  dbus::MessageReader reader(method_call);
-  std::string interface;
-  if (!reader.PopString(&interface)) {
-    response_sender.Run(nullptr);
-    return;
-  }
-
-  std::string property_name;
-  if (!reader.PopString(&property_name)) {
-    response_sender.Run(nullptr);
-    return;
-  }
-
-  std::unique_ptr<dbus::Response> response =
-      dbus::Response::FromMethodCall(method_call);
-  dbus::MessageWriter writer(response.get());
-
-  bool success = false;
-  if (interface == kMprisAPIInterfaceName) {
-    auto property_iter = media_player2_properties_.find(property_name);
-    if (property_iter != media_player2_properties_.end()) {
-      dbus::AppendValueDataAsVariant(&writer, property_iter->second);
-      success = true;
-    }
-  } else if (interface == kMprisAPIPlayerInterfaceName) {
-    auto property_iter = media_player2_player_properties_.find(property_name);
-    if (property_iter != media_player2_player_properties_.end()) {
-      if (property_name == "Metadata") {
-        const base::DictionaryValue* metadata = nullptr;
-        property_iter->second.GetAsDictionary(&metadata);
-        AddMetadataToWriter(&writer, metadata);
-      } else {
-        dbus::AppendValueDataAsVariant(&writer, property_iter->second);
-      }
-      success = true;
-    }
-  }
-
-  // If we don't support the given property, return a null response.
-  if (!success) {
-    response_sender.Run(nullptr);
-    return;
-  }
-
-  response_sender.Run(std::move(response));
-}
-
-void MprisServiceImpl::AddPropertiesToWriter(dbus::MessageWriter* writer,
-                                             const PropertyMap& properties) {
-  DCHECK(writer);
-
-  dbus::MessageWriter array_writer(nullptr);
-  dbus::MessageWriter dict_entry_writer(nullptr);
-
-  writer->OpenArray("{sv}", &array_writer);
-
-  for (auto& property : properties) {
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(property.first);
-
-    if (property.first == "Metadata") {
-      const base::DictionaryValue* metadata = nullptr;
-      property.second.GetAsDictionary(&metadata);
-      AddMetadataToWriter(&dict_entry_writer, metadata);
-    } else {
-      dbus::AppendValueDataAsVariant(&dict_entry_writer, property.second);
-    }
-
-    array_writer.CloseContainer(&dict_entry_writer);
-  }
-
-  writer->CloseContainer(&array_writer);
-}
-
-void MprisServiceImpl::AddMetadataToWriter(
-    dbus::MessageWriter* writer,
-    const base::DictionaryValue* metadata) {
-  // We need to special-case Metadata's xesam:artist when emitting properties,
-  // since |dbus::AppendValueDataAsVariant()| only supports arrays of variants
-  // and not arrays of strings.
-  DCHECK(writer);
-  DCHECK(metadata);
-
-  dbus::MessageWriter metadata_variant_writer(nullptr);
-  writer->OpenVariant("a{sv}", &metadata_variant_writer);
-  dbus::MessageWriter metadata_writer(nullptr);
-  metadata_variant_writer.OpenArray("{sv}", &metadata_writer);
-
-  for (base::DictionaryValue::Iterator iter(*metadata); !iter.IsAtEnd();
-       iter.Advance()) {
-    dbus::MessageWriter metadata_entry_writer(nullptr);
-    metadata_writer.OpenDictEntry(&metadata_entry_writer);
-    metadata_entry_writer.AppendString(iter.key());
-
-    if (iter.key() == "xesam:artist") {
-      // Here, we convert our string value for artist into an array of
-      // strings to append to the message.
-      dbus::MessageWriter artist_writer(nullptr);
-      metadata_entry_writer.OpenVariant("as", &artist_writer);
-
-      std::vector<std::string> artists{iter.value().GetString()};
-      artist_writer.AppendArrayOfStrings(artists);
-
-      metadata_entry_writer.CloseContainer(&artist_writer);
-    } else {
-      dbus::AppendValueDataAsVariant(&metadata_entry_writer, iter.value());
-    }
-
-    metadata_writer.CloseContainer(&metadata_entry_writer);
-  }
-
-  metadata_variant_writer.CloseContainer(&metadata_writer);
-  writer->CloseContainer(&metadata_variant_writer);
-}
-
-void MprisServiceImpl::SetPropertyInternal(PropertyMap& property_map,
-                                           const std::string& property_name,
-                                           const base::Value& new_value) {
-  if (property_map[property_name] == new_value)
-    return;
-
-  property_map[property_name] = new_value.Clone();
-
-  changed_properties_.insert(property_name);
-
-  EmitPropertiesChangedSignalDebounced();
-}
-
 void MprisServiceImpl::SetMetadataPropertyInternal(
     const std::string& property_name,
-    const base::Value& new_value) {
-  base::Value& metadata = media_player2_player_properties_["Metadata"];
-  base::Value* current_value = metadata.FindKey(property_name);
-
-  if (current_value && *current_value == new_value)
-    return;
-  metadata.SetKey(property_name, new_value.Clone());
-
-  changed_properties_.insert("Metadata");
-
-  EmitPropertiesChangedSignalDebounced();
-}
-
-void MprisServiceImpl::EmitPropertiesChangedSignalDebounced() {
-  properties_changed_debounce_timer_.Stop();
-  properties_changed_debounce_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this,
-      &MprisServiceImpl::EmitPropertiesChangedSignal);
-}
-
-void MprisServiceImpl::EmitPropertiesChangedSignal() {
-  // If we're still trying to start the service, delay emitting.
-  if (!service_ready_ && !service_failed_to_start_) {
-    EmitPropertiesChangedSignalDebounced();
-    return;
-  }
-
-  if (!bus_ || !exported_object_ || !service_ready_)
-    return;
-
-  PropertyMap changed_property_map;
-  for (std::string property_name : changed_properties_) {
-    changed_property_map[property_name] =
-        media_player2_player_properties_[property_name].Clone();
-  }
-  changed_properties_.clear();
-
-  // |signal| follows the PropertiesChanged API:
-  // org.freedesktop.DBus.Properties.PropertiesChanged(
-  //     STRING interface_name,
-  //     DICT<STRING,VARIANT> changed_properties,
-  //     ARRAY<STRING> invalidated_properties);
-  dbus::Signal signal(dbus::kPropertiesInterface, dbus::kPropertiesChanged);
-  dbus::MessageWriter writer(&signal);
-  writer.AppendString(kMprisAPIPlayerInterfaceName);
-
-  AddPropertiesToWriter(&writer, changed_property_map);
-
-  std::vector<std::string> empty_invalidated_properties;
-  writer.AppendArrayOfStrings(empty_invalidated_properties);
-
-  exported_object_->SendSignal(&signal);
+    DbusVariant&& new_value) {
+  DbusVariant* dictionary_variant =
+      properties_->GetProperty(kMprisAPIPlayerInterfaceName, "Metadata");
+  DCHECK(dictionary_variant);
+  DbusDictionary* dictionary = dictionary_variant->GetAs<DbusDictionary>();
+  DCHECK(dictionary);
+  if (dictionary->Put(property_name, std::move(new_value)))
+    properties_->PropertyUpdated(kMprisAPIPlayerInterfaceName, "Metadata");
 }
 
 }  // namespace mpris
diff --git a/ui/base/mpris/mpris_service_impl.h b/ui/base/mpris/mpris_service_impl.h
index 2e4a404..17530c9 100644
--- a/ui/base/mpris/mpris_service_impl.h
+++ b/ui/base/mpris/mpris_service_impl.h
@@ -11,20 +11,16 @@
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/memory/singleton.h"
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
+#include "components/dbus/properties/types.h"
 #include "dbus/bus.h"
 #include "dbus/exported_object.h"
 #include "ui/base/mpris/mpris_service.h"
 
-namespace base {
-class DictionaryValue;
-class Value;
-}  // namespace base
+class DbusProperties;
 
 namespace dbus {
-class MessageWriter;
 class MethodCall;
 }  // namespace dbus
 
@@ -64,6 +60,7 @@
   void OnExported(const std::string& interface_name,
                   const std::string& method_name,
                   bool success);
+  void OnInitialized(bool success);
   void OnOwnership(const std::string& service_name, bool success);
 
   // org.mpris.MediaPlayer2.Player interface.
@@ -84,47 +81,12 @@
   void DoNothing(dbus::MethodCall* method_call,
                  dbus::ExportedObject::ResponseSender response_sender);
 
-  // org.freedesktop.DBus.Properties interface.
-  void GetAllProperties(dbus::MethodCall* method_call,
-                        dbus::ExportedObject::ResponseSender response_sender);
-  void GetProperty(dbus::MethodCall* method_call,
-                   dbus::ExportedObject::ResponseSender response_sender);
-
-  using PropertyMap = base::flat_map<std::string, base::Value>;
-
-  // Sets a value on the given PropertyMap and sends a PropertiesChanged signal
-  // if necessary.
-  void SetPropertyInternal(PropertyMap& property_map,
-                           const std::string& property_name,
-                           const base::Value& new_value);
-
   // Sets a value on the Metadata property map and sends a PropertiesChanged
   // signal if necessary.
   void SetMetadataPropertyInternal(const std::string& property_name,
-                                   const base::Value& new_value);
+                                   DbusVariant&& new_value);
 
-  // Updates a timer to debounce calls to |EmitPropertiesChangedSignal|.
-  void EmitPropertiesChangedSignalDebounced();
-
-  // Emits a org.freedesktop.DBus.Properties.PropertiesChanged signal for the
-  // given map of changed properties.
-  void EmitPropertiesChangedSignal();
-
-  // Writes all properties onto writer.
-  void AddPropertiesToWriter(dbus::MessageWriter* writer,
-                             const PropertyMap& properties);
-
-  // Writes the metadata property onto writer. Metadata is handled differently
-  // than other properties since it has sub-properties that need to be handled
-  // as non-variants.
-  void AddMetadataToWriter(dbus::MessageWriter* writer,
-                           const base::DictionaryValue* metadata);
-
-  // Map of org.mpris.MediaPlayer2 interface properties.
-  PropertyMap media_player2_properties_;
-
-  // Map of org.mpris.MediaPlayer2.Player interface properties.
-  PropertyMap media_player2_player_properties_;
+  std::unique_ptr<DbusProperties> properties_;
 
   scoped_refptr<dbus::Bus> bus_;
   dbus::ExportedObject* exported_object_;
@@ -132,24 +94,11 @@
   // The generated service name given to |bus_| when requesting ownership.
   const std::string service_name_;
 
-  // The number of methods that have been successfully exported through
-  // |exported_object_|.
-  int num_methods_exported_ = 0;
+  base::RepeatingCallback<void(bool)> barrier_;
 
   // True if we have finished creating the DBus service and received ownership.
   bool service_ready_ = false;
 
-  // True if we failed to start the MPRIS DBus service.
-  bool service_failed_to_start_ = false;
-
-  // Used to only send 1 PropertiesChanged signal when many properties are
-  // changed at once.
-  base::OneShotTimer properties_changed_debounce_timer_;
-
-  // Holds a list of properties that have changed since the last time we emitted
-  // a PropertiesChanged signal.
-  base::flat_set<std::string> changed_properties_;
-
   base::ObserverList<MprisServiceObserver> observers_;
 
   DISALLOW_COPY_AND_ASSIGN(MprisServiceImpl);
diff --git a/ui/events/gesture_detection/filtered_gesture_provider_unittest.cc b/ui/events/gesture_detection/filtered_gesture_provider_unittest.cc
index 750344a..be29cff9 100644
--- a/ui/events/gesture_detection/filtered_gesture_provider_unittest.cc
+++ b/ui/events/gesture_detection/filtered_gesture_provider_unittest.cc
@@ -14,7 +14,8 @@
                                     public testing::Test {
  public:
   FilteredGestureProviderTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {}
   ~FilteredGestureProviderTest() override {}
 
   // GestureProviderClient implementation.
@@ -22,7 +23,7 @@
   bool RequiresDoubleTapGestureEvents() const override { return false; }
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 // Single touch drag test: After touch-start, the moved_beyond_slop_region bit
diff --git a/ui/events/gesture_detection/gesture_detector.cc b/ui/events/gesture_detection/gesture_detector.cc
index 3468f41..7523ad0e 100644
--- a/ui/events/gesture_detection/gesture_detector.cc
+++ b/ui/events/gesture_detection/gesture_detector.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 
+#include "base/numerics/ranges.h"
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "ui/events/gesture_detection/gesture_listeners.h"
@@ -446,7 +447,7 @@
   DCHECK_GT(config.maximum_swipe_deviation_angle, 0);
   DCHECK_LE(config.maximum_swipe_deviation_angle, 45);
   const float maximum_swipe_deviation_angle =
-      std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle));
+      base::ClampToRange(config.maximum_swipe_deviation_angle, 0.001f, 45.0f);
   min_swipe_direction_component_ratio_ =
       1.f / tan(gfx::DegToRad(maximum_swipe_deviation_angle));
 
diff --git a/ui/events/gesture_detection/gesture_provider_unittest.cc b/ui/events/gesture_detection/gesture_provider_unittest.cc
index 11ba982..9d3a522 100644
--- a/ui/events/gesture_detection/gesture_provider_unittest.cc
+++ b/ui/events/gesture_detection/gesture_provider_unittest.cc
@@ -66,7 +66,8 @@
 class GestureProviderTest : public testing::Test, public GestureProviderClient {
  public:
   GestureProviderTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {}
   ~GestureProviderTest() override {}
 
   static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
@@ -437,7 +438,7 @@
   std::vector<GestureEventData> gestures_;
   std::unique_ptr<GestureProvider> gesture_provider_;
   std::unique_ptr<GestureEventData> active_scroll_begin_event_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
   bool should_process_double_tap_events_ = true;
 };
 
diff --git a/ui/events/gestures/gesture_provider_aura_unittest.cc b/ui/events/gestures/gesture_provider_aura_unittest.cc
index f270dc4..1e0aeea 100644
--- a/ui/events/gestures/gesture_provider_aura_unittest.cc
+++ b/ui/events/gestures/gesture_provider_aura_unittest.cc
@@ -17,7 +17,8 @@
                                 public GestureProviderAuraClient {
  public:
   GestureProviderAuraTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {}
 
   ~GestureProviderAuraTest() override {}
 
@@ -36,7 +37,7 @@
  private:
   std::unique_ptr<GestureConsumer> consumer_;
   std::unique_ptr<GestureProviderAura> provider_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 };
 
 TEST_F(GestureProviderAuraTest, IgnoresExtraPressEvents) {
diff --git a/ui/gfx/animation/linear_animation.cc b/ui/gfx/animation/linear_animation.cc
index f74d0c9..2791194a 100644
--- a/ui/gfx/animation/linear_animation.cc
+++ b/ui/gfx/animation/linear_animation.cc
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 
+#include "base/numerics/ranges.h"
 #include "ui/gfx/animation/animation_container.h"
 #include "ui/gfx/animation/animation_delegate.h"
 
@@ -46,7 +47,7 @@
 }
 
 void LinearAnimation::SetCurrentValue(double new_value) {
-  new_value = std::max(0.0, std::min(1.0, new_value));
+  new_value = base::ClampToRange(new_value, 0.0, 1.0);
   base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
       static_cast<int64_t>(duration_.InMicroseconds() * (new_value - state_)));
   SetStartTime(start_time() - time_delta);
diff --git a/ui/gfx/geometry/cubic_bezier.cc b/ui/gfx/geometry/cubic_bezier.cc
index a903d3f..1e9e1e4 100644
--- a/ui/gfx/geometry/cubic_bezier.cc
+++ b/ui/gfx/geometry/cubic_bezier.cc
@@ -8,6 +8,7 @@
 #include <cmath>
 
 #include "base/logging.h"
+#include "base/numerics/ranges.h"
 
 namespace gfx {
 
@@ -228,7 +229,7 @@
 }
 
 double CubicBezier::SlopeWithEpsilon(double x, double epsilon) const {
-  x = std::min(std::max(x, 0.0), 1.0);
+  x = base::ClampToRange(x, 0.0, 1.0);
   double t = SolveCurveX(x, epsilon);
   double dx = SampleCurveDerivativeX(t);
   double dy = SampleCurveDerivativeY(t);
diff --git a/ui/gfx/geometry/quaternion.cc b/ui/gfx/geometry/quaternion.cc
index f2be00b..a9d553e 100644
--- a/ui/gfx/geometry/quaternion.cc
+++ b/ui/gfx/geometry/quaternion.cc
@@ -8,6 +8,7 @@
 #include <cmath>
 
 #include "base/numerics/math_constants.h"
+#include "base/numerics/ranges.h"
 #include "base/strings/stringprintf.h"
 #include "ui/gfx/geometry/vector3d_f.h"
 
@@ -60,8 +61,7 @@
 Quaternion Quaternion::Slerp(const Quaternion& q, double t) const {
   double dot = x_ * q.x_ + y_ * q.y_ + z_ * q.z_ + w_ * q.w_;
 
-  // Clamp dot to -1.0 <= dot <= 1.0.
-  dot = std::min(std::max(dot, -1.0), 1.0);
+  dot = base::ClampToRange(dot, -1.0, 1.0);
 
   // Quaternions are facing the same direction.
   if (std::abs(dot - 1.0) < kEpsilon || std::abs(dot + 1.0) < kEpsilon)
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 8aedc0e..bd8491ad 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -1589,7 +1589,7 @@
   const int space =
       display_height - ((internal_leading != 0) ? cap_height : font_height);
   const int baseline_shift = space / 2 - internal_leading;
-  return baseline + std::max(min_shift, std::min(max_shift, baseline_shift));
+  return baseline + base::ClampToRange(baseline_shift, min_shift, max_shift);
 }
 
 // static
diff --git a/ui/gfx/skia_color_space_util.cc b/ui/gfx/skia_color_space_util.cc
index a415c031..657ec16c 100644
--- a/ui/gfx/skia_color_space_util.cc
+++ b/ui/gfx/skia_color_space_util.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "base/numerics/ranges.h"
 
 namespace gfx {
 
@@ -20,7 +21,7 @@
 
 float SkTransferFnEval(const skcms_TransferFunction& fn, float x) {
   float fn_at_x_unclamped = SkTransferFnEvalUnclamped(fn, x);
-  return std::min(std::max(fn_at_x_unclamped, 0.f), 1.f);
+  return base::ClampToRange(fn_at_x_unclamped, 0.0f, 1.0f);
 }
 
 skcms_TransferFunction SkTransferFnInverse(const skcms_TransferFunction& fn) {
diff --git a/ui/native_theme/native_theme_base.cc b/ui/native_theme/native_theme_base.cc
index 6e36ec77..0b338f9a 100644
--- a/ui/native_theme/native_theme_base.cc
+++ b/ui/native_theme/native_theme_base.cc
@@ -9,6 +9,7 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/numerics/ranges.h"
 #include "cc/paint/paint_flags.h"
 #include "cc/paint/paint_shader.h"
 #include "third_party/skia/include/core/SkPath.h"
@@ -964,8 +965,10 @@
                                              SkScalar brighten_amount) const {
   SkScalar color[3];
   color[0] = hsv[0];
-  color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0);
-  color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0);
+  color[1] =
+      base::ClampToRange(hsv[1] + saturate_amount, SkScalar{0}, SK_Scalar1);
+  color[2] =
+      base::ClampToRange(hsv[2] + brighten_amount, SkScalar{0}, SK_Scalar1);
   return SkHSVToColor(color);
 }
 
@@ -1012,12 +1015,6 @@
   DrawVertLine(canvas, rect.x(), rect.y(), bottom, flags);
 }
 
-SkScalar NativeThemeBase::Clamp(SkScalar value,
-                                SkScalar min,
-                                SkScalar max) const {
-  return std::min(std::max(value, min), max);
-}
-
 SkColor NativeThemeBase::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const {
   // GTK Theme engines have way too much control over the layout of
   // the scrollbar. We might be able to more closely approximate its
@@ -1046,8 +1043,10 @@
   //
   // The following code has been tested to look OK with all of the
   // default GTK themes.
-  SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f);
-  SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f);
+  SkScalar min_diff =
+      base::ClampToRange((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f);
+  SkScalar diff =
+      base::ClampToRange(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f);
 
   if (hsv1[2] + hsv2[2] > 1.0)
     diff = -diff;
diff --git a/ui/native_theme/native_theme_base.h b/ui/native_theme/native_theme_base.h
index 0390f9f..01587b92 100644
--- a/ui/native_theme/native_theme_base.h
+++ b/ui/native_theme/native_theme_base.h
@@ -198,9 +198,6 @@
   void DrawBox(cc::PaintCanvas* canvas,
                const gfx::Rect& rect,
                const cc::PaintFlags& flags) const;
-  SkScalar Clamp(SkScalar value,
-                 SkScalar min,
-                 SkScalar max) const;
   SkColor OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const;
 
   // Paint the common parts of the checkboxes and radio buttons.
diff --git a/ui/touch_selection/touch_handle.cc b/ui/touch_selection/touch_handle.cc
index 503f9ea..fbaff756 100644
--- a/ui/touch_selection/touch_handle.cc
+++ b/ui/touch_selection/touch_handle.cc
@@ -3,11 +3,13 @@
 // found in the LICENSE file.
 
 #include "ui/touch_selection/touch_handle.h"
-#include "base/metrics/histogram_macros.h"
 
 #include <algorithm>
 #include <cmath>
 
+#include "base/metrics/histogram_macros.h"
+#include "base/numerics/ranges.h"
+
 namespace ui {
 
 namespace {
@@ -173,9 +175,10 @@
       if (!is_visible_)
         return false;
       const gfx::PointF touch_point(event.GetX(), event.GetY());
-      const float touch_radius = std::max(
-          kMinTouchMajorForHitTesting,
-          std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor())) * 0.5f;
+      const float touch_radius =
+          base::ClampToRange(event.GetTouchMajor(), kMinTouchMajorForHitTesting,
+                             kMaxTouchMajorForHitTesting) *
+          0.5f;
       const gfx::RectF drawable_bounds = drawable_->GetVisibleBounds();
       // Only use the touch radius for targetting if the touch is at or below
       // the drawable area. This makes it easier to interact with the line of
@@ -429,7 +432,7 @@
 }
 
 void TouchHandle::SetAlpha(float alpha) {
-  alpha = std::max(0.f, std::min(1.f, alpha));
+  alpha = base::ClampToRange(alpha, 0.0f, 1.0f);
   if (alpha_ == alpha)
     return;
   alpha_ = alpha;
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc
index 05a9c961..78806f645 100644
--- a/ui/views/controls/scroll_view.cc
+++ b/ui/views/controls/scroll_view.cc
@@ -371,7 +371,7 @@
   gfx::Insets insets = GetInsets();
   width = std::max(0, width - insets.width());
   int height = contents_->GetHeightForWidth(width) + insets.height();
-  return std::min(std::max(height, min_height_), max_height_);
+  return base::ClampToRange(height, min_height_, max_height_);
 }
 
 void ScrollView::Layout() {
@@ -733,9 +733,8 @@
   const int contents_max_y =
       std::max(contents_viewport_->height(), contents_->height());
 
-  // Make sure x and y are within the bounds of [0,contents_max_*].
-  int x = std::max(0, std::min(contents_max_x, rect.x()));
-  int y = std::max(0, std::min(contents_max_y, rect.y()));
+  int x = base::ClampToRange(rect.x(), 0, contents_max_x);
+  int y = base::ClampToRange(rect.y(), 0, contents_max_y);
 
   // Figure out how far and down the rectangle will go taking width
   // and height into account.  This will be "clipped" by the viewport.
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc
index 002c59a..0fb712a 100644
--- a/ui/views/controls/table/table_view.cc
+++ b/ui/views/controls/table/table_view.cc
@@ -16,6 +16,7 @@
 #include "base/callback.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/ptr_util.h"
+#include "base/numerics/ranges.h"
 #include "base/optional.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -964,7 +965,7 @@
 
   PaintRegion region;
   region.min_row =
-      std::min(GetRowCount() - 1, std::max(0, bounds.y() / row_height_));
+      base::ClampToRange(bounds.y() / row_height_, 0, GetRowCount() - 1);
   region.max_row = bounds.bottom() / row_height_;
   if (bounds.bottom() % row_height_ != 0)
     region.max_row++;
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc
index b15886ae..536c38e5 100644
--- a/ui/views/controls/tree/tree_view.cc
+++ b/ui/views/controls/tree/tree_view.cc
@@ -10,6 +10,7 @@
 #include "base/containers/adapters.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/ptr_util.h"
+#include "base/numerics/ranges.h"
 #include "build/build_config.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/accessibility/ax_node_data.h"
@@ -1052,7 +1053,7 @@
   int depth = 0;
   int delta = type == INCREMENT_PREVIOUS ? -1 : 1;
   int row = GetRowForInternalNode(selected_node_, &depth);
-  int new_row = std::min(GetRowCount() - 1, std::max(0, row + delta));
+  int new_row = base::ClampToRange(row + delta, 0, GetRowCount() - 1);
   if (new_row == row)
     return;  // At the end/beginning.
   SetSelectedNode(GetNodeByRow(new_row, &depth)->model_node());
diff --git a/ui/views/examples/progress_bar_example.cc b/ui/views/examples/progress_bar_example.cc
index 4a103933..01c99b3c 100644
--- a/ui/views/examples/progress_bar_example.cc
+++ b/ui/views/examples/progress_bar_example.cc
@@ -6,22 +6,13 @@
 
 #include <algorithm>
 
+#include "base/numerics/ranges.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/progress_bar.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/view.h"
 
-namespace {
-
-const double kStepSize = 0.1;
-
-double SetToMax(double percent) {
-  return std::min(std::max(percent, 0.0), 1.0);
-}
-
-}  // namespace
-
 namespace views {
 namespace examples {
 
@@ -66,11 +57,9 @@
 }
 
 void ProgressBarExample::ButtonPressed(Button* sender, const ui::Event& event) {
-  if (sender == minus_button_)
-    current_percent_ = SetToMax(current_percent_ - kStepSize);
-  else if (sender == plus_button_)
-    current_percent_ = SetToMax(current_percent_ + kStepSize);
-
+  constexpr double kStepSize = 0.1;
+  const double step = (sender == minus_button_) ? -kStepSize : kStepSize;
+  current_percent_ = base::ClampToRange(current_percent_ + step, 0.0, 1.0);
   progress_bar_->SetValue(current_percent_);
 }
 
diff --git a/ui/views/layout/flex_layout_types_internal.cc b/ui/views/layout/flex_layout_types_internal.cc
index f6c636a..8069a25 100644
--- a/ui/views/layout/flex_layout_types_internal.cc
+++ b/ui/views/layout/flex_layout_types_internal.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <tuple>
 
+#include "base/numerics/ranges.h"
 #include "base/strings/stringprintf.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/point.h"
@@ -73,8 +74,8 @@
 }
 
 void NormalizedSize::SetToMin(int main, int cross) {
-  main_ = std::max(0, std::min(main_, main));
-  cross_ = std::max(0, std::min(cross_, cross));
+  main_ = base::ClampToRange(main, 0, main_);
+  cross_ = base::ClampToRange(cross, 0, cross_);
 }
 
 void NormalizedSize::SetToMax(const NormalizedSize& other) {
diff --git a/ui/views/selection_controller.cc b/ui/views/selection_controller.cc
index 01b583b..8bc18468 100644
--- a/ui/views/selection_controller.cc
+++ b/ui/views/selection_controller.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/numerics/ranges.h"
 #include "build/build_config.h"
 #include "ui/events/event.h"
 #include "ui/gfx/render_text.h"
@@ -115,7 +116,7 @@
     SelectThroughLastDragLocation();
   } else if (!drag_selection_timer_.IsRunning()) {
     // Select through the edge of the visible text, then start the scroll timer.
-    last_drag_location_.set_x(std::min(std::max(0, x), width));
+    last_drag_location_.set_x(base::ClampToRange(x, 0, width));
     SelectThroughLastDragLocation();
 
     drag_selection_timer_.Start(