diff --git a/DEPS b/DEPS
index 4f2ac01..29786e29 100644
--- a/DEPS
+++ b/DEPS
@@ -199,11 +199,11 @@
   # 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': 'b64da3907f7638c87967d60cd250a6b02c914251',
+  'skia_revision': '860d01ca8bae3a8a85a104fa755c4149fd1349c5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '804d2150372f0e8a19996e7152d984898e8cb85d',
+  'v8_revision': 'fc4ac7024d121a1fdc77cecab42defe4bd11a967',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -266,7 +266,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '92c77100518eb763855f8b0ef8ba9ce6b29ac9f5',
+  'catapult_revision': '5039608d33669976de3673888c138b0aba2f47ff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -274,7 +274,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '0096403e47fb3159757415c943e63826b228a192',
+  'devtools_frontend_revision': '7df55c21d64b6df52a923c3e6e3b370db6e0a495',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -365,7 +365,7 @@
   'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47',
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'tint_revision': '181d8baf8f016df2a50dd2bf1776c3283f282807',
+  'tint_revision': 'd1469c60c1ab5c96278d570aa93ef38b722b67e4',
 
   # TODO(crbug.com/941824): The values below need to be kept in sync
   # between //DEPS and //buildtools/DEPS, so if you're updating one,
@@ -565,7 +565,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e946f7e093404de560e8f63a76921e1bf7e2b1f6',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'f03c0a36e0fcc5ded1f7ce51b0a0589224689d01',
       'condition': 'checkout_ios',
   },
 
@@ -901,7 +901,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'cfecd6b3e2e9744ab94908f51bc11b1573f0f960',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '36522931735d23b029d58b244ed8f4b90ce40260',
       'condition': 'checkout_chromeos',
   },
 
@@ -916,7 +916,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '460536ec43e3f40609e3b0a22732fb0b57c629e0',
+      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'efa6d9547c85979240e5bf0c4c796e0a84b0fdf5',
       'condition': 'checkout_linux',
   },
 
@@ -1293,7 +1293,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '0da7da798b33eb8624ed09f0b50d83cbec80e0cb',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '0d23e521cc40b7a795ad98247a5d5b20121a5cf4',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1371,7 +1371,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'aVUjhhx6rvX82et0M0vk6jejLNbKQMZwukDovqaW3pgC'
+              'version': 'xbub5pS-4jut2bXIXFZ4xABfPqAJC0wMGX7DZaoMJNcC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1615,7 +1615,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7bbf434aef522ac6e4a1cc0002aa61d698399549',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@fdd70108b562959fc71b0d0c0c7e76c4e7b25b9c',
     'condition': 'checkout_src_internal',
   },
 
@@ -1623,7 +1623,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'vut0tWjt1yQoJk5vrwYDcHtYQKjr64przVZjYeqRU6EC',
+        'version': 'Lhu0LG_M8M2Pn2h_RBp-1HjjF6xbNUOUOu6DedtsKlQC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1634,7 +1634,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'F2qSaG03RybV34PPKgVY50FpLeJhLL-u5pz5Gmi9s9AC',
+        'version': 'Lqnbzl4-hoc2WrAL80TsiADU6Of1I2wk_-c35v-9vSkC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 49397fb..d446f5c6 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1749,7 +1749,9 @@
   """
   result = []
 
-  if line.endswith(" nocheck"):
+  if input_api.re.search(r"^ *//", line):  # Ignore comments about banned types.
+    return result
+  if line.endswith(" nocheck"):  # A // nocheck comment will bypass this error.
     return result
 
   matched = False
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index 64b1b1d1f..e64703ca 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -2320,6 +2320,10 @@
                ['using std::string;']),
       MockFile('some/cpp/problematic/file2.cc',
                ['set_owned_by_client()']),
+      MockFile('some/cpp/nocheck/file.cc',
+               ['using namespace std;  // nocheck']),
+      MockFile('some/cpp/comment/file.cc',
+               ['  // A comment about `using namespace std;`']),
     ]
 
     results = PRESUBMIT.CheckNoBannedFunctions(input_api, MockOutputApi())
@@ -2331,6 +2335,10 @@
         'third_party/blink/problematic/file.cc' in results[0].message)
     self.assertTrue('some/cpp/ok/file.cc' not in results[1].message)
     self.assertTrue('some/cpp/problematic/file2.cc' in results[0].message)
+    self.assertFalse('some/cpp/nocheck/file.cc' in results[0].message)
+    self.assertFalse('some/cpp/nocheck/file.cc' in results[1].message)
+    self.assertFalse('some/cpp/comment/file.cc' in results[0].message)
+    self.assertFalse('some/cpp/comment/file.cc' in results[1].message)
 
   def testBannedIosObjcFunctions(self):
     input_api = MockInputApi()
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
index 822d5f2..1602f4b9 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -17,6 +17,7 @@
 import android.os.Build;
 import android.os.Build.VERSION;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.SystemClock;
@@ -54,11 +55,13 @@
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.MetricsUtils;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.components.autofill.AutofillHintsServiceTestHelper;
 import org.chromium.components.autofill.AutofillManagerWrapper;
 import org.chromium.components.autofill.AutofillPopup;
 import org.chromium.components.autofill.AutofillProvider;
 import org.chromium.components.autofill.AutofillProviderTestHelper;
 import org.chromium.components.autofill.AutofillProviderUMA;
+import org.chromium.components.autofill_public.ViewType;
 import org.chromium.components.embedder_support.util.WebResourceResponseInfo;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.DOMUtils;
@@ -2112,6 +2115,10 @@
                         "crowdsourcing-autofill-hints"));
         assertEquals("HTML_TYPE_EMAIL",
                 viewStructure.getChild(1).getHtmlInfo().getAttribute("computed-autofill-hints"));
+
+        // Binder will not be set if the prediction already arrives.
+        IBinder binder = viewStructure.getExtras().getBinder("AUTOFILL_HINTS_SERVICE");
+        assertNull(binder);
     }
 
     @Test
@@ -2149,6 +2156,68 @@
         assertEquals("HTML_TYPE_EMAIL",
                 viewStructure.getChild(1).getHtmlInfo().getAttribute("computed-autofill-hints"));
 
+        IBinder binder = viewStructure.getExtras().getBinder("AUTOFILL_HINTS_SERVICE");
+        assertNotNull(binder);
+        AutofillHintsServiceTestHelper autofillHintsServiceTestHelper =
+                new AutofillHintsServiceTestHelper();
+        autofillHintsServiceTestHelper.registerViewTypeService(binder);
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                ()
+                        -> AutofillProviderTestHelper
+                                   .simulateMainFrameAutofillServerResponseForTesting(
+                                           mAwContents.getWebContents(),
+                                           new String[] {"text1", "text2"},
+                                           new int[] {/*USERNAME, EMAIL_ADDRESS*/ 86, 9}));
+
+        cnt += waitForCallbackAndVerifyTypes(cnt, new Integer[] {AUTOFILL_QUERY_DONE});
+        assertTrue(mTestAutofillManagerWrapper.isQuerySucceed());
+        autofillHintsServiceTestHelper.waitForCallbackInvoked();
+        List<ViewType> viewTypes = autofillHintsServiceTestHelper.getViewTypes();
+        assertEquals(2, viewTypes.size());
+        assertEquals(viewStructure.getChild(0).getAutofillId(), viewTypes.get(0).mAutofillId);
+        assertEquals("USERNAME", viewTypes.get(0).mServerType);
+        assertEquals("USERNAME", viewTypes.get(0).mComputedType);
+        assertEquals(viewStructure.getChild(1).getAutofillId(), viewTypes.get(1).mAutofillId);
+        assertEquals("EMAIL_ADDRESS", viewTypes.get(1).mServerType);
+        assertEquals("HTML_TYPE_EMAIL", viewTypes.get(1).mComputedType);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    @CommandLineFlags.Add({"enable-features=AndroidAutofillQueryServerFieldTypes"})
+    public void testServerPredictionArrivesBeforeCallbackRegistered() throws Throwable {
+        final String data = "<html><head></head><body><form action='a.html' name='formname'>"
+                + "<input type='text' id='text1' name='username'>"
+                + "<input type='text' name='email' id='text2' autocomplete='email'/>"
+                + "</form></body></html>";
+        final String url = mWebServer.setResponse(FILE, data, null);
+        loadUrlSync(url);
+
+        int cnt = 0;
+        executeJavaScriptAndWaitForResult("document.getElementById('text1').select();");
+        dispatchDownAndUpKeyEvents(KeyEvent.KEYCODE_A);
+
+        cnt += waitForCallbackAndVerifyTypes(cnt,
+                new Integer[] {AUTOFILL_CANCEL, AUTOFILL_VIEW_ENTERED, AUTOFILL_SESSION_STARTED,
+                        AUTOFILL_VALUE_CHANGED});
+
+        invokeOnProvideAutoFillVirtualStructure();
+        TestViewStructure viewStructure = mTestValues.testViewStructure;
+        assertNotNull(viewStructure);
+        assertEquals(2, viewStructure.getChildCount());
+        assertEquals("NO_SERVER_DATA",
+                viewStructure.getChild(0).getHtmlInfo().getAttribute(
+                        "crowdsourcing-autofill-hints"));
+        assertEquals("UNKNOWN_TYPE",
+                viewStructure.getChild(0).getHtmlInfo().getAttribute("computed-autofill-hints"));
+        assertEquals("NO_SERVER_DATA",
+                viewStructure.getChild(1).getHtmlInfo().getAttribute(
+                        "crowdsourcing-autofill-hints"));
+        assertEquals("HTML_TYPE_EMAIL",
+                viewStructure.getChild(1).getHtmlInfo().getAttribute("computed-autofill-hints"));
+
         TestThreadUtils.runOnUiThreadBlocking(
                 ()
                         -> AutofillProviderTestHelper
@@ -2160,7 +2229,20 @@
         cnt += waitForCallbackAndVerifyTypes(cnt, new Integer[] {AUTOFILL_QUERY_DONE});
         assertTrue(mTestAutofillManagerWrapper.isQuerySucceed());
 
-        // TODO(crbug.com/1151542): Verify the field types once they are sent from service.
+        IBinder binder = viewStructure.getExtras().getBinder("AUTOFILL_HINTS_SERVICE");
+        assertNotNull(binder);
+        AutofillHintsServiceTestHelper autofillHintsServiceTestHelper =
+                new AutofillHintsServiceTestHelper();
+        autofillHintsServiceTestHelper.registerViewTypeService(binder);
+        autofillHintsServiceTestHelper.waitForCallbackInvoked();
+        List<ViewType> viewTypes = autofillHintsServiceTestHelper.getViewTypes();
+        assertEquals(2, viewTypes.size());
+        assertEquals(viewStructure.getChild(0).getAutofillId(), viewTypes.get(0).mAutofillId);
+        assertEquals("USERNAME", viewTypes.get(0).mServerType);
+        assertEquals("USERNAME", viewTypes.get(0).mComputedType);
+        assertEquals(viewStructure.getChild(1).getAutofillId(), viewTypes.get(1).mAutofillId);
+        assertEquals("EMAIL_ADDRESS", viewTypes.get(1).mServerType);
+        assertEquals("HTML_TYPE_EMAIL", viewTypes.get(1).mComputedType);
     }
 
     @Test
@@ -2193,8 +2275,8 @@
         assertNull(viewStructure.getChild(1).getHtmlInfo().getAttribute(
                 "crowdsourcing-autofill-hints"));
         assertNull(viewStructure.getChild(1).getHtmlInfo().getAttribute("computed-autofill-hints"));
-
-        // TODO(crbug.com/1151542): Complete the test once the prediction update is implemented.
+        IBinder binder = viewStructure.getExtras().getBinder("AUTOFILL_HINTS_SERVICE");
+        assertNull(binder);
     }
 
     @Test
@@ -2232,6 +2314,12 @@
         assertEquals("HTML_TYPE_EMAIL",
                 viewStructure.getChild(1).getHtmlInfo().getAttribute("computed-autofill-hints"));
 
+        IBinder binder = viewStructure.getExtras().getBinder("AUTOFILL_HINTS_SERVICE");
+        assertNotNull(binder);
+        AutofillHintsServiceTestHelper autofillHintsServiceTestHelper =
+                new AutofillHintsServiceTestHelper();
+        autofillHintsServiceTestHelper.registerViewTypeService(binder);
+
         TestThreadUtils.runOnUiThreadBlocking(
                 ()
                         -> AutofillProviderTestHelper
@@ -2240,6 +2328,9 @@
 
         cnt += waitForCallbackAndVerifyTypes(cnt, new Integer[] {AUTOFILL_QUERY_DONE});
         assertFalse(mTestAutofillManagerWrapper.isQuerySucceed());
+
+        autofillHintsServiceTestHelper.waitForCallbackInvoked();
+        assertTrue(autofillHintsServiceTestHelper.isQueryFailed());
     }
 
     private void pollJavascriptResult(String script, String expectedResult) throws Throwable {
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index f298c08..d33403a 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -48,7 +48,7 @@
   paint.setBlendMode(SkBlendMode::kSrcOver);
   canvas.drawRoundRect(gfx::RectToSkRect(gfx::Rect(image_size)), 100.f, 100.f,
                        paint);
-  return gfx::ImageSkia(gfx::ImageSkiaRep(std::move(bitmap), 1.f));
+  return gfx::ImageSkia::CreateFromBitmap(std::move(bitmap), 1.f);
 }
 
 void HandleToggleWallpaperMode() {
diff --git a/ash/app_list/views/ghost_image_view.cc b/ash/app_list/views/ghost_image_view.cc
index ec07e26..521f264 100644
--- a/ash/app_list/views/ghost_image_view.cc
+++ b/ash/app_list/views/ghost_image_view.cc
@@ -188,7 +188,7 @@
                   bitmap.pixmap().height() + kGhostImagePadding * 2),
         rep.scale(), false /* is_opaque */);
     padded_canvas.DrawImageInt(
-        gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, rep.scale())),
+        gfx::ImageSkia::CreateFromBitmap(bitmap, rep.scale()),
         kGhostImagePadding, kGhostImagePadding);
     bitmap = padded_canvas.GetBitmap();
 
diff --git a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc
index 60c287a5..8f635335 100644
--- a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc
+++ b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc
@@ -160,11 +160,15 @@
     auto image_view = BuildImageView();
     image_view->SetPreferredSize(
         gfx::Size(INT_MAX, ClipboardHistoryViews::kImageViewPreferredHeight));
-    image_view->SetBorder(views::CreateRoundedRectBorder(
+    image_view_ = AddChildView(std::move(image_view));
+
+    // `border_container_view_` should be above `image_view_`.
+    border_container_view_ = AddChildView(std::make_unique<views::View>());
+
+    border_container_view_->SetBorder(views::CreateRoundedRectBorder(
         ClipboardHistoryViews::kImageBorderThickness,
         ClipboardHistoryViews::kImageRoundedCornerRadius,
         gfx::kPlaceholderColor));
-    image_view_ = AddChildView(std::move(image_view));
 
     InstallDeleteButton();
   }
@@ -208,7 +212,7 @@
     ScopedLightModeAsDefault scoped_light_mode_as_default;
 
     ContentsView::OnThemeChanged();
-    image_view_->border()->set_color(
+    border_container_view_->border()->set_color(
         AshColorProvider::Get()->GetControlsLayerColor(
             AshColorProvider::ControlsLayerType::kHairlineBorderColor));
   }
@@ -283,6 +287,9 @@
   ClipboardHistoryBitmapItemView* const container_;
   RoundedImageView* image_view_ = nullptr;
 
+  // Helps to place a border above `image_view_`.
+  views::View* border_container_view_ = nullptr;
+
   base::WeakPtrFactory<BitmapContentsView> weak_ptr_factory_{this};
 };
 
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 5c001db..e0ca385 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -366,8 +366,8 @@
 
   const gfx::ImageSkiaRep& image_rep = resized.GetRepresentation(cursor_scale);
   delegate_->SetCursorImage(resized.size(),
-                            gfx::ImageSkia(gfx::ImageSkiaRep(
-                                GetAdjustedBitmap(image_rep), cursor_scale)));
+                            gfx::ImageSkia::CreateFromBitmap(
+                                GetAdjustedBitmap(image_rep), cursor_scale));
   // TODO(danakj): Should this be rounded? Or kept as a floating point?
   hot_point_ = gfx::ToFlooredPoint(
       gfx::ConvertPointToDips(hot_point_in_physical_pixels, cursor_scale));
diff --git a/ash/drag_drop/drag_image_view.cc b/ash/drag_drop/drag_image_view.cc
index c5a57534..c1e846c 100644
--- a/ash/drag_drop/drag_image_view.cc
+++ b/ash/drag_drop/drag_image_view.cc
@@ -127,7 +127,8 @@
     SkBitmap scaled = skia::ImageOperations::Resize(
         image_rep.GetBitmap(), skia::ImageOperations::RESIZE_LANCZOS3,
         drag_image_size_pixels.width(), drag_image_size_pixels.height());
-    gfx::ImageSkia image_skia(gfx::ImageSkiaRep(scaled, device_scale));
+    gfx::ImageSkia image_skia =
+        gfx::ImageSkia::CreateFromBitmap(scaled, device_scale);
     canvas->DrawImageInt(image_skia, 0, 0);
   }
 
diff --git a/ash/public/cpp/assistant/assistant_state_base.cc b/ash/public/cpp/assistant/assistant_state_base.cc
index cf22ae3..c0e6dc2 100644
--- a/ash/public/cpp/assistant/assistant_state_base.cc
+++ b/ash/public/cpp/assistant/assistant_state_base.cc
@@ -117,10 +117,6 @@
       chromeos::assistant::prefs::kAssistantOnboardingMode,
       base::BindRepeating(&AssistantStateBase::UpdateOnboardingMode,
                           base::Unretained(this)));
-  pref_change_registrar_->Add(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled,
-      base::BindRepeating(&AssistantStateBase::UpdateQuickAnswersEnabled,
-                          base::Unretained(this)));
 
   UpdateConsentStatus();
   UpdateContextEnabled();
@@ -130,7 +126,6 @@
   UpdateLaunchWithMicOpen();
   UpdateNotificationEnabled();
   UpdateOnboardingMode();
-  UpdateQuickAnswersEnabled();
 }
 
 bool AssistantStateBase::IsScreenContextAllowed() const {
@@ -157,8 +152,6 @@
     observer->OnAssistantNotificationEnabled(notification_enabled_.value());
   if (onboarding_mode_.has_value())
     observer->OnAssistantOnboardingModeChanged(onboarding_mode_.value());
-  if (quick_answers_enabled_.has_value())
-    observer->OnAssistantQuickAnswersEnabled(quick_answers_enabled_.value());
 
   observer->OnAssistantStatusChanged(assistant_status_);
   if (allowed_state_.has_value())
@@ -301,16 +294,4 @@
   }
 }
 
-void AssistantStateBase::UpdateQuickAnswersEnabled() {
-  auto quick_answers_enabled = pref_change_registrar_->prefs()->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled);
-  if (quick_answers_enabled_.has_value() &&
-      quick_answers_enabled_.value() == quick_answers_enabled) {
-    return;
-  }
-  quick_answers_enabled_ = quick_answers_enabled;
-  for (auto& observer : observers_)
-    observer.OnAssistantQuickAnswersEnabled(quick_answers_enabled_.value());
-}
-
 }  // namespace ash
diff --git a/ash/public/cpp/assistant/assistant_state_base.h b/ash/public/cpp/assistant/assistant_state_base.h
index e4a3007..6c74d4e 100644
--- a/ash/public/cpp/assistant/assistant_state_base.h
+++ b/ash/public/cpp/assistant/assistant_state_base.h
@@ -37,7 +37,6 @@
   virtual void OnAssistantOnboardingModeChanged(
       chromeos::assistant::prefs::AssistantOnboardingMode onboarding_mode) {}
   virtual void OnAssistantStateDestroyed() {}
-  virtual void OnAssistantQuickAnswersEnabled(bool quick_answers_enabled) {}
   virtual void OnAssistantStatusChanged(
       chromeos::assistant::AssistantStatus status) {}
   virtual void OnAssistantFeatureAllowedChanged(
@@ -131,7 +130,6 @@
   void UpdateLaunchWithMicOpen();
   void UpdateNotificationEnabled();
   void UpdateOnboardingMode();
-  void UpdateQuickAnswersEnabled();
 
   // Called when new values of the listened states are received.
   void UpdateAssistantStatus(chromeos::assistant::AssistantStatus status);
@@ -186,9 +184,6 @@
   // available yet.
   base::Optional<bool> locked_full_screen_enabled_;
 
-  // Whether quick answers is enabled. nullopt if the data is not available yet.
-  base::Optional<bool> quick_answers_enabled_;
-
   // Observes user profile prefs for the Assistant.
   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
diff --git a/ash/system/holding_space/holding_space_drag_util.cc b/ash/system/holding_space/holding_space_drag_util.cc
index b0a0394..2e134f1 100644
--- a/ash/system/holding_space/holding_space_drag_util.cc
+++ b/ash/system/holding_space/holding_space_drag_util.cc
@@ -325,7 +325,7 @@
                           /*clear_color=*/SK_ColorTRANSPARENT, is_pixel_canvas)
             .context(),
         size()));
-    return gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, scale));
+    return gfx::ImageSkia::CreateFromBitmap(bitmap, scale);
   }
 
   // Returns the drag offset to use when rendering this view as a drag image.
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py
index 5a10a3b..aa4b3dcd 100755
--- a/build/android/gyp/proguard.py
+++ b/build/android/gyp/proguard.py
@@ -411,12 +411,6 @@
         # TODO(crbug.com/1142530): Fix this missing reference properly.
         'org/chromium/base/library_loader/NativeLibraries',
 
-        # Currently required when enable_chrome_android_internal=true.
-        'com/google/protos/research/ink/InkEventProto',
-        'ink_sdk/com/google/protobuf/Internal$EnumVerifier',
-        'ink_sdk/com/google/protobuf/MessageLite',
-        'com/google/protobuf/GeneratedMessageLite$GeneratedExtension',
-
         # TODO(agrieve): Exclude these only when use_jacoco_coverage=true.
         'Ljava/lang/instrument/ClassFileTransformer',
         'Ljava/lang/instrument/IllegalClassFormatException',
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index e5d0729..a473867 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -284,6 +284,7 @@
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchContextControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchImageControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java",
+  "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHelp.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchQuickActionControl.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
index 364db3a2..e1ecaf63 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
@@ -10,15 +10,22 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.PackageManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.SystemClock;
 
+import dalvik.system.DexFile;
+
 import org.chromium.base.ActivityState;
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.JNIUtils;
+import org.chromium.base.Log;
+import org.chromium.base.PackageUtils;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
 import java.lang.reflect.Field;
 
@@ -27,8 +34,11 @@
  * perform any necessary initialization for non-browser processes without loading code from the
  * chrome split. In the browser process, the necessary logic is loaded from the chrome split using
  * reflection.
+ *
+ * This class will be used when isolated splits are enabled.
  */
 public class SplitChromeApplication extends SplitCompatApplication {
+    private static final String TAG = "SplitChromeApp";
     private String mChromeApplicationClassName;
     private SplitPreloader mSplitPreloader;
 
@@ -59,6 +69,7 @@
                         chromeContext, mChromeApplicationClassName);
             });
             applyActivityClassLoaderWorkaround();
+            applyDexCompileWorkaround();
         } else {
             setImplSupplier(() -> createNonBrowserApplication());
         }
@@ -164,6 +175,63 @@
                 });
     }
 
+    /**
+     * Android OMR1 has a bug where bg-dexopt-job will break optimized dex files for splits. This
+     * leads to *very* slow startup on those devices. To mitigate this, we attempt to force a dex
+     * compile if necessary.
+     */
+    private void applyDexCompileWorkaround() {
+        // This bug only happens in OMR1.
+        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
+            return;
+        }
+
+        new Thread(() -> {
+            try {
+                // If the app has just been updated, it will be compiled with quicken. The next time
+                // bg-dexopt-job runs it will break the optimized dex for splits. If we force
+                // compile now, then bg-dexopt-job won't mess up the splits, and we save the user a
+                // slow startup.
+                if (needsDexCompileAfterUpdate()) {
+                    performDexCompile();
+                    return;
+                }
+
+                // Make sure all splits are compiled correclty, and if not force a compile.
+                for (String sourceDir : getApplicationInfo().splitSourceDirs) {
+                    if (DexFile.isDexOptNeeded(sourceDir)) {
+                        performDexCompile();
+                        return;
+                    }
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Error compiling dex.", e);
+            }
+        }).start();
+    }
+
+    /** Returns whether the dex has been compiled since the last app update. */
+    private boolean needsDexCompileAfterUpdate() {
+        return SharedPreferencesManager.getInstance().readInt(
+                       ChromePreferenceKeys.ISOLATED_SPLITS_DEX_COMPILE_VERSION)
+                != PackageUtils.getPackageVersion(this, getPackageName());
+    }
+
+    /** Compiles dex for the app, and sets the pref key tracking the latest compiled version. */
+    private void performDexCompile() throws Exception {
+        Class<?> c = Class.forName("android.os.SystemProperties");
+        java.lang.reflect.Method get = c.getMethod("get", String.class, String.class);
+        // Use the shared compile mode, and if we can't find that, default to speed. The shared
+        // compile mode will be quicken on Android Go.
+        String compileMode = (String) get.invoke(null, "pm.dexopt.shared", "speed");
+
+        Runtime.getRuntime().exec(new String[] {
+                "cmd", "package", "compile", "-m", compileMode, "-f", getPackageName()});
+        SharedPreferencesManager.getInstance().writeInt(
+                ChromePreferenceKeys.ISOLATED_SPLITS_DEX_COMPILE_VERSION,
+                PackageUtils.getPackageVersion(this, getPackageName()));
+    }
+
     private static void replaceClassLoader(Context baseContext, ClassLoader classLoader) {
         while (baseContext instanceof ContextWrapper) {
             baseContext = ((ContextWrapper) baseContext).getBaseContext();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
index 434e05b06..b667faf6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
@@ -44,6 +44,9 @@
  * Application base class which will call through to the given {@link Impl}. Application classes
  * which extend this class should also extend {@link Impl}, and call {@link #setImpl(Impl)} before
  * calling {@link attachBaseContext(Context)}.
+ *
+ * This is the base class of all Chrome applications. Logic specific to isolated splits should go in
+ * {@link SplitChromeApplication}.
  */
 public class SplitCompatApplication extends Application {
     private static final String COMMAND_LINE_FILE = "chrome-command-line";
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 b1e5c794..5013f0e2 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
@@ -9,6 +9,7 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.ActivityState;
@@ -46,6 +47,10 @@
     /** The distance of the divider from the end of the bar, in dp. */
     private final float mEndButtonWidthDp;
 
+    /** The Help section of the Panel. */
+    @NonNull
+    private final ContextualSearchPanelHelp mPanelHelp;
+
     /** Whether the Panel should be promoted to a new tab after being maximized. */
     private boolean mShouldPromoteToTabAfterMaximizing;
 
@@ -88,6 +93,7 @@
         mEndButtonWidthDp = mContext.getResources().getDimensionPixelSize(
                                     R.dimen.contextual_search_padded_button_width)
                 * mPxToDp;
+        mPanelHelp = new ContextualSearchPanelHelp(context);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHelp.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHelp.java
new file mode 100644
index 0000000..9a7d85e5
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHelp.java
@@ -0,0 +1,31 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.compositor.bottombar.contextualsearch;
+
+import android.content.Context;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+
+/**
+ * Controls a section of the Panel that provides end user help messages.
+ * TODO(donnd): Implement along the lines of {@code ContextualSearchPromoControl}.
+ */
+public class ContextualSearchPanelHelp {
+    private final boolean mIsEnabled;
+    private final String mHelpHeaderText;
+    private final String mHelpBodyText;
+
+    /**
+     * @param context The current Android {@link Context}.
+     */
+    ContextualSearchPanelHelp(Context context) {
+        mIsEnabled = ChromeFeatureList.isEnabled(
+                ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_PANEL_HELP);
+        mHelpHeaderText = context.getResources().getString(R.string.contextual_search_help_header);
+        mHelpBodyText = context.getResources().getString(R.string.contextual_search_help_body);
+        // TODO(donnd): Update this class and constructor to do useful work.
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
index e0cce7b..2486eb3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
@@ -96,11 +96,8 @@
      * @param container         The container View used to inflate the View.
      * @param resourceLoader    The resource loader that will handle the snapshot capturing.
      */
-    public ContextualSearchPromoControl(OverlayPanel panel,
-                                        ContextualSearchPromoHost host,
-                                        Context context,
-                                        ViewGroup container,
-                                        DynamicResourceLoader resourceLoader) {
+    ContextualSearchPromoControl(OverlayPanel panel, ContextualSearchPromoHost host,
+            Context context, ViewGroup container, DynamicResourceLoader resourceLoader) {
         super(panel, R.layout.contextual_search_promo_view,
                 R.id.contextual_search_promo, context, container, resourceLoader);
 
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index fcd78ec842..2d71a60 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -10701,6 +10701,9 @@
       <message name="IDS_WEBAUTHN_CLIENT_PIN_AUTHENTICATOR_REMOVED_DESCRIPTION" desc="Description in the error dialog shown after their security key (an external physical device for user authentication) was removed while the application was waiting for the security key PIN to be entered.">
         Reinsert your security key and try again
       </message>
+      <message name="IDS_WEBAUTHN_PIN_ENTRY_ERROR_SAME_AS_CURRENT" desc="Error message. Displayed when the user attempts to set a new PIN code for their security key (an external physical device for user authentication), and the new PIN is the same as the currently set PIN.">
+        Create a new PIN that's different from your current PIN
+      </message>
 
       <!-- WebAuthn authenticator internal user verification -->
       <message name="IDS_WEBAUTHN_INLINE_ENROLLMENT_CANCEL_LABEL" desc="The label on a button allowing users to skip fingerprint registration when setting up a fingerprint enabled authenticator.">
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_PIN_ENTRY_ERROR_SAME_AS_CURRENT.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_PIN_ENTRY_ERROR_SAME_AS_CURRENT.png.sha1
new file mode 100644
index 0000000..04f59b7
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_PIN_ENTRY_ERROR_SAME_AS_CURRENT.png.sha1
@@ -0,0 +1 @@
+ef36303bdac070a591fdc032977a5dd3240f83cc
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index c795c1d..a77b92f 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -100,17 +100,17 @@
   <message name="IDS_SETTINGS_HOME_BUTTON_DISABLED" desc="Sub label for the Show home button setting when disabled.">
     Disabled
   </message>
-  <if expr="chromeos">
+  <if expr="chromeos or lacros">
     <message name="IDS_SETTINGS_THEMES" desc="Name of the control which allows the user to get a theme for the browser.">
       Browser themes
     </message>
   </if>
-  <if expr="not chromeos">
+  <if expr="not chromeos and not lacros">
     <message name="IDS_SETTINGS_THEMES" desc="Name of the control which allows the user to get a theme for the browser.">
       Theme
     </message>
   </if>
-  <if expr="is_linux and not chromeos">
+  <if expr="is_linux and not chromeos and not lacros">
     <message name="IDS_SETTINGS_SYSTEM_THEME" desc="Text of the label describing the system (GTK+) browser theme on Linux">
       GTK+
     </message>
@@ -124,7 +124,7 @@
       Use Classic
     </message>
   </if>
-  <if expr="not is_linux or chromeos">
+  <if expr="not is_linux or chromeos or lacros">
     <message name="IDS_SETTINGS_RESET_TO_DEFAULT_THEME" desc="Name of the control which resets the browser theme back to the default theme.">
       Reset to default
     </message>
@@ -586,7 +586,7 @@
     Move
   </message>
   <message name="IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT" desc="Text for the button that cancels the action of moving a password to the user Google Account.">
-    No thanks
+    Cancel
   </message>
   <message name="IDS_SETTINGS_PASSWORD_OPEN_MOVE_MULTIPLE_PASSWORDS_TO_ACCOUNT_DIALOG_BUTTON_TEXT" desc="Text for the button that opens the dialog that moves multiple passwords to the user Google Account.">
     Move passwords
@@ -609,14 +609,8 @@
   <message name="IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_FROM_DEVICE_CHECKBOX_LABEL" desc="The label for the checkbox that represents whether the user wishes to remove a password from the device.">
     From this device
   </message>
-  <message name="IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR" desc="The label for the link on settings leading to the 'device passwords' page, when there is 1 device password.">
-    You have 1 password saved on this device
-  </message>
-  <message name="IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL" desc="The label for the link on settings leading to the 'device passwords' page, when there is more than 1 device password.">
-    You have <ph name="NUMBER_OF_DEVICE_PASSWORDS">$1<ex>2</ex></ph> passwords saved on this device
-  </message>
-  <message name="IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL" desc="The sub-label for the link on settings leading to the 'device passwords' page.">
-    Save all your passwords in your Google Account, so you can use them on all your devices
+  <message name="IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL" desc="The label for the link on settings leading to the 'device passwords' page.">
+    See and manage passwords saved on this device
   </message>
   <message name="IDS_SETTINGS_PASSWORDS_MANAGE_PASSWORDS" desc="Shown in the passwords section of settings. Descriptive text to inform that passwords can be accessed online. Has a link.">
     View and manage saved passwords in your <ph name="BEGIN_LINK">&lt;a is="action-link" href="$1" target="_blank"&gt;</ph>Google Account<ph name="END_LINK">&lt;/a&gt;</ph>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL.png.sha1
new file mode 100644
index 0000000..06d17f4
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL.png.sha1
@@ -0,0 +1 @@
+1c45071d1fddd97f280aecf63df2a04e24b1a9a6
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL.png.sha1
deleted file mode 100644
index b542b46b..0000000
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5fd06cd94a1ed3799b1255fcce176240ec7c0e4e
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR.png.sha1
deleted file mode 100644
index 768e0da5..0000000
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-05437d4c175654f3739e031c851b1cee1979d27f
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL.png.sha1
deleted file mode 100644
index b542b46b..0000000
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5fd06cd94a1ed3799b1255fcce176240ec7c0e4e
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT.png.sha1
index d51f775..c06374e 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT.png.sha1
@@ -1 +1 @@
-30f492c6f7b9086acf66d2b2b24fbd54781f2c34
\ No newline at end of file
+360e52314348f6321593ad6e781163aec6224fe5
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index d5707259..d43857a 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -476,6 +476,8 @@
     "download/trusted_sources_manager.h",
     "endpoint_fetcher/endpoint_fetcher.cc",
     "endpoint_fetcher/endpoint_fetcher.h",
+    "engagement/history_aware_site_engagement_service.cc",
+    "engagement/history_aware_site_engagement_service.h",
     "engagement/important_sites_usage_counter.cc",
     "engagement/important_sites_usage_counter.h",
     "engagement/important_sites_util.cc",
@@ -496,6 +498,8 @@
     "enterprise/browser_management/browser_management_service.h",
     "enterprise/browser_management/browser_management_status_provider.cc",
     "enterprise/browser_management/browser_management_status_provider.h",
+    "enterprise/util/affiliation.cc",
+    "enterprise/util/affiliation.h",
     "enterprise/util/managed_browser_utils.cc",
     "enterprise/util/managed_browser_utils.h",
     "expired_flags_list.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 71c195d..61f0b2d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4638,11 +4638,6 @@
      flag_descriptions::kTabHoverCardImagesDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kTabHoverCardImages)},
 
-    {"stop-non-timers-in-background",
-     flag_descriptions::kStopNonTimersInBackgroundName,
-     flag_descriptions::kStopNonTimersInBackgroundDescription, kOsAll,
-     FEATURE_VALUE_TYPE(blink::features::kStopNonTimersInBackground)},
-
     {"stop-in-background", flag_descriptions::kStopInBackgroundName,
      flag_descriptions::kStopInBackgroundDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(blink::features::kStopInBackground)},
@@ -5095,9 +5090,6 @@
      FEATURE_VALUE_TYPE(features::kDestroyProfileOnBrowserClose)},
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-    {"enable-usbguard", flag_descriptions::kUsbguardName,
-     flag_descriptions::kUsbguardDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(features::kUsbguard)},
     {"enable-fs-nosymfollow", flag_descriptions::kFsNosymfollowName,
      flag_descriptions::kFsNosymfollowDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kFsNosymfollow)},
@@ -5358,13 +5350,6 @@
          autofill_assistant::features::kAutofillAssistantProactiveHelp)},
 #endif  // defined(OS_ANDROID)
 
-#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-    {"web-contents-occlusion", flag_descriptions::kWebContentsOcclusionName,
-     flag_descriptions::kWebContentsOcclusionDescription,
-     kOsWin | kOsMac | kOsCrOS,
-     FEATURE_VALUE_TYPE(features::kWebContentsOcclusion)},
-#endif  // defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if defined(OS_ANDROID)
     {"mobile-identity-consistency",
      flag_descriptions::kMobileIdentityConsistencyName,
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc
index cf8a22a..13411b9 100644
--- a/chrome/browser/apps/app_service/app_icon_factory.cc
+++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -226,7 +226,7 @@
 }
 
 gfx::ImageSkia SkBitmapToImageSkia(SkBitmap bitmap, float icon_scale) {
-  return gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, icon_scale));
+  return gfx::ImageSkia::CreateFromBitmap(bitmap, icon_scale);
 }
 
 // Returns a callback that converts a gfx::Image to an ImageSkia.
diff --git a/chrome/browser/apps/app_service/app_icon_factory_unittest.cc b/chrome/browser/apps/app_service/app_icon_factory_unittest.cc
index cc6c58f6..4989837 100644
--- a/chrome/browser/apps/app_service/app_icon_factory_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon_factory_unittest.cc
@@ -195,7 +195,7 @@
     ASSERT_TRUE(gfx::PNGCodec::Decode(compressed_data.data(),
                                       compressed_data.size(), &decoded));
 
-    output_image_skia = gfx::ImageSkia(gfx::ImageSkiaRep(decoded, scale));
+    output_image_skia = gfx::ImageSkia::CreateFromBitmap(decoded, scale);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     if (base::FeatureList::IsEnabled(features::kAppServiceAdaptiveIcon)) {
diff --git a/chrome/browser/chromeos/crosapi/message_center_ash_unittest.cc b/chrome/browser/chromeos/crosapi/message_center_ash_unittest.cc
index 3e3303f..27a5b43 100644
--- a/chrome/browser/chromeos/crosapi/message_center_ash_unittest.cc
+++ b/chrome/browser/chromeos/crosapi/message_center_ash_unittest.cc
@@ -196,7 +196,8 @@
 
   // Create a high DPI image.
   SkBitmap bitmap = gfx::test::CreateBitmap(2, 4);
-  gfx::ImageSkia high_dpi_image_skia(gfx::ImageSkiaRep(bitmap, 2.0f));
+  gfx::ImageSkia high_dpi_image_skia =
+      gfx::ImageSkia::CreateFromBitmap(bitmap, 2.0f);
   mojo_notification->image = high_dpi_image_skia;
 
   // Display the notification.
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
index 9a5a8fa..005199c 100644
--- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
+++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
@@ -91,13 +91,6 @@
                      weak_ptr_factory_.GetWeakPtr()));
   exported_object->ExportMethod(
       kChromeFeaturesServiceInterface,
-      kChromeFeaturesServiceIsUsbguardEnabledMethod,
-      base::BindRepeating(&ChromeFeaturesServiceProvider::IsUsbguardEnabled,
-                          weak_ptr_factory_.GetWeakPtr()),
-      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
-                     weak_ptr_factory_.GetWeakPtr()));
-  exported_object->ExportMethod(
-      kChromeFeaturesServiceInterface,
       kChromeFeaturesServiceIsCryptohomeDistributedModelEnabledMethod,
       base::BindRepeating(
           &ChromeFeaturesServiceProvider::IsCryptohomeDistributedModelEnabled,
@@ -143,8 +136,6 @@
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
   static const base::Feature constexpr* kFeatureLookup[] = {
-      &::features::kUsbbouncer,
-      &::features::kUsbguard,
       &arc::kBootCompletedBroadcastFeature,
       &arc::kCustomTabsExperimentFeature,
       &arc::kFilePickerExperimentFeature,
@@ -229,13 +220,6 @@
       profile ? plugin_vm::PluginVmFeatures::Get()->IsAllowed(profile) : false);
 }
 
-void ChromeFeaturesServiceProvider::IsUsbguardEnabled(
-    dbus::MethodCall* method_call,
-    dbus::ExportedObject::ResponseSender response_sender) {
-  SendResponse(method_call, std::move(response_sender),
-               base::FeatureList::IsEnabled(::features::kUsbguard));
-}
-
 void ChromeFeaturesServiceProvider::IsVmManagementCliAllowed(
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
index 8a54dfd6e6..3e57043a 100644
--- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
+++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
@@ -76,8 +76,6 @@
       dbus::ExportedObject::ResponseSender response_sender);
   void IsPluginVmEnabled(dbus::MethodCall* method_call,
                          dbus::ExportedObject::ResponseSender response_sender);
-  void IsUsbguardEnabled(dbus::MethodCall* method_call,
-                         dbus::ExportedObject::ResponseSender response_sender);
   void IsVmManagementCliAllowed(
       dbus::MethodCall* method_call,
       dbus::ExportedObject::ResponseSender response_sender);
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_view.cc b/chrome/browser/chromeos/input_method/ui/candidate_view.cc
index 81fdd81..6c93e81 100644
--- a/chrome/browser/chromeos/input_method/ui/candidate_view.cc
+++ b/chrome/browser/chromeos/input_method/ui/candidate_view.cc
@@ -15,6 +15,7 @@
 #include "ui/views/background.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/label.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 
 namespace ui {
@@ -26,7 +27,10 @@
 // the vertical candidate window.
 class VerticalCandidateLabel : public views::Label {
  public:
+  METADATA_HEADER(VerticalCandidateLabel);
   VerticalCandidateLabel() = default;
+  VerticalCandidateLabel(const VerticalCandidateLabel&) = delete;
+  VerticalCandidateLabel& operator=(const VerticalCandidateLabel&) = delete;
   ~VerticalCandidateLabel() override = default;
 
  private:
@@ -39,12 +43,11 @@
     size.SetToMin(gfx::Size(kMaxCandidateLabelWidth, size.height()));
     return size;
   }
-
-  const char* GetClassName() const override { return "VerticalCandidateLabel"; }
-
-  DISALLOW_COPY_AND_ASSIGN(VerticalCandidateLabel);
 };
 
+BEGIN_METADATA(VerticalCandidateLabel, views::Label)
+END_METADATA
+
 // Creates the shortcut label, and returns it (never returns nullptr).
 // The label text is not set in this function.
 std::unique_ptr<views::Label> CreateShortcutLabel(
@@ -211,10 +214,6 @@
     SetHighlighted(true);
 }
 
-const char* CandidateView::GetClassName() const {
-  return "CandidateView";
-}
-
 bool CandidateView::OnMouseDragged(const ui::MouseEvent& event) {
   if (!HitTestPoint(event.location())) {
     // Moves the drag target to the sibling view.
@@ -300,5 +299,8 @@
                              total_candidates_);
 }
 
+BEGIN_METADATA(CandidateView, views::Button)
+END_METADATA
+
 }  // namespace ime
 }  // namespace ui
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_view.h b/chrome/browser/chromeos/input_method/ui/candidate_view.h
index 5deb714..1ebe8e6 100644
--- a/chrome/browser/chromeos/input_method/ui/candidate_view.h
+++ b/chrome/browser/chromeos/input_method/ui/candidate_view.h
@@ -11,6 +11,8 @@
 #include "ui/chromeos/ui_chromeos_export.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/view.h"
 
 namespace ui {
@@ -19,8 +21,11 @@
 // CandidateView renderes a row of a candidate.
 class UI_CHROMEOS_EXPORT CandidateView : public views::Button {
  public:
+  METADATA_HEADER(CandidateView);
   CandidateView(PressedCallback callback,
                 ui::CandidateWindow::Orientation orientation);
+  CandidateView(const CandidateView&) = delete;
+  CandidateView& operator=(const CandidateView&) = delete;
   ~CandidateView() override {}
 
   void GetPreferredWidths(int* shortcut_width, int* candidate_width);
@@ -44,7 +49,6 @@
   void StateChanged(ButtonState old_state) override;
 
   // Overridden from View:
-  const char* GetClassName() const override;
   bool OnMouseDragged(const ui::MouseEvent& event) override;
   void Layout() override;
   gfx::Size CalculatePreferredSize() const override;
@@ -72,11 +76,17 @@
   // 0-based index of this candidate e.g. [0, total_candidates_ -1].
   int candidate_index_;
   int total_candidates_;
-
-  DISALLOW_COPY_AND_ASSIGN(CandidateView);
 };
 
+BEGIN_VIEW_BUILDER(UI_CHROMEOS_EXPORT, CandidateView, views::Button)
+VIEW_BUILDER_PROPERTY(bool, InfolistIcon)
+VIEW_BUILDER_PROPERTY(bool, Highlighted)
+VIEW_BUILDER_PROPERTY(const ui::CandidateWindow::Entry&, Entry)
+END_VIEW_BUILDER
+
 }  // namespace ime
 }  // namespace ui
 
+DEFINE_VIEW_BUILDER(UI_CHROMEOS_EXPORT, ui::ime::CandidateView)
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_CANDIDATE_VIEW_H_
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc b/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc
index d46e24d..8682b1b7 100644
--- a/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc
+++ b/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc
@@ -28,6 +28,7 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/wm/core/window_animations.h"
 
 namespace ui {
@@ -418,14 +419,13 @@
                                                    total_candidates);
 }
 
-const char* CandidateWindowView::GetClassName() const {
-  return "CandidateWindowView";
-}
-
 void CandidateWindowView::CandidateViewPressed(int index) {
   for (Observer& observer : observers_)
     observer.OnCandidateCommitted(index);
 }
 
+BEGIN_METADATA(CandidateWindowView, views::BubbleDialogDelegateView)
+END_METADATA
+
 }  // namespace ime
 }  // namespace ui
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_window_view.h b/chrome/browser/chromeos/input_method/ui/candidate_window_view.h
index 6746789a..5ed8be9 100644
--- a/chrome/browser/chromeos/input_method/ui/candidate_window_view.h
+++ b/chrome/browser/chromeos/input_method/ui/candidate_window_view.h
@@ -11,6 +11,8 @@
 #include "ui/base/ime/candidate_window.h"
 #include "ui/chromeos/ui_chromeos_export.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/view_factory.h"
 
 namespace ui {
 namespace ime {
@@ -22,6 +24,7 @@
 class UI_CHROMEOS_EXPORT CandidateWindowView
     : public views::BubbleDialogDelegateView {
  public:
+  METADATA_HEADER(CandidateWindowView);
   // The object can be monitored by the observer.
   class Observer {
    public:
@@ -31,6 +34,8 @@
   };
 
   explicit CandidateWindowView(gfx::NativeView parent);
+  CandidateWindowView(const CandidateWindowView&) = delete;
+  CandidateWindowView& operator=(const CandidateWindowView&) = delete;
   ~CandidateWindowView() override;
   views::Widget* InitWidget();
 
@@ -73,9 +78,6 @@
  private:
   friend class CandidateWindowViewTest;
 
-  // views::BubbleDialogDelegateView:
-  const char* GetClassName() const override;
-
   void SelectCandidateAt(int index_in_page);
   void UpdateVisibility();
 
@@ -125,11 +127,16 @@
   // True if the candidate window was open.  This is used to determine when to
   // send OnCandidateWindowOpened and OnCandidateWindowClosed events.
   bool was_candidate_window_open_;
-
-  DISALLOW_COPY_AND_ASSIGN(CandidateWindowView);
 };
 
+BEGIN_VIEW_BUILDER(UI_CHROMEOS_EXPORT,
+                   CandidateWindowView,
+                   views::BubbleDialogDelegateView)
+END_VIEW_BUILDER
+
 }  // namespace ime
 }  // namespace ui
 
+DEFINE_VIEW_BUILDER(UI_CHROMEOS_EXPORT, ui::ime::CandidateWindowView)
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_CANDIDATE_WINDOW_VIEW_H_
diff --git a/chrome/browser/chromeos/input_method/ui/infolist_window.cc b/chrome/browser/chromeos/input_method/ui/infolist_window.cc
index 717b6c50..ceea2e5 100644
--- a/chrome/browser/chromeos/input_method/ui/infolist_window.cc
+++ b/chrome/browser/chromeos/input_method/ui/infolist_window.cc
@@ -23,6 +23,7 @@
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/window_animations.h"
 
@@ -87,9 +88,12 @@
 // InfolistRow renderes a row of a infolist.
 class InfolistEntryView : public views::View {
  public:
+  METADATA_HEADER(InfolistEntryView);
   InfolistEntryView(const ui::InfolistEntry& entry,
                     const gfx::FontList& title_font_list,
                     const gfx::FontList& description_font_list);
+  InfolistEntryView(const InfolistEntryView&) = delete;
+  InfolistEntryView& operator=(const InfolistEntryView&) = delete;
   ~InfolistEntryView() override;
 
   void SetEntry(const ui::InfolistEntry& entry);
@@ -107,10 +111,11 @@
 
   // The description label. Owned by views hierarchy.
   views::Label* description_label_;
-
-  DISALLOW_COPY_AND_ASSIGN(InfolistEntryView);
 };
 
+BEGIN_METADATA(InfolistEntryView, views::View)
+END_METADATA
+
 InfolistEntryView::InfolistEntryView(const ui::InfolistEntry& entry,
                                      const gfx::FontList& title_font_list,
                                      const gfx::FontList& description_font_list)
@@ -268,13 +273,12 @@
   GetWidget()->Close();
 }
 
-const char* InfolistWindow::GetClassName() const {
-  return "InfolistWindow";
-}
-
 void InfolistWindow::WindowClosing() {
   show_hide_timer_.Stop();
 }
 
+BEGIN_METADATA(InfolistWindow, views::BubbleDialogDelegateView)
+END_METADATA
+
 }  // namespace ime
 }  // namespace ui
diff --git a/chrome/browser/chromeos/input_method/ui/infolist_window.h b/chrome/browser/chromeos/input_method/ui/infolist_window.h
index 445224d..89b7548 100644
--- a/chrome/browser/chromeos/input_method/ui/infolist_window.h
+++ b/chrome/browser/chromeos/input_method/ui/infolist_window.h
@@ -16,6 +16,8 @@
 #include "ui/chromeos/ui_chromeos_export.h"
 #include "ui/gfx/font_list.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/view_factory.h"
 
 namespace ui {
 namespace ime {
@@ -26,8 +28,11 @@
 class UI_CHROMEOS_EXPORT InfolistWindow
     : public views::BubbleDialogDelegateView {
  public:
+  METADATA_HEADER(InfolistWindow);
   InfolistWindow(views::View* candidate_window,
                  const std::vector<ui::InfolistEntry>& entries);
+  InfolistWindow(const InfolistWindow&) = delete;
+  InfolistWindow& operator=(const InfolistWindow&) = delete;
   ~InfolistWindow() override;
   void InitWidget();
 
@@ -43,9 +48,6 @@
   void HideImmediately();
 
  private:
-  // views::BubbleDialogDelegateView:
-  const char* GetClassName() const override;
-
   // views::WidgetDelegate implementation.
   void WindowClosing() override;
 
@@ -59,11 +61,16 @@
   gfx::FontList description_font_list_;
 
   base::OneShotTimer show_hide_timer_;
-
-  DISALLOW_COPY_AND_ASSIGN(InfolistWindow);
 };
 
+BEGIN_VIEW_BUILDER(UI_CHROMEOS_EXPORT,
+                   InfolistWindow,
+                   views::BubbleDialogDelegateView)
+END_VIEW_BUILDER
+
 }  // namespace ime
 }  // namespace ui
 
+DEFINE_VIEW_BUILDER(UI_CHROMEOS_EXPORT, ui::ime::InfolistWindow)
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_INFOLIST_WINDOW_H_
diff --git a/chrome/browser/chromeos/input_method/ui/suggestion_view.cc b/chrome/browser/chromeos/input_method/ui/suggestion_view.cc
index 755d46e9..e84cc407 100644
--- a/chrome/browser/chromeos/input_method/ui/suggestion_view.cc
+++ b/chrome/browser/chromeos/input_method/ui/suggestion_view.cc
@@ -16,6 +16,7 @@
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 
 namespace ui {
@@ -196,10 +197,6 @@
   views::View::OnThemeChanged();
 }
 
-const char* SuggestionView::GetClassName() const {
-  return "SuggestionView";
-}
-
 void SuggestionView::Layout() {
   int left = kPadding;
   if (index_label_->GetVisible()) {
@@ -241,5 +238,8 @@
   min_width_ = min_width;
 }
 
+BEGIN_METADATA(SuggestionView, views::Button)
+END_METADATA
+
 }  // namespace ime
 }  // namespace ui
diff --git a/chrome/browser/chromeos/input_method/ui/suggestion_view.h b/chrome/browser/chromeos/input_method/ui/suggestion_view.h
index 9abc274..c6dc4daf 100644
--- a/chrome/browser/chromeos/input_method/ui/suggestion_view.h
+++ b/chrome/browser/chromeos/input_method/ui/suggestion_view.h
@@ -11,6 +11,8 @@
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/styled_label.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/view.h"
 
 namespace views {
@@ -42,7 +44,10 @@
 // SuggestionView renders a suggestion.
 class UI_CHROMEOS_EXPORT SuggestionView : public views::Button {
  public:
+  METADATA_HEADER(SuggestionView);
   explicit SuggestionView(PressedCallback callback);
+  SuggestionView(const SuggestionView&) = delete;
+  SuggestionView& operator=(const SuggestionView&) = delete;
   ~SuggestionView() override;
 
   void SetView(const SuggestionDetails& details);
@@ -57,8 +62,6 @@
   friend class SuggestionWindowViewTest;
   FRIEND_TEST_ALL_PREFIXES(SuggestionWindowViewTest, ShortcutSettingTest);
 
-  // Overridden from View:
-  const char* GetClassName() const override;
   void Layout() override;
   gfx::Size CalculatePreferredSize() const override;
   void OnThemeChanged() override;
@@ -83,11 +86,17 @@
   int index_width_ = 0;
   int min_width_ = 0;
   bool highlighted_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(SuggestionView);
 };
 
+BEGIN_VIEW_BUILDER(UI_CHROMEOS_EXPORT, SuggestionView, views::Button)
+VIEW_BUILDER_PROPERTY(const SuggestionDetails&, View)
+VIEW_BUILDER_PROPERTY(bool, Highlighted)
+VIEW_BUILDER_PROPERTY(int, MinWidth)
+END_VIEW_BUILDER
+
 }  // namespace ime
 }  // namespace ui
 
+DEFINE_VIEW_BUILDER(UI_CHROMEOS_EXPORT, ui::ime::SuggestionView)
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_SUGGESTION_VIEW_H_
diff --git a/chrome/browser/chromeos/input_method/ui/undo_window.cc b/chrome/browser/chromeos/input_method/ui/undo_window.cc
index 16330f5..b3c5bb9 100644
--- a/chrome/browser/chromeos/input_method/ui/undo_window.cc
+++ b/chrome/browser/chromeos/input_method/ui/undo_window.cc
@@ -11,6 +11,7 @@
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/layout_provider.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/wm/core/window_animations.h"
 
 namespace ui {
@@ -100,10 +101,6 @@
   return undo_button_;
 }
 
-const char* UndoWindow::GetClassName() const {
-  return "UndoWindow";
-}
-
 void UndoWindow::UndoButtonPressed() {
   const AssistiveWindowButton button = {
       .id = ButtonId::kUndo, .window_type = AssistiveWindowType::kUndoWindow};
@@ -111,5 +108,8 @@
   delegate_->AssistiveWindowButtonClicked(button);
 }
 
+BEGIN_METADATA(UndoWindow, views::BubbleDialogDelegateView)
+END_METADATA
+
 }  // namespace ime
 }  // namespace ui
diff --git a/chrome/browser/chromeos/input_method/ui/undo_window.h b/chrome/browser/chromeos/input_method/ui/undo_window.h
index ed54bb8..32aced39 100644
--- a/chrome/browser/chromeos/input_method/ui/undo_window.h
+++ b/chrome/browser/chromeos/input_method/ui/undo_window.h
@@ -9,6 +9,8 @@
 #include "ui/chromeos/ui_chromeos_export.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 #include "ui/views/controls/button/label_button.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/view_factory.h"
 
 namespace ui {
 namespace ime {
@@ -16,7 +18,10 @@
 // Pop up UI for users to undo an autocorrected word.
 class UI_CHROMEOS_EXPORT UndoWindow : public views::BubbleDialogDelegateView {
  public:
+  METADATA_HEADER(UndoWindow);
   explicit UndoWindow(gfx::NativeView parent, AssistiveDelegate* delegate);
+  UndoWindow(const UndoWindow&) = delete;
+  UndoWindow& operator=(const UndoWindow&) = delete;
   ~UndoWindow() override;
 
   views::Widget* InitWidget();
@@ -35,18 +40,21 @@
   void OnThemeChanged() override;
 
  private:
-  // views::BubbleDialogDelegateView:
-  const char* GetClassName() const override;
 
   void UndoButtonPressed();
 
   AssistiveDelegate* delegate_;
   views::LabelButton* undo_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(UndoWindow);
 };
 
+BEGIN_VIEW_BUILDER(UI_CHROMEOS_EXPORT,
+                   UndoWindow,
+                   views::BubbleDialogDelegateView)
+END_VIEW_BUILDER
+
 }  // namespace ime
 }  // namespace ui
 
+DEFINE_VIEW_BUILDER(UI_CHROMEOS_EXPORT, ui::ime::UndoWindow)
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_UNDO_WINDOW_H_
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
index fd21d69..75d009133 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
@@ -66,7 +66,7 @@
 }
 
 void ImageLoader::OnImageDecoded(const SkBitmap& decoded_image) {
-  decoded_image_ = gfx::ImageSkia(gfx::ImageSkiaRep(decoded_image, 1.0f));
+  decoded_image_ = gfx::ImageSkia::CreateFromBitmap(decoded_image, 1.0f);
   run_loop_.Quit();
 }
 
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc b/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc
index a7768cb..d3f9ddb 100644
--- a/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc
+++ b/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc
@@ -126,7 +126,7 @@
   SkBitmap bitmap;
   bitmap.allocN32Pixels(size, size);
   bitmap.eraseColor(color);
-  return gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, 1.0f));
+  return gfx::ImageSkia::CreateFromBitmap(bitmap, 1.0f);
 }
 
 void CheckIconsEqual(const gfx::ImageSkia& expected,
diff --git a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
index 7e866ed..bced4c3 100644
--- a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
+++ b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "ash/public/cpp/tablet_mode.h"
 #include "base/files/file_path.h"
 #include "base/system/sys_info.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
@@ -18,7 +19,9 @@
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/browser/web_launch/web_launch_files_helper.h"
@@ -31,15 +34,6 @@
 #include "ui/gfx/native_widget_types.h"
 #include "url/gurl.h"
 
-// static
-void ChromeCameraAppUIDelegate::CameraAppDialog::ShowIntent(
-    const std::string& queries,
-    gfx::NativeWindow parent) {
-  std::string url = chromeos::kChromeUICameraAppMainURL + queries;
-  CameraAppDialog* dialog = new CameraAppDialog(url);
-  dialog->ShowSystemDialog(parent);
-}
-
 ChromeCameraAppUIDelegate::CameraAppDialog::CameraAppDialog(
     const std::string& url)
     : chromeos::SystemWebDialogDelegate(GURL(url),
@@ -80,6 +74,23 @@
 ChromeCameraAppUIDelegate::ChromeCameraAppUIDelegate(content::WebUI* web_ui)
     : web_ui_(web_ui) {}
 
+// static
+void ChromeCameraAppUIDelegate::ShowIntent(const std::string& queries,
+                                           gfx::NativeWindow parent) {
+  std::string url = chromeos::kChromeUICameraAppMainURL + queries;
+
+  // For tablet mode, apps should better display in fullscreen. Therefore, it is
+  // preferable to launch CCA into a browser, which will handle the tablet mode
+  // case itself, rather than a system dialog.
+  if (ash::TabletMode::Get()->InTabletMode()) {
+    web_app::LaunchSystemWebApp(ProfileManager::GetActiveUserProfile(),
+                                web_app::SystemAppType::CAMERA, GURL(url));
+  } else {
+    CameraAppDialog* dialog = new CameraAppDialog(url);
+    dialog->ShowSystemDialog(parent);
+  }
+}
+
 void ChromeCameraAppUIDelegate::SetLaunchDirectory() {
   Profile* profile = Profile::FromWebUI(web_ui_);
   content::WebContents* web_contents = web_ui_->GetWebContents();
diff --git a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h
index 403b1d78c1..b106f2cf 100644
--- a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h
+++ b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h
@@ -36,8 +36,7 @@
  public:
   class CameraAppDialog : public chromeos::SystemWebDialogDelegate {
    public:
-    static void ShowIntent(const std::string& queries,
-                           gfx::NativeWindow parent);
+    explicit CameraAppDialog(const std::string& url);
 
     // SystemWebDialogDelegate
     ui::ModalType GetDialogModalType() const override;
@@ -55,7 +54,6 @@
         blink::mojom::MediaStreamType type) override;
 
    private:
-    explicit CameraAppDialog(const std::string& url);
     ~CameraAppDialog() override;
 
     DISALLOW_COPY_AND_ASSIGN(CameraAppDialog);
@@ -67,6 +65,8 @@
   ChromeCameraAppUIDelegate& operator=(const ChromeCameraAppUIDelegate&) =
       delete;
 
+  static void ShowIntent(const std::string& queries, gfx::NativeWindow parent);
+
   // CameraAppUIDelegate
   void SetLaunchDirectory() override;
   void PopulateLoadTimeData(content::WebUIDataSource* source) override;
diff --git a/chrome/browser/engagement/history_aware_site_engagement_service.cc b/chrome/browser/engagement/history_aware_site_engagement_service.cc
new file mode 100644
index 0000000..196fdc9
--- /dev/null
+++ b/chrome/browser/engagement/history_aware_site_engagement_service.cc
@@ -0,0 +1,120 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/history_aware_site_engagement_service.h"
+
+#include "base/time/clock.h"
+#include "base/time/time.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/engagement/site_engagement_score.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "content/public/browser/browser_context.h"
+
+namespace site_engagement {
+
+HistoryAwareSiteEngagementService::HistoryAwareSiteEngagementService(
+    content::BrowserContext* browser_context,
+    history::HistoryService* history_service)
+    : SiteEngagementService(browser_context) {
+  // May be null in tests.
+  if (history_service)
+    history_service_observation_.Observe(history_service);
+}
+
+HistoryAwareSiteEngagementService::~HistoryAwareSiteEngagementService() =
+    default;
+
+void HistoryAwareSiteEngagementService::Shutdown() {
+  history_service_observation_.Reset();
+}
+
+void HistoryAwareSiteEngagementService::OnURLsDeleted(
+    history::HistoryService* history_service,
+    const history::DeletionInfo& deletion_info) {
+  std::multiset<GURL> origins;
+  for (const history::URLRow& row : deletion_info.deleted_rows())
+    origins.insert(row.url().GetOrigin());
+
+  UpdateEngagementScores(origins, deletion_info.is_from_expiration(),
+                         deletion_info.deleted_urls_origin_map());
+}
+
+void HistoryAwareSiteEngagementService::UpdateEngagementScores(
+    const std::multiset<GURL>& deleted_origins,
+    bool expired,
+    const history::OriginCountAndLastVisitMap& remaining_origins) {
+  // The most in-the-past option in the Clear Browsing Dialog aside from "all
+  // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins
+  // where we can't find a valid last visit date.
+  base::Time now = clock().Now();
+  base::Time four_weeks_ago = now - base::TimeDelta::FromDays(28);
+
+  HostContentSettingsMap* settings_map =
+      HostContentSettingsMapFactory::GetForProfile(browser_context());
+
+  for (const auto& origin_to_count : remaining_origins) {
+    GURL origin = origin_to_count.first;
+    // It appears that the history service occasionally sends bad URLs to us.
+    // See crbug.com/612881.
+    if (!origin.is_valid())
+      continue;
+
+    int remaining = origin_to_count.second.first;
+    base::Time last_visit = origin_to_count.second.second;
+    int deleted = deleted_origins.count(origin);
+
+    // Do not update engagement scores if the deletion was an expiry, but the
+    // URL still has entries in history.
+    if ((expired && remaining != 0) || deleted == 0)
+      continue;
+
+    // Remove origins that have no urls left.
+    if (remaining == 0) {
+      settings_map->SetWebsiteSettingDefaultScope(
+          origin, GURL(), ContentSettingsType::SITE_ENGAGEMENT, nullptr);
+      continue;
+    }
+
+    // Remove engagement proportional to the urls expired from the origin's
+    // entire history.
+    double proportion_remaining =
+        static_cast<double>(remaining) / (remaining + deleted);
+    if (last_visit.is_null() || last_visit > now)
+      last_visit = four_weeks_ago;
+
+    // At this point, we are going to proportionally decay the origin's
+    // engagement, and reset its last visit date to the last visit to a URL
+    // under the origin in history. If this new last visit date is long enough
+    // in the past, the next time the origin's engagement is accessed the
+    // automatic decay will kick in - i.e. a double decay will have occurred.
+    // To prevent this, compute the decay that would have taken place since the
+    // new last visit and add it to the engagement at this point. When the
+    // engagement is next accessed, it will decay back to the proportionally
+    // reduced value rather than being decayed once here, and then once again
+    // when it is next accessed.
+    // TODO(703848): Move the proportional decay logic into SiteEngagementScore,
+    // so it can decay raw_score_ directly, without the double-decay issue.
+    SiteEngagementScore engagement_score = CreateEngagementScore(origin);
+
+    double new_score = proportion_remaining * engagement_score.GetTotalScore();
+    int hours_since_engagement = (now - last_visit).InHours();
+    int periods =
+        hours_since_engagement / SiteEngagementScore::GetDecayPeriodInHours();
+    new_score += periods * SiteEngagementScore::GetDecayPoints();
+    new_score *= pow(1.0 / SiteEngagementScore::GetDecayProportion(), periods);
+
+    double score = std::min(SiteEngagementScore::kMaxPoints, new_score);
+    engagement_score.Reset(score, last_visit);
+    if (!engagement_score.last_shortcut_launch_time().is_null() &&
+        engagement_score.last_shortcut_launch_time() > last_visit) {
+      engagement_score.set_last_shortcut_launch_time(last_visit);
+    }
+
+    engagement_score.Commit();
+  }
+
+  SetLastEngagementTime(now);
+}
+
+}  // namespace site_engagement
diff --git a/chrome/browser/engagement/history_aware_site_engagement_service.h b/chrome/browser/engagement/history_aware_site_engagement_service.h
new file mode 100644
index 0000000..28ef6f5
--- /dev/null
+++ b/chrome/browser/engagement/history_aware_site_engagement_service.h
@@ -0,0 +1,56 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENGAGEMENT_HISTORY_AWARE_SITE_ENGAGEMENT_SERVICE_H_
+#define CHROME_BROWSER_ENGAGEMENT_HISTORY_AWARE_SITE_ENGAGEMENT_SERVICE_H_
+
+#include <set>
+
+#include "base/scoped_observation.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/history/core/browser/history_service_observer.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace site_engagement {
+
+// A version of SiteEngagementService that observes changes to (deletions of)
+// history.
+class HistoryAwareSiteEngagementService
+    : public SiteEngagementService,
+      public history::HistoryServiceObserver {
+ public:
+  HistoryAwareSiteEngagementService(content::BrowserContext* browser_context,
+                                    history::HistoryService* history_service);
+  HistoryAwareSiteEngagementService(
+      const HistoryAwareSiteEngagementService& other) = delete;
+  HistoryAwareSiteEngagementService& operator=(
+      const HistoryAwareSiteEngagementService& other) = delete;
+  ~HistoryAwareSiteEngagementService() override;
+
+  // SiteEngagementService:
+  void Shutdown() override;
+
+  // history::HistoryServiceObserver:
+  void OnURLsDeleted(history::HistoryService* history_service,
+                     const history::DeletionInfo& deletion_info) override;
+
+ private:
+  // Updates site engagement scores after some data has been deleted.
+  void UpdateEngagementScores(
+      const std::multiset<GURL>& deleted_url_origins,
+      bool expired,
+      const history::OriginCountAndLastVisitMap& remaining_origin_counts);
+
+  base::ScopedObservation<history::HistoryService,
+                          history::HistoryServiceObserver>
+      history_service_observation_{this};
+};
+
+}  // namespace site_engagement
+
+#endif  // CHROME_BROWSER_ENGAGEMENT_HISTORY_AWARE_SITE_ENGAGEMENT_SERVICE_H_
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
index cf4c6063..11d943b 100644
--- a/chrome/browser/engagement/site_engagement_service.cc
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -22,15 +22,13 @@
 #include "chrome/browser/engagement/site_engagement_metrics.h"
 #include "chrome/browser/engagement/site_engagement_observer.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
-#include "chrome/browser/engagement/site_engagement_service_factory.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/prefs/pref_service.h"
+#include "components/user_prefs/user_prefs.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
@@ -44,11 +42,11 @@
 
 namespace {
 
-const int FOUR_WEEKS_IN_DAYS = 28;
-
 // Global bool to ensure we only update the parameters from variations once.
 bool g_updated_from_variations = false;
 
+SiteEngagementService::ServiceProvider* g_service_provider = nullptr;
+
 // Length of time between metrics logging.
 const int kMetricsIntervalInMinutes = 60;
 
@@ -76,11 +74,11 @@
   return content_settings;
 }
 
-ContentSettingsForOneType GetContentSettingsFromProfile(
-    Profile* profile,
+ContentSettingsForOneType GetContentSettingsFromBrowserContext(
+    content::BrowserContext* browser_context,
     ContentSettingsType type) {
   return GetContentSettingsFromMap(
-      HostContentSettingsMapFactory::GetForProfile(profile), type);
+      HostContentSettingsMapFactory::GetForProfile(browser_context), type);
 }
 
 // Returns the combined list of origins which either have site engagement
@@ -162,8 +160,23 @@
 const char SiteEngagementService::kEngagementParams[] = "SiteEngagement";
 
 // static
-SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
-  return SiteEngagementServiceFactory::GetForProfile(profile);
+SiteEngagementService* SiteEngagementService::Get(
+    content::BrowserContext* context) {
+  return g_service_provider->GetSiteEngagementService(context);
+}
+
+// static
+void SiteEngagementService::SetServiceProvider(ServiceProvider* provider) {
+  DCHECK(provider);
+  DCHECK(!g_service_provider);
+  g_service_provider = provider;
+}
+
+// static
+void SiteEngagementService::ClearServiceProvider(ServiceProvider* provider) {
+  DCHECK(provider);
+  DCHECK_EQ(provider, g_service_provider);
+  g_service_provider = nullptr;
 }
 
 // static
@@ -198,8 +211,8 @@
                            map.get());
 }
 
-SiteEngagementService::SiteEngagementService(Profile* profile)
-    : SiteEngagementService(profile, base::DefaultClock::GetInstance()) {
+SiteEngagementService::SiteEngagementService(content::BrowserContext* context)
+    : browser_context_(context), clock_(base::DefaultClock::GetInstance()) {
   content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
       ->PostTask(FROM_HERE,
                  base::BindOnce(&SiteEngagementService::AfterStartupTask,
@@ -217,13 +230,6 @@
     observer.Observe(nullptr);
 }
 
-void SiteEngagementService::Shutdown() {
-  history::HistoryService* history = HistoryServiceFactory::GetForProfile(
-      profile_, ServiceAccessType::IMPLICIT_ACCESS);
-  if (history)
-    history->RemoveObserver(this);
-}
-
 blink::mojom::EngagementLevel
 SiteEngagementService::GetEngagementLevel(const GURL& url) const {
   if (IsLastEngagementStale())
@@ -239,7 +245,7 @@
 
   return GetAllDetailsImpl(
       browsing_data::TimePeriod::ALL_TIME, clock_,
-      HostContentSettingsMapFactory::GetForProfile(profile_));
+      HostContentSettingsMapFactory::GetForProfile(browser_context_));
 }
 
 std::vector<mojom::SiteEngagementDetails>
@@ -250,7 +256,7 @@
 
   return GetAllDetailsImpl(
       time_period, clock_,
-      HostContentSettingsMapFactory::GetForProfile(profile_));
+      HostContentSettingsMapFactory::GetForProfile(browser_context_));
 }
 
 void SiteEngagementService::HandleNotificationInteraction(const GURL& url) {
@@ -339,8 +345,9 @@
   if (IsLastEngagementStale())
     CleanupEngagementScores(true);
 
-  return GetDetailsImpl(clock_, url,
-                        HostContentSettingsMapFactory::GetForProfile(profile_));
+  return GetDetailsImpl(
+      clock_, url,
+      HostContentSettingsMapFactory::GetForProfile(browser_context_));
 }
 
 double SiteEngagementService::GetTotalEngagementPoints() const {
@@ -369,16 +376,6 @@
 }
 #endif
 
-SiteEngagementService::SiteEngagementService(Profile* profile,
-                                             base::Clock* clock)
-    : profile_(profile), clock_(clock) {
-  // May be null in tests.
-  history::HistoryService* history = HistoryServiceFactory::GetForProfile(
-      profile, ServiceAccessType::IMPLICIT_ACCESS);
-  if (history)
-    history->AddObserver(this);
-}
-
 void SiteEngagementService::AddPoints(const GURL& url, double points) {
   if (points == 0)
     return;
@@ -426,9 +423,9 @@
     last_engagement_time = now;
 
   HostContentSettingsMap* settings_map =
-      HostContentSettingsMapFactory::GetForProfile(profile_);
-  for (const auto& site : GetContentSettingsFromProfile(
-           profile_, ContentSettingsType::SITE_ENGAGEMENT)) {
+      HostContentSettingsMapFactory::GetForProfile(browser_context_);
+  for (const auto& site : GetContentSettingsFromBrowserContext(
+           browser_context_, ContentSettingsType::SITE_ENGAGEMENT)) {
     GURL origin(site.primary_pattern.ToString());
 
     if (origin.is_valid()) {
@@ -481,7 +478,7 @@
 
 void SiteEngagementService::MaybeRecordMetrics() {
   base::Time now = clock_->Now();
-  if (profile_->IsOffTheRecord() ||
+  if (browser_context_->IsOffTheRecord() ||
       (!last_metrics_time_.is_null() &&
        (now - last_metrics_time_).InMinutes() < kMetricsIntervalInMinutes)) {
     return;
@@ -497,11 +494,11 @@
   // with minor data inconsistency but this doesn't really matter for metrics
   // purposes.
   //
-  // The profile and its KeyedServices are normally destroyed before the
+  // The BrowserContext and its KeyedServices are normally destroyed before the
   // ThreadPool shuts down background threads, so the task needs to hold a
   // strong reference to HostContentSettingsMap (which supports outliving the
-  // profile), and needs to avoid using any members of SiteEngagementService
-  // (which does not). See https://crbug.com/900022.
+  // browser context), and needs to avoid using any members of
+  // SiteEngagementService (which does not). See https://crbug.com/900022.
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE,
       {base::TaskPriority::BEST_EFFORT,
@@ -509,7 +506,7 @@
       base::BindOnce(
           &GetAllDetailsInBackground, now,
           base::WrapRefCounted(
-              HostContentSettingsMapFactory::GetForProfile(profile_))),
+              HostContentSettingsMapFactory::GetForProfile(browser_context_))),
       base::BindOnce(&SiteEngagementService::RecordMetrics,
                      weak_factory_.GetWeakPtr()));
 }
@@ -553,19 +550,21 @@
 }
 
 base::Time SiteEngagementService::GetLastEngagementTime() const {
-  if (profile_->IsOffTheRecord())
+  if (browser_context_->IsOffTheRecord())
     return base::Time();
 
   return base::Time::FromInternalValue(
-      profile_->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
+      user_prefs::UserPrefs::Get(browser_context_)
+          ->GetInt64(prefs::kSiteEngagementLastUpdateTime));
 }
 
 void SiteEngagementService::SetLastEngagementTime(
     base::Time last_engagement_time) const {
-  if (profile_->IsOffTheRecord())
+  if (browser_context_->IsOffTheRecord())
     return;
-  profile_->GetPrefs()->SetInt64(prefs::kSiteEngagementLastUpdateTime,
-                                 last_engagement_time.ToInternalValue());
+  user_prefs::UserPrefs::Get(browser_context_)
+      ->SetInt64(prefs::kSiteEngagementLastUpdateTime,
+                 last_engagement_time.ToInternalValue());
 }
 
 base::TimeDelta SiteEngagementService::GetMaxDecayPeriod() const {
@@ -661,32 +660,22 @@
          (now < last_engagement_time);
 }
 
-void SiteEngagementService::OnURLsDeleted(
-    history::HistoryService* history_service,
-    const history::DeletionInfo& deletion_info) {
-  std::multiset<GURL> origins;
-  for (const history::URLRow& row : deletion_info.deleted_rows())
-    origins.insert(row.url().GetOrigin());
-
-  UpdateEngagementScores(origins, deletion_info.is_from_expiration(),
-                         deletion_info.deleted_urls_origin_map());
-}
-
 SiteEngagementScore SiteEngagementService::CreateEngagementScore(
     const GURL& origin) const {
   // If we are in incognito, |settings| will automatically have the data from
   // the original profile migrated in, so all engagement scores in incognito
   // will be initialised to the values from the original profile.
   return CreateEngagementScoreImpl(
-      clock_, origin, HostContentSettingsMapFactory::GetForProfile(profile_));
+      clock_, origin,
+      HostContentSettingsMapFactory::GetForProfile(browser_context_));
 }
 
 int SiteEngagementService::OriginsWithMaxDailyEngagement() const {
   int total_origins = 0;
 
   // We cannot call GetScoreMap as we need the score objects, not raw scores.
-  for (const auto& site : GetContentSettingsFromProfile(
-           profile_, ContentSettingsType::SITE_ENGAGEMENT)) {
+  for (const auto& site : GetContentSettingsFromBrowserContext(
+           browser_context_, ContentSettingsType::SITE_ENGAGEMENT)) {
     GURL origin(site.primary_pattern.ToString());
 
     if (!origin.is_valid())
@@ -699,82 +688,4 @@
   return total_origins;
 }
 
-void SiteEngagementService::UpdateEngagementScores(
-    const std::multiset<GURL>& deleted_origins,
-    bool expired,
-    const history::OriginCountAndLastVisitMap& remaining_origins) {
-  // The most in-the-past option in the Clear Browsing Dialog aside from "all
-  // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins
-  // where we can't find a valid last visit date.
-  base::Time now = clock_->Now();
-  base::Time four_weeks_ago =
-      now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS);
-
-  HostContentSettingsMap* settings_map =
-      HostContentSettingsMapFactory::GetForProfile(profile_);
-
-  for (const auto& origin_to_count : remaining_origins) {
-    GURL origin = origin_to_count.first;
-    // It appears that the history service occasionally sends bad URLs to us.
-    // See crbug.com/612881.
-    if (!origin.is_valid())
-      continue;
-
-    int remaining = origin_to_count.second.first;
-    base::Time last_visit = origin_to_count.second.second;
-    int deleted = deleted_origins.count(origin);
-
-    // Do not update engagement scores if the deletion was an expiry, but the
-    // URL still has entries in history.
-    if ((expired && remaining != 0) || deleted == 0)
-      continue;
-
-    // Remove origins that have no urls left.
-    if (remaining == 0) {
-      settings_map->SetWebsiteSettingDefaultScope(
-          origin, GURL(), ContentSettingsType::SITE_ENGAGEMENT, nullptr);
-      continue;
-    }
-
-    // Remove engagement proportional to the urls expired from the origin's
-    // entire history.
-    double proportion_remaining =
-        static_cast<double>(remaining) / (remaining + deleted);
-    if (last_visit.is_null() || last_visit > now)
-      last_visit = four_weeks_ago;
-
-    // At this point, we are going to proportionally decay the origin's
-    // engagement, and reset its last visit date to the last visit to a URL
-    // under the origin in history. If this new last visit date is long enough
-    // in the past, the next time the origin's engagement is accessed the
-    // automatic decay will kick in - i.e. a double decay will have occurred.
-    // To prevent this, compute the decay that would have taken place since the
-    // new last visit and add it to the engagement at this point. When the
-    // engagement is next accessed, it will decay back to the proportionally
-    // reduced value rather than being decayed once here, and then once again
-    // when it is next accessed.
-    // TODO(703848): Move the proportional decay logic into SiteEngagementScore,
-    // so it can decay raw_score_ directly, without the double-decay issue.
-    SiteEngagementScore engagement_score = CreateEngagementScore(origin);
-
-    double new_score = proportion_remaining * engagement_score.GetTotalScore();
-    int hours_since_engagement = (now - last_visit).InHours();
-    int periods =
-        hours_since_engagement / SiteEngagementScore::GetDecayPeriodInHours();
-    new_score += periods * SiteEngagementScore::GetDecayPoints();
-    new_score *= pow(1.0 / SiteEngagementScore::GetDecayProportion(), periods);
-
-    double score = std::min(SiteEngagementScore::kMaxPoints, new_score);
-    engagement_score.Reset(score, last_visit);
-    if (!engagement_score.last_shortcut_launch_time().is_null() &&
-        engagement_score.last_shortcut_launch_time() > last_visit) {
-      engagement_score.set_last_shortcut_launch_time(last_visit);
-    }
-
-    engagement_score.Commit();
-  }
-
-  SetLastEngagementTime(now);
-}
-
 }  // namespace site_engagement
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h
index 55fd14f..b672b68 100644
--- a/chrome/browser/engagement/site_engagement_service.h
+++ b/chrome/browser/engagement/site_engagement_service.h
@@ -6,7 +6,6 @@
 #define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
 
 #include <memory>
-#include <set>
 #include <vector>
 
 #include "base/gtest_prod_util.h"
@@ -16,7 +15,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
-#include "components/history/core/browser/history_service_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/site_engagement/core/mojom/site_engagement_details.mojom.h"
 #include "third_party/blink/public/mojom/site_engagement/site_engagement.mojom.h"
@@ -31,20 +29,16 @@
 }
 
 namespace content {
+class BrowserContext;
 class WebContents;
 }
 
-namespace history {
-class HistoryService;
-}
-
 namespace web_app {
 class WebAppEngagementBrowserTest;
 }
 
 class GURL;
 class HostContentSettingsMap;
-class Profile;
 
 namespace site_engagement {
 
@@ -81,9 +75,21 @@
 // threads using SiteEngagementService::GetScoreFromSettings, but use of this
 // method is discouraged unless it is not possible to use the UI thread.
 class SiteEngagementService : public KeyedService,
-                              public history::HistoryServiceObserver,
                               public SiteEngagementScoreProvider {
  public:
+  // The provider allows code agnostic to the embedder (e.g. in
+  // //components) to retrieve the SiteEngagementService. It should be set by
+  // each embedder that uses the SiteEngagementService, via SetServiceProvider.
+  class ServiceProvider {
+   public:
+    ~ServiceProvider() = default;
+
+    // Should always return a non null value, creating the service if it does
+    // not exist.
+    virtual SiteEngagementService* GetSiteEngagementService(
+        content::BrowserContext* browser_context) = 0;
+  };
+
   // This is used to back a UMA histogram, so it should be treated as
   // append-only. Any new values should be inserted immediately prior to
   // ENGAGEMENT_LAST and added to SiteEngagementServiceEngagementType in
@@ -110,14 +116,20 @@
   // The name of the site engagement variation field trial.
   static const char kEngagementParams[];
 
-  // Returns the site engagement service attached to this profile. The service
-  // exists in incognito mode; scores will be initialised using the score from
-  // the profile that the incognito session was created from, and will increase
-  // and decrease as usual. Engagement earned or decayed in incognito will not
-  // be persisted or reflected in the original profile.
+  // Sets and clears the service provider. These are separate functions to
+  // enable better checking.
+  static void SetServiceProvider(ServiceProvider* provider);
+  static void ClearServiceProvider(ServiceProvider* provider);
+
+  // Returns the site engagement service attached to this Browser Context. The
+  // service exists in incognito mode; scores will be initialised using the
+  // score from the Browser Context that the incognito session was created from,
+  // and will increase and decrease as usual. Engagement earned or decayed in
+  // incognito will not be persisted or reflected in the original Browser
+  // Context.
   //
   // This method must be called on the UI thread.
-  static SiteEngagementService* Get(Profile* profile);
+  static SiteEngagementService* Get(content::BrowserContext* browser_context);
 
   // Returns the maximum possible amount of engagement that a site can accrue.
   static double GetMaxPoints();
@@ -140,12 +152,9 @@
       base::Time now,
       scoped_refptr<HostContentSettingsMap> map);
 
-  explicit SiteEngagementService(Profile* profile);
+  explicit SiteEngagementService(content::BrowserContext* browser_context);
   ~SiteEngagementService() override;
 
-  // KeyedService support:
-  void Shutdown() override;
-
   // Returns the engagement level of |url|.
   blink::mojom::EngagementLevel GetEngagementLevel(const GURL& url) const;
 
@@ -200,6 +209,16 @@
   // Just forwards calls AddPoints.
   void AddPointsForTesting(const GURL& url, double points);
 
+  void set_clock_for_test(base::Clock* clock) { clock_ = clock; }
+
+ protected:
+  // Retrieves the SiteEngagementScore object for |origin|.
+  SiteEngagementScore CreateEngagementScore(const GURL& origin) const;
+  void SetLastEngagementTime(base::Time last_engagement_time) const;
+
+  content::BrowserContext* browser_context() { return browser_context_; }
+  const base::Clock& clock() { return *clock_; }
+
  private:
   friend class SiteEngagementObserver;
   friend class SiteEngagementServiceTest;
@@ -242,16 +261,10 @@
       std::unique_ptr<SiteEngagementServiceAndroid> android_service);
 #endif
 
-  // Only used in tests.
-  SiteEngagementService(Profile* profile, base::Clock* clock);
-
   // Adds the specified number of points to the given origin, respecting the
   // maximum limits for the day and overall.
   void AddPoints(const GURL& url, double points);
 
-  // Retrieves the SiteEngagementScore object for |origin|.
-  SiteEngagementScore CreateEngagementScore(const GURL& origin) const;
-
   // Runs site engagement maintenance tasks.
   void AfterStartupTask();
 
@@ -278,7 +291,6 @@
 
   // Get and set the last engagement time from prefs.
   base::Time GetLastEngagementTime() const;
-  void SetLastEngagementTime(base::Time last_engagement_time) const;
 
   // Get the maximum decay period and the stale period for last engagement
   // times.
@@ -319,25 +331,15 @@
   // browser for an extended period of time do not have their engagement decay.
   bool IsLastEngagementStale() const;
 
-  // Overridden from history::HistoryServiceObserver:
-  void OnURLsDeleted(history::HistoryService* history_service,
-                     const history::DeletionInfo& deletion_info) override;
-
   // Returns the number of origins with maximum daily and total engagement
   // respectively.
   int OriginsWithMaxDailyEngagement() const;
 
-  // Update site engagement scores after a history deletion.
-  void UpdateEngagementScores(
-      const std::multiset<GURL>& deleted_url_origins,
-      bool expired,
-      const history::OriginCountAndLastVisitMap& remaining_origin_counts);
-
   // Add and remove observers of this service.
   void AddObserver(SiteEngagementObserver* observer);
   void RemoveObserver(SiteEngagementObserver* observer);
 
-  Profile* profile_;
+  content::BrowserContext* browser_context_;
 
   // The clock used to vend times.
   base::Clock* clock_;
diff --git a/chrome/browser/engagement/site_engagement_service_factory.cc b/chrome/browser/engagement/site_engagement_service_factory.cc
index ec4806e..b8ad9d0 100644
--- a/chrome/browser/engagement/site_engagement_service_factory.cc
+++ b/chrome/browser/engagement/site_engagement_service_factory.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/engagement/site_engagement_service_factory.h"
 
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/engagement/history_aware_site_engagement_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
@@ -15,10 +15,10 @@
 
 // static
 SiteEngagementService* SiteEngagementServiceFactory::GetForProfile(
-    Profile* profile) {
+    content::BrowserContext* browser_context) {
   return static_cast<SiteEngagementService*>(
-      GetInstance()->GetServiceForBrowserContext(profile,
-                                                 /*create_service=*/true));
+      GetInstance()->GetServiceForBrowserContext(browser_context,
+                                                 /*create=*/true));
 }
 
 // static
@@ -26,7 +26,7 @@
     Profile* profile) {
   return static_cast<SiteEngagementService*>(
       GetInstance()->GetServiceForBrowserContext(profile,
-                                                 /*create_service=*/false));
+                                                 /*create=*/false));
 }
 
 // static
@@ -40,14 +40,18 @@
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
+  SiteEngagementService::SetServiceProvider(this);
 }
 
 SiteEngagementServiceFactory::~SiteEngagementServiceFactory() {
+  SiteEngagementService::ClearServiceProvider(this);
 }
 
 KeyedService* SiteEngagementServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* profile) const {
-  return new SiteEngagementService(static_cast<Profile*>(profile));
+    content::BrowserContext* context) const {
+  history::HistoryService* history = HistoryServiceFactory::GetForProfile(
+      Profile::FromBrowserContext(context), ServiceAccessType::IMPLICIT_ACCESS);
+  return new HistoryAwareSiteEngagementService(context, history);
 }
 
 content::BrowserContext* SiteEngagementServiceFactory::GetBrowserContextToUse(
@@ -55,4 +59,9 @@
   return chrome::GetBrowserContextOwnInstanceInIncognito(context);
 }
 
+SiteEngagementService* SiteEngagementServiceFactory::GetSiteEngagementService(
+    content::BrowserContext* browser_context) {
+  return GetForProfile(browser_context);
+}
+
 }  // namespace site_engagement
diff --git a/chrome/browser/engagement/site_engagement_service_factory.h b/chrome/browser/engagement/site_engagement_service_factory.h
index e81419a..53d4177 100644
--- a/chrome/browser/engagement/site_engagement_service_factory.h
+++ b/chrome/browser/engagement/site_engagement_service_factory.h
@@ -7,14 +7,13 @@
 
 #include "base/macros.h"
 #include "base/memory/singleton.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 
 class Profile;
 
 namespace site_engagement {
 
-class SiteEngagementService;
-
 // Singleton that owns all SiteEngagementServices and associates them with
 // Profiles. Listens for the Profile's destruction notification and cleans up
 // the associated SiteEngagementService.
@@ -22,13 +21,20 @@
 // The default factory behavior is suitable for this factory as:
 // * the site engagement service should be created lazily
 // * the site engagement service is needed in tests.
-class SiteEngagementServiceFactory : public BrowserContextKeyedServiceFactory {
+class SiteEngagementServiceFactory
+    : public BrowserContextKeyedServiceFactory,
+      public SiteEngagementService::ServiceProvider {
  public:
-  static SiteEngagementService* GetForProfile(Profile* profile);
+  static SiteEngagementService* GetForProfile(
+      content::BrowserContext* browser_context);
   static SiteEngagementService* GetForProfileIfExists(Profile* profile);
 
   static SiteEngagementServiceFactory* GetInstance();
 
+  // SiteEngagementService::ServiceProvider:
+  SiteEngagementService* GetSiteEngagementService(
+      content::BrowserContext* browser_context) override;
+
  private:
   friend struct base::DefaultSingletonTraits<SiteEngagementServiceFactory>;
 
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
index 3b106e5f..1acd79a 100644
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -21,6 +21,7 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/engagement/history_aware_site_engagement_service.h"
 #include "chrome/browser/engagement/site_engagement_helper.h"
 #include "chrome/browser/engagement/site_engagement_metrics.h"
 #include "chrome/browser/engagement/site_engagement_observer.h"
@@ -176,7 +177,8 @@
     // (See KeyedServiceBaseFactory::ServiceIsCreatedWithContext).
     DCHECK(!SiteEngagementServiceFactory::GetForProfileIfExists(profile()));
 
-    service_ = base::WrapUnique(new SiteEngagementService(profile(), &clock_));
+    service_ = std::make_unique<SiteEngagementService>(profile());
+    service_->set_clock_for_test(&clock_);
   }
 
   void TearDown() override {
@@ -1109,6 +1111,10 @@
 }
 
 TEST_F(SiteEngagementServiceTest, CleanupOriginsOnHistoryDeletion) {
+  service_ = std::make_unique<HistoryAwareSiteEngagementService>(
+      profile(), HistoryServiceFactory::GetForProfile(
+                     profile(), ServiceAccessType::IMPLICIT_ACCESS));
+  service_->set_clock_for_test(&clock_);
   // Enable proportional decay to ensure that the undecay that happens to
   // balance out history deletion also accounts for the proportional decay.
   SetParamValue(SiteEngagementScore::DECAY_PROPORTION, 0.5);
@@ -1636,8 +1642,9 @@
   service->AddPoints(url1, 1);
   service->AddPoints(url2, 2);
 
-  auto incognito_service = base::WrapUnique(
-      new SiteEngagementService(profile()->GetPrimaryOTRProfile(), &clock_));
+  auto incognito_service = std::make_unique<SiteEngagementService>(
+      profile()->GetPrimaryOTRProfile());
+  incognito_service->set_clock_for_test(&clock_);
   EXPECT_EQ(1, incognito_service->GetScore(url1));
   EXPECT_EQ(2, incognito_service->GetScore(url2));
   EXPECT_EQ(0, incognito_service->GetScore(url3));
diff --git a/chrome/browser/enterprise/connectors/common.cc b/chrome/browser/enterprise/connectors/common.cc
index c2f43fd..5e78914a 100644
--- a/chrome/browser/enterprise/connectors/common.cc
+++ b/chrome/browser/enterprise/connectors/common.cc
@@ -15,8 +15,10 @@
 AnalysisSettings::~AnalysisSettings() = default;
 
 ReportingSettings::ReportingSettings() = default;
-ReportingSettings::ReportingSettings(GURL url, const std::string& dm_token)
-    : reporting_url(url), dm_token(dm_token) {}
+ReportingSettings::ReportingSettings(GURL url,
+                                     const std::string& dm_token,
+                                     bool per_profile)
+    : reporting_url(url), dm_token(dm_token), per_profile(per_profile) {}
 ReportingSettings::ReportingSettings(ReportingSettings&&) = default;
 ReportingSettings& ReportingSettings::operator=(ReportingSettings&&) = default;
 ReportingSettings::~ReportingSettings() = default;
diff --git a/chrome/browser/enterprise/connectors/common.h b/chrome/browser/enterprise/connectors/common.h
index e0450bf..488b919a 100644
--- a/chrome/browser/enterprise/connectors/common.h
+++ b/chrome/browser/enterprise/connectors/common.h
@@ -66,13 +66,19 @@
 
 struct ReportingSettings {
   ReportingSettings();
-  explicit ReportingSettings(GURL url, const std::string& dm_token);
+  explicit ReportingSettings(GURL url,
+                             const std::string& dm_token,
+                             bool per_profile);
   ReportingSettings(ReportingSettings&&);
   ReportingSettings& operator=(ReportingSettings&&);
   ~ReportingSettings();
 
   GURL reporting_url;
   std::string dm_token;
+
+  // Indicates if the report should be made for the profile, or the browser if
+  // false.
+  bool per_profile = false;
 };
 
 // Returns the pref path corresponding to a connector.
diff --git a/chrome/browser/enterprise/connectors/connectors_service.cc b/chrome/browser/enterprise/connectors/connectors_service.cc
index b4b379d..cfdf737 100644
--- a/chrome/browser/enterprise/connectors/connectors_service.cc
+++ b/chrome/browser/enterprise/connectors/connectors_service.cc
@@ -7,13 +7,20 @@
 
 #include "base/memory/singleton.h"
 #include "base/no_destructor.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/enterprise/connectors/common.h"
 #include "chrome/browser/enterprise/connectors/connectors_manager.h"
 #include "chrome/browser/enterprise/connectors/service_provider_config.h"
+#include "chrome/browser/enterprise/util/affiliation.h"
+#include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/policy/dm_token_utils.h"
 #include "chrome/browser/profiles/profile.h"
+#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "components/enterprise/common/proto/connectors.pb.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/policy/core/common/cloud/dm_token.h"
+#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
+#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
 #include "components/policy/core/common/policy_types.h"
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/browser_context.h"
@@ -23,6 +30,9 @@
 const base::Feature kEnterpriseConnectorsEnabled{
     "EnterpriseConnectorsEnabled", base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kPerProfileConnectorsEnabled{
+    "PerProfileConnectorsEnabled", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const char kServiceProviderConfig[] = R"({
   "version": "1",
   "service_providers" : [
@@ -117,7 +127,7 @@
   if (!ConnectorsEnabled())
     return base::nullopt;
 
-  base::Optional<DmToken> dm_token = GetDmToken(ConnectorPref(connector));
+  base::Optional<DmToken> dm_token = GetDmToken(ConnectorScopePref(connector));
   if (!dm_token.has_value())
     return base::nullopt;
 
@@ -125,6 +135,8 @@
       connectors_manager_->GetReportingSettings(connector);
   if (settings.has_value()) {
     settings.value().dm_token = dm_token.value().value;
+    settings.value().per_profile =
+        dm_token.value().scope == policy::POLICY_SCOPE_USER;
   }
 
   return settings;
@@ -136,7 +148,7 @@
   if (!ConnectorsEnabled())
     return base::nullopt;
 
-  base::Optional<DmToken> dm_token = GetDmToken(ConnectorPref(connector));
+  base::Optional<DmToken> dm_token = GetDmToken(ConnectorScopePref(connector));
   if (!dm_token.has_value())
     return base::nullopt;
 
@@ -183,10 +195,20 @@
 ConnectorsService::DmToken::~DmToken() = default;
 
 base::Optional<ConnectorsService::DmToken> ConnectorsService::GetDmToken(
-    const char* pref) {
-  // TODO(crbug.com/1148789): Add code to check the scope of |pref| and handle
-  // the "user" case.
+    const char* scope_pref) const {
+#if defined(OS_CHROMEOS)
+  // On CrOS, the device must be affiliated to use the DM token for
+  // scanning/reporting so we always use the browser DM token.
+  return GetBrowserDmToken();
+#else
+  return GetPolicyScope(scope_pref) == policy::POLICY_SCOPE_USER
+             ? GetProfileDmToken()
+             : GetBrowserDmToken();
+#endif
+}
 
+base::Optional<ConnectorsService::DmToken>
+ConnectorsService::GetBrowserDmToken() const {
   policy::DMToken dm_token =
       policy::GetDMToken(Profile::FromBrowserContext(context_));
 
@@ -196,6 +218,60 @@
   return DmToken(dm_token.value(), policy::POLICY_SCOPE_MACHINE);
 }
 
+#if !defined(OS_CHROMEOS)
+base::Optional<ConnectorsService::DmToken>
+ConnectorsService::GetProfileDmToken() const {
+  if (!base::FeatureList::IsEnabled(kPerProfileConnectorsEnabled))
+    return base::nullopt;
+
+  if (!CanUseProfileDmToken())
+    return base::nullopt;
+
+  policy::UserCloudPolicyManager* policy_manager =
+      Profile::FromBrowserContext(context_)->GetUserCloudPolicyManager();
+  if (!policy_manager || !policy_manager->IsClientRegistered())
+    return base::nullopt;
+
+  return DmToken(policy_manager->core()->client()->dm_token(),
+                 policy::POLICY_SCOPE_USER);
+}
+
+bool ConnectorsService::CanUseProfileDmToken() const {
+  // If the browser isn't managed by CBCM, then the profile DM token can be
+  // used.
+  if (!policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().is_valid())
+    return true;
+
+  policy::UserCloudPolicyManager* profile_policy_manager =
+      Profile::FromBrowserContext(context_)->GetUserCloudPolicyManager();
+  policy::MachineLevelUserCloudPolicyManager* browser_policy_manager =
+      g_browser_process->browser_policy_connector()
+          ->machine_level_user_cloud_policy_manager();
+
+  if (!profile_policy_manager || !browser_policy_manager ||
+      !profile_policy_manager->IsClientRegistered() ||
+      !browser_policy_manager->IsClientRegistered()) {
+    return false;
+  }
+
+  auto* profile_policy = profile_policy_manager->core()->store()->policy();
+  auto* browser_policy = browser_policy_manager->core()->store()->policy();
+
+  if (!profile_policy || !browser_policy)
+    return false;
+
+  return chrome::enterprise_util::IsProfileAffiliated(*profile_policy,
+                                                      *browser_policy);
+}
+#endif  // !defined(OS_CHROMEOS)
+
+policy::PolicyScope ConnectorsService::GetPolicyScope(
+    const char* scope_pref) const {
+  return static_cast<policy::PolicyScope>(
+      Profile::FromBrowserContext(context_)->GetPrefs()->GetInteger(
+          scope_pref));
+}
+
 bool ConnectorsService::ConnectorsEnabled() const {
   if (!base::FeatureList::IsEnabled(kEnterpriseConnectorsEnabled))
     return false;
diff --git a/chrome/browser/enterprise/connectors/connectors_service.h b/chrome/browser/enterprise/connectors/connectors_service.h
index 905d86c..47f4ccd 100644
--- a/chrome/browser/enterprise/connectors/connectors_service.h
+++ b/chrome/browser/enterprise/connectors/connectors_service.h
@@ -25,6 +25,9 @@
 // ConnectorsManager.
 extern const base::Feature kEnterpriseConnectorsEnabled;
 
+// Controls whether per-profile Enterprise Connector policies are applied.
+extern const base::Feature kPerProfileConnectorsEnabled;
+
 // For the moment, service provider configurations are static and only support
 // google endpoints.  Therefore the configuration is placed here directly.
 // Once the configuration becomes more dynamic this static string will be
@@ -71,8 +74,26 @@
     // policy used to get a DM token.
     policy::PolicyScope scope;
   };
-  base::Optional<DmToken> GetDmToken(const char* pref);
 
+  // Returns the DM token to use with the given |scope_pref|. That pref should
+  // contain either POLICY_SCOPE_MACHINE or POLICY_SCOPE_USER.
+  base::Optional<DmToken> GetDmToken(const char* scope_pref) const;
+  base::Optional<DmToken> GetBrowserDmToken() const;
+#if !defined(OS_CHROMEOS)
+  base::Optional<DmToken> GetProfileDmToken() const;
+
+  // Returns true if the browser isn't managed by CBCM, otherwise this checks if
+  // the affiliations IDs from the profile and browser policy fetching responses
+  // indicate that the same customer manages both.
+  bool CanUseProfileDmToken() const;
+#endif
+
+  // Returns the policy::PolicyScope stored in the given |scope_pref|.
+  policy::PolicyScope GetPolicyScope(const char* scope_pref) const;
+
+  // Returns whether Connectors are enabled at all. This can be false if:
+  // - The kEnterpriseConnectorsEnabled feature is disabled
+  // - The profile is incognito
   bool ConnectorsEnabled() const;
 
   content::BrowserContext* context_;
diff --git a/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
new file mode 100644
index 0000000..f372ad990
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
@@ -0,0 +1,326 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/connectors_service.h"
+
+#include <memory>
+
+#include "base/json/json_reader.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/enterprise/connectors/common.h"
+#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
+#include "chrome/browser/policy/chrome_browser_policy_connector.h"
+#include "chrome/browser/policy/dm_token_utils.h"
+#include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h"
+#include "chrome/browser/ui/browser.h"
+#include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
+#include "components/enterprise/browser/enterprise_switches.h"
+#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
+#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
+#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
+#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
+#include "components/policy/core/common/policy_switches.h"
+#include "content/public/test/browser_test.h"
+
+namespace enterprise_connectors {
+
+namespace {
+
+constexpr char kNormalAnalysisSettingsPref[] = R"([
+  {
+    "service_provider": "google",
+    "enable": [
+      {"url_list": ["*"], "tags": ["dlp", "malware"]}
+    ]
+  }
+])";
+
+constexpr char kNormalReportingSettingsPref[] = R"([
+  {
+    "service_provider": "google"
+  }
+])";
+
+#if !defined(OS_CHROMEOS)
+constexpr char kFakeProfileDMToken[] = "fake-profile-dm-token";
+constexpr char kFakeEnrollmentToken[] = "fake-enrollment-token";
+constexpr char kFakeBrowserClientId[] = "fake-browser-client-id";
+constexpr char kAffiliationId1[] = "affiliation-id-1";
+constexpr char kAffiliationId2[] = "affiliation-id-2";
+#endif
+
+constexpr char kFakeBrowserDMToken[] = "fake-browser-dm-token";
+constexpr char kTestUrl[] = "https://foo.com";
+
+}  // namespace
+
+// Profile DM token tests
+// These tests validate that ConnectorsService obtains the correct DM token on
+// each GetAnalysisSettings/GetReportingSettings call. There are 3 mains cases
+// to validate here:
+//
+// - Affiliated: The profile and browser are managed by the same customer. In
+// this case, it is OK to get the profile DM token and apply Connector policies.
+// - Unaffiliated: The profile and browser are managed by different customers.
+// In this case, no profile settings should be returned.
+// - Unmanaged: The profile is managed by a customer while the browser is
+// unmanaged. In this case, it is OK to get the profile DM token and apply
+// Connector policies.
+//
+// The exception to the above rules is CrOS. Even when the policies are applied
+// at a user scope, only the browser DM token should be returned.
+
+enum class ManagementStatus { AFFILIATED, UNAFFILIATED, UNMANAGED };
+
+class ConnectorsServiceProfileBrowserTest
+    : public safe_browsing::DeepScanningBrowserTestBase {
+ public:
+  explicit ConnectorsServiceProfileBrowserTest(
+      ManagementStatus management_status)
+      : management_status_(management_status) {
+    if (management_status_ != ManagementStatus::UNMANAGED) {
+#if defined(OS_CHROMEOS)
+      policy::SetDMTokenForTesting(
+          policy::DMToken::CreateValidTokenForTesting(kFakeBrowserDMToken));
+#else
+      browser_dm_token_storage_ =
+          std::make_unique<policy::FakeBrowserDMTokenStorage>();
+      browser_dm_token_storage_->SetEnrollmentToken(kFakeEnrollmentToken);
+      browser_dm_token_storage_->SetClientId(kFakeBrowserClientId);
+      browser_dm_token_storage_->EnableStorage(true);
+      browser_dm_token_storage_->SetDMToken(kFakeBrowserDMToken);
+      policy::BrowserDMTokenStorage::SetForTesting(
+          browser_dm_token_storage_.get());
+#endif
+    }
+
+    // Set the required features for the per-profile feature to work.
+    scoped_feature_list_.Reset();
+    scoped_feature_list_.InitWithFeatures(
+        {kEnterpriseConnectorsEnabled, kPerProfileConnectorsEnabled}, {});
+  }
+
+#if !defined(OS_CHROMEOS)
+  void SetUpOnMainThread() override {
+    safe_browsing::DeepScanningBrowserTestBase::SetUpOnMainThread();
+
+    auto client = std::make_unique<policy::MockCloudPolicyClient>();
+    client->SetDMToken(kFakeProfileDMToken);
+    browser()->profile()->GetUserCloudPolicyManager()->Connect(
+        g_browser_process->local_state(), std::move(client));
+
+    // Set profile/browser affiliation IDs.
+    auto* profile_policy_manager =
+        browser()->profile()->GetUserCloudPolicyManager();
+    auto* mock_profile_store = static_cast<policy::MockCloudPolicyStore*>(
+        profile_policy_manager->core()->store());
+    mock_profile_store->policy_ =
+        std::make_unique<enterprise_management::PolicyData>();
+    mock_profile_store->policy_->add_user_affiliation_ids(kAffiliationId1);
+
+    if (management_status_ != ManagementStatus::UNMANAGED) {
+      auto* browser_policy_manager =
+          g_browser_process->browser_policy_connector()
+              ->machine_level_user_cloud_policy_manager();
+      auto* mock_browser_store = static_cast<policy::MockCloudPolicyStore*>(
+          browser_policy_manager->core()->store());
+      mock_browser_store->policy_ =
+          std::make_unique<enterprise_management::PolicyData>();
+      mock_browser_store->policy_->add_device_affiliation_ids(
+          management_status() == ManagementStatus::AFFILIATED
+              ? kAffiliationId1
+              : kAffiliationId2);
+    }
+  }
+
+#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
+    command_line->AppendSwitch(::switches::kEnableChromeBrowserCloudManagement);
+  }
+#endif
+
+#endif  // !defined(OS_CHROMEOS)
+
+  void SetPrefs(const char* pref,
+                const char* scope_pref,
+                const char* pref_value) {
+    browser()->profile()->GetPrefs()->Set(pref,
+                                          *base::JSONReader::Read(pref_value));
+    browser()->profile()->GetPrefs()->SetInteger(scope_pref,
+                                                 policy::POLICY_SCOPE_USER);
+  }
+
+  ManagementStatus management_status() { return management_status_; }
+
+ protected:
+  std::unique_ptr<policy::FakeBrowserDMTokenStorage> browser_dm_token_storage_;
+  ManagementStatus management_status_;
+};
+
+class ConnectorsServiceReportingProfileBrowserTest
+    : public ConnectorsServiceProfileBrowserTest,
+      public testing::WithParamInterface<
+          std::tuple<ReportingConnector, ManagementStatus>> {
+ public:
+  ConnectorsServiceReportingProfileBrowserTest()
+      : ConnectorsServiceProfileBrowserTest(std::get<1>(GetParam())) {}
+  ReportingConnector connector() { return std::get<0>(GetParam()); }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ConnectorsServiceReportingProfileBrowserTest,
+    testing::Combine(testing::Values(ReportingConnector::SECURITY_EVENT),
+                     testing::Values(ManagementStatus::AFFILIATED,
+                                     ManagementStatus::UNAFFILIATED,
+                                     ManagementStatus::UNMANAGED)));
+
+IN_PROC_BROWSER_TEST_P(ConnectorsServiceReportingProfileBrowserTest, Test) {
+  SetPrefs(ConnectorPref(connector()), ConnectorScopePref(connector()),
+           kNormalReportingSettingsPref);
+
+  auto settings =
+      ConnectorsServiceFactory::GetForBrowserContext(browser()->profile())
+          ->GetReportingSettings(connector());
+#if defined(OS_CHROMEOS)
+  if (management_status() == ManagementStatus::UNMANAGED) {
+    ASSERT_FALSE(settings.has_value());
+  } else {
+    ASSERT_TRUE(settings.has_value());
+    ASSERT_FALSE(settings.value().per_profile);
+    ASSERT_EQ(kFakeBrowserDMToken, settings.value().dm_token);
+  }
+#else
+  switch (management_status()) {
+    case ManagementStatus::AFFILIATED:
+      EXPECT_TRUE(settings.has_value());
+      ASSERT_EQ(kFakeProfileDMToken, settings.value().dm_token);
+      ASSERT_TRUE(settings.value().per_profile);
+      break;
+    case ManagementStatus::UNAFFILIATED:
+      EXPECT_FALSE(settings.has_value());
+      break;
+    case ManagementStatus::UNMANAGED:
+      EXPECT_TRUE(settings.has_value());
+      ASSERT_EQ(kFakeProfileDMToken, settings.value().dm_token);
+      ASSERT_TRUE(settings.value().per_profile);
+      break;
+  }
+#endif
+}
+
+class ConnectorsServiceAnalysisProfileBrowserTest
+    : public ConnectorsServiceProfileBrowserTest,
+      public testing::WithParamInterface<
+          std::tuple<AnalysisConnector, ManagementStatus>> {
+ public:
+  ConnectorsServiceAnalysisProfileBrowserTest()
+      : ConnectorsServiceProfileBrowserTest(std::get<1>(GetParam())) {}
+  AnalysisConnector connector() { return std::get<0>(GetParam()); }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ConnectorsServiceAnalysisProfileBrowserTest,
+    testing::Combine(
+        testing::Values(FILE_ATTACHED, FILE_DOWNLOADED, BULK_DATA_ENTRY),
+        testing::Values(ManagementStatus::AFFILIATED,
+                        ManagementStatus::UNAFFILIATED,
+                        ManagementStatus::UNMANAGED)));
+
+IN_PROC_BROWSER_TEST_P(ConnectorsServiceAnalysisProfileBrowserTest, Test) {
+  SetPrefs(ConnectorPref(connector()), ConnectorScopePref(connector()),
+           kNormalAnalysisSettingsPref);
+  auto settings =
+      ConnectorsServiceFactory::GetForBrowserContext(browser()->profile())
+          ->GetAnalysisSettings(GURL(kTestUrl), connector());
+
+#if defined(OS_CHROMEOS)
+  if (management_status() == ManagementStatus::UNMANAGED) {
+    ASSERT_FALSE(settings.has_value());
+  } else {
+    ASSERT_TRUE(settings.has_value());
+    ASSERT_EQ(kFakeBrowserDMToken, settings.value().dm_token);
+  }
+#else
+  switch (management_status()) {
+    case ManagementStatus::AFFILIATED:
+      EXPECT_TRUE(settings.has_value());
+      ASSERT_EQ(kFakeProfileDMToken, settings.value().dm_token);
+      break;
+    case ManagementStatus::UNAFFILIATED:
+      EXPECT_FALSE(settings.has_value());
+      break;
+    case ManagementStatus::UNMANAGED:
+      EXPECT_TRUE(settings.has_value());
+      ASSERT_EQ(kFakeProfileDMToken, settings.value().dm_token);
+      break;
+  }
+#endif
+}
+
+// This test validates that no settings are obtained when
+// kPerProfileConnectorsEnabled is disabled. CrOS is unaffected as it only gets
+// the browser token if it is present.
+class ConnectorsServiceNoProfileFeatureBrowserTest
+    : public ConnectorsServiceProfileBrowserTest,
+      public testing::WithParamInterface<ManagementStatus> {
+ public:
+  ConnectorsServiceNoProfileFeatureBrowserTest()
+      : ConnectorsServiceProfileBrowserTest(GetParam()) {
+    scoped_feature_list_.Reset();
+    scoped_feature_list_.InitWithFeatures({kEnterpriseConnectorsEnabled},
+                                          {kPerProfileConnectorsEnabled});
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+                         ConnectorsServiceNoProfileFeatureBrowserTest,
+                         testing::Values(ManagementStatus::AFFILIATED,
+                                         ManagementStatus::UNAFFILIATED,
+                                         ManagementStatus::UNMANAGED));
+
+IN_PROC_BROWSER_TEST_P(ConnectorsServiceNoProfileFeatureBrowserTest, Test) {
+  for (auto connector : {FILE_ATTACHED, FILE_DOWNLOADED, BULK_DATA_ENTRY}) {
+    SetPrefs(ConnectorPref(connector), ConnectorScopePref(connector),
+             kNormalAnalysisSettingsPref);
+  }
+  SetPrefs(ConnectorPref(ReportingConnector::SECURITY_EVENT),
+           ConnectorScopePref(ReportingConnector::SECURITY_EVENT),
+           kNormalReportingSettingsPref);
+
+  for (auto connector : {FILE_ATTACHED, FILE_DOWNLOADED, BULK_DATA_ENTRY}) {
+    auto settings =
+        ConnectorsServiceFactory::GetForBrowserContext(browser()->profile())
+            ->GetAnalysisSettings(GURL(kTestUrl), connector);
+#if defined(OS_CHROMEOS)
+    if (management_status() == ManagementStatus::UNMANAGED) {
+      ASSERT_FALSE(settings.has_value());
+    } else {
+      ASSERT_TRUE(settings.has_value());
+      ASSERT_EQ(kFakeBrowserDMToken, settings.value().dm_token);
+    }
+#else
+    EXPECT_FALSE(settings.has_value());
+#endif
+  }
+
+  auto settings =
+      ConnectorsServiceFactory::GetForBrowserContext(browser()->profile())
+          ->GetReportingSettings(ReportingConnector::SECURITY_EVENT);
+#if defined(OS_CHROMEOS)
+  if (management_status() == ManagementStatus::UNMANAGED) {
+    ASSERT_FALSE(settings.has_value());
+  } else {
+    ASSERT_TRUE(settings.has_value());
+    ASSERT_EQ(kFakeBrowserDMToken, settings.value().dm_token);
+    ASSERT_FALSE(settings.value().per_profile);
+  }
+#else
+  EXPECT_FALSE(settings.has_value());
+#endif
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/connectors_service_unittest.cc b/chrome/browser/enterprise/connectors/connectors_service_unittest.cc
index 95599dc..ce205407 100644
--- a/chrome/browser/enterprise/connectors/connectors_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/connectors_service_unittest.cc
@@ -11,6 +11,7 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/enterprise/common/proto/connectors.pb.h"
+#include "components/policy/core/common/policy_types.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -130,6 +131,8 @@
 
   const char* pref() const { return ConnectorPref(connector()); }
 
+  const char* scope_pref() const { return ConnectorScopePref(connector()); }
+
   const char* pref_value() const {
     switch (policy_value()) {
       case 1:
@@ -155,8 +158,11 @@
 };
 
 TEST_P(ConnectorsServiceReportingFeatureTest, Test) {
-  if (policy_value() != 0)
+  if (policy_value() != 0) {
     profile_->GetPrefs()->Set(pref(), *base::JSONReader::Read(pref_value()));
+    profile_->GetPrefs()->SetInteger(scope_pref(),
+                                     policy::POLICY_SCOPE_MACHINE);
+  }
 
   auto settings = ConnectorsServiceFactory::GetForBrowserContext(profile_)
                       ->GetReportingSettings(connector());
diff --git a/chrome/browser/enterprise/util/affiliation.cc b/chrome/browser/enterprise/util/affiliation.cc
new file mode 100644
index 0000000..506d164a
--- /dev/null
+++ b/chrome/browser/enterprise/util/affiliation.cc
@@ -0,0 +1,26 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/util/affiliation.h"
+#include <set>
+
+namespace chrome {
+namespace enterprise_util {
+
+bool IsProfileAffiliated(
+    const enterprise_management::PolicyData& profile_policy,
+    const enterprise_management::PolicyData& browser_policy) {
+  std::set<std::string> profile_affiliation_ids;
+  profile_affiliation_ids.insert(profile_policy.user_affiliation_ids().begin(),
+                                 profile_policy.user_affiliation_ids().end());
+  for (const std::string& browser_affiliation_id :
+       browser_policy.device_affiliation_ids()) {
+    if (profile_affiliation_ids.count(browser_affiliation_id))
+      return true;
+  }
+  return false;
+}
+
+}  // namespace enterprise_util
+}  // namespace chrome
diff --git a/chrome/browser/enterprise/util/affiliation.h b/chrome/browser/enterprise/util/affiliation.h
new file mode 100644
index 0000000..55de0787
--- /dev/null
+++ b/chrome/browser/enterprise/util/affiliation.h
@@ -0,0 +1,24 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_UTIL_AFFILIATION_H_
+#define CHROME_BROWSER_ENTERPRISE_UTIL_AFFILIATION_H_
+
+#include "device_management_backend.pb.h"
+
+namespace chrome {
+namespace enterprise_util {
+
+// Returns true if the profile and browser are managed by the same customer
+// (affiliated). This is determined by comparing affiliation IDs obtained in the
+// policy fetching response. If either policies has no affiliation IDs, this
+// function returns false.
+bool IsProfileAffiliated(
+    const enterprise_management::PolicyData& profile_policy,
+    const enterprise_management::PolicyData& browser_policy);
+
+}  // namespace enterprise_util
+}  // namespace chrome
+
+#endif  // CHROME_BROWSER_ENTERPRISE_UTIL_AFFILIATION_H_
diff --git a/chrome/browser/enterprise/util/affiliation_unittest.cc b/chrome/browser/enterprise/util/affiliation_unittest.cc
new file mode 100644
index 0000000..5ff9096
--- /dev/null
+++ b/chrome/browser/enterprise/util/affiliation_unittest.cc
@@ -0,0 +1,52 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/util/affiliation.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome {
+namespace enterprise_util {
+
+namespace {
+const char kAffiliationID1[] = "id1";
+const char kAffiliationID2[] = "id2";
+}  // namespace
+
+TEST(BrowserAffiliationTest, Affiliated) {
+  enterprise_management::PolicyData profile_policy;
+  profile_policy.add_user_affiliation_ids(kAffiliationID1);
+  enterprise_management::PolicyData browser_policy;
+  browser_policy.add_device_affiliation_ids(kAffiliationID1);
+
+  EXPECT_TRUE(IsProfileAffiliated(profile_policy, browser_policy));
+}
+
+TEST(BrowserAffiliationTest, Unaffiliated) {
+  enterprise_management::PolicyData profile_policy;
+  profile_policy.add_user_affiliation_ids(kAffiliationID1);
+  enterprise_management::PolicyData browser_policy;
+  browser_policy.add_device_affiliation_ids(kAffiliationID2);
+
+  EXPECT_FALSE(IsProfileAffiliated(profile_policy, browser_policy));
+}
+
+TEST(BrowserAffiliationTest, BrowserPolicyEmpty) {
+  enterprise_management::PolicyData profile_policy;
+  profile_policy.add_user_affiliation_ids(kAffiliationID1);
+  enterprise_management::PolicyData browser_policy;
+
+  EXPECT_FALSE(IsProfileAffiliated(profile_policy, browser_policy));
+}
+
+TEST(BrowserAffiliationTest, ProfilePolicyEmpty) {
+  enterprise_management::PolicyData profile_policy;
+  enterprise_management::PolicyData browser_policy;
+  browser_policy.add_device_affiliation_ids(kAffiliationID2);
+
+  EXPECT_FALSE(IsProfileAffiliated(profile_policy, browser_policy));
+}
+
+}  // namespace enterprise_util
+}  // namespace chrome
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
index 812097d..4c3a518 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -185,7 +185,7 @@
 
   // TODO(dewittj): Handle HiDPI images with more than one scale factor
   // representation.
-  gfx::ImageSkia skia(gfx::ImageSkiaRep(bitmap, 1.0f));
+  gfx::ImageSkia skia = gfx::ImageSkia::CreateFromBitmap(bitmap, 1.0f);
   *return_image = gfx::Image(skia);
   return true;
 }
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index cb636a01..736a2ef 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -567,8 +567,6 @@
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[chromeos::assistant::prefs::kAssistantNotificationEnabled] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
-  (*s_allowlist)[chromeos::assistant::prefs::kAssistantQuickAnswersEnabled] =
-      settings_api::PrefType::PREF_TYPE_BOOLEAN;
 
   // Misc.
   (*s_allowlist)[::prefs::kUse24HourClock] =
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index a278de6..de35bbc7 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2363,11 +2363,6 @@
     "expiry_milestone": 90
   },
   {
-    "name": "enable-usbguard",
-    "owners": [ "allenwebb", "mnissler", "jorgelo" ],
-    "expiry_milestone": 84
-  },
-  {
     "name": "enable-use-aaudio-driver",
     "owners": [ "tguilbert" ],
     "expiry_milestone": 88
@@ -4587,11 +4582,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "stop-non-timers-in-background",
-    "owners": [ "fdoray" ],
-    "expiry_milestone": 75
-  },
-  {
     "name": "storage-access-api",
     "owners": [ "brandm@microsoft.com" ],
     "expiry_milestone": 90
@@ -4990,11 +4980,6 @@
     "expiry_milestone": 90
   },
   {
-    "name": "web-contents-occlusion",
-    "owners": [ "davidbienvenu", "fdoray" ],
-    "expiry_milestone": 84
-  },
-  {
     "name": "web-feed",
     "owners": [ "//chrome/android/feed/OWNERS", "feed@chromium.org" ],
     "expiry_milestone": 99
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index d131528..3cdbede 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2247,12 +2247,6 @@
     "Stop scheduler task queues, in the background, "
     " after a grace period.";
 
-const char kStopNonTimersInBackgroundName[] =
-    "Stop non-timer task queues background";
-const char kStopNonTimersInBackgroundDescription[] =
-    "Stop non-timer task queues, in the background, "
-    "after a grace period.";
-
 const char kStorageAccessAPIName[] = "Storage Access API";
 const char kStorageAccessAPIDescription[] =
     "Enables the Storage Access API, allowing websites to request storage "
@@ -4682,12 +4676,6 @@
     "Enable unified media view to browse recently-modified media files from"
     " local disk, Google Drive, and Android.";
 
-const char kUsbguardName[] = "Block new USB devices at the lock screen.";
-const char kUsbguardDescription[] =
-    "Prevents newly connected USB devices from operating at the lock screen"
-    " until Chrome OS is unlocked to protect against malicious USB devices."
-    " Already connected USB devices will continue to function.";
-
 const char kVaapiJpegImageDecodeAccelerationName[] =
     "VA-API JPEG decode acceleration for images";
 const char kVaapiJpegImageDecodeAccelerationDescription[] =
@@ -4832,15 +4820,6 @@
 #endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
-#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-
-const char kWebContentsOcclusionName[] = "Enable occlusion of web contents";
-const char kWebContentsOcclusionDescription[] =
-    "If enabled, web contents will behave as hidden when it is occluded by "
-    "other windows.";
-
-#endif  // defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
 #if BUILDFLAG(USE_TCMALLOC)
 const char kDynamicTcmallocName[] = "Dynamic Tcmalloc Tuning";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 9f687b7..fc408ce6 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1301,9 +1301,6 @@
 extern const char kStopInBackgroundName[];
 extern const char kStopInBackgroundDescription[];
 
-extern const char kStopNonTimersInBackgroundName[];
-extern const char kStopNonTimersInBackgroundDescription[];
-
 extern const char kStoragePressureEventName[];
 extern const char kStoragePressureEventDescription[];
 
@@ -2730,9 +2727,6 @@
 extern const char kUnifiedMediaViewName[];
 extern const char kUnifiedMediaViewDescription[];
 
-extern const char kUsbguardName[];
-extern const char kUsbguardDescription[];
-
 extern const char kUseFakeDeviceForMediaStreamName[];
 extern const char kUseFakeDeviceForMediaStreamDescription[];
 
@@ -2822,13 +2816,6 @@
 #endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
-#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-
-extern const char kWebContentsOcclusionName[];
-extern const char kWebContentsOcclusionDescription[];
-
-#endif  // defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
 #if BUILDFLAG(USE_TCMALLOC)
 extern const char kDynamicTcmallocName[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index ff34a8c0..741de7bc 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -164,6 +164,7 @@
     &kContextualSearchDefinitions,
     &kContextualSearchLegacyHttpPolicy,
     &kContextualSearchLiteralSearchTap,
+    &kContextualSearchLongpressPanelHelp,
     &kContextualSearchLongpressResolve,
     &kContextualSearchMlTapSuppression,
     &kContextualSearchSecondTap,
@@ -455,6 +456,9 @@
 const base::Feature kContextualSearchLiteralSearchTap{
     "ContextualSearchLiteralSearchTap", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kContextualSearchLongpressPanelHelp{
+    "ContextualSearchLongpressPanelHelp", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kContextualSearchLongpressResolve{
     "ContextualSearchLongpressResolve", base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index bff9f36..14f056a7 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -60,6 +60,7 @@
 extern const base::Feature kContextualSearchDefinitions;
 extern const base::Feature kContextualSearchLegacyHttpPolicy;
 extern const base::Feature kContextualSearchLiteralSearchTap;
+extern const base::Feature kContextualSearchLongpressPanelHelp;
 extern const base::Feature kContextualSearchLongpressResolve;
 extern const base::Feature kContextualSearchMlTapSuppression;
 extern const base::Feature kContextualSearchSecondTap;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 4227f5e..b83459d 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -279,6 +279,8 @@
             "ContextualSearchLiteralSearchTap";
     public static final String CONTEXTUAL_SEARCH_ML_TAP_SUPPRESSION =
             "ContextualSearchMlTapSuppression";
+    public static final String CONTEXTUAL_SEARCH_LONGPRESS_PANEL_HELP =
+            "ContextualSearchLongpressPanelHelp";
     public static final String CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE =
             "ContextualSearchLongpressResolve";
     public static final String CONTEXTUAL_SEARCH_SECOND_TAP = "ContextualSearchSecondTap";
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
index 0db42f9..40fb208 100644
--- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
+++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
@@ -1338,8 +1338,9 @@
   SnapshotRequestInfo request_info(
       current_snapshot_request_info_->file_id,
       current_snapshot_request_info_->snapshot_file_path,
-      base::Bind(&MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile,
-                 weak_ptr_factory_.GetWeakPtr()),
+      base::BindRepeating(
+          &MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile,
+          weak_ptr_factory_.GetWeakPtr()),
       base::BindRepeating(
           &MTPDeviceDelegateImplLinux::OnWriteDataIntoSnapshotFileError,
           weak_ptr_factory_.GetWeakPtr()));
@@ -1677,7 +1678,7 @@
 
   CreateSnapshotFile(
       source_file_path, temporary_file_path,
-      base::Bind(
+      base::BindRepeating(
           &MTPDeviceDelegateImplLinux::OnDidCreateSnapshotFileOfCopyFileLocal,
           weak_ptr_factory_.GetWeakPtr(), device_file_path, progress_callback,
           success_callback, error_callback),
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
index 732583f..14ecc30f 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
@@ -222,9 +222,9 @@
   delegate->CreateSnapshotFile(
       url.path(),  // device file path
       snapshot_file_path,
-      base::Bind(&OnDidCreateSnapshotFile, copyable_callback,
-                 base::RetainedRef(context->task_runner()),
-                 validate_media_files),
+      base::BindRepeating(&OnDidCreateSnapshotFile, copyable_callback,
+                          base::RetainedRef(context->task_runner()),
+                          validate_media_files),
       base::BindRepeating(&OnCreateSnapshotFileError, copyable_callback));
 }
 
diff --git a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
index 6e85a27..bd783ec 100644
--- a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
+++ b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
@@ -46,9 +46,12 @@
   typedef base::RepeatingCallback<void(base::File::Error error)> ErrorCallback;
 
   // A callback to be called when CreateSnapshotFile method call succeeds.
-  typedef base::Callback<
-      void(const base::File::Info& file_info,
-           const base::FilePath& local_path)> CreateSnapshotFileSuccessCallback;
+  // TODO: consider make this a OnceCallback. Right now it is repeating because
+  // it is used in SnapshotRequestInfo, which is owned by SnapshotFileDetails,
+  // and SnapshotFileDetails needs const access to SnapshotRequestInfo.
+  typedef base::RepeatingCallback<void(const base::File::Info& file_info,
+                                       const base::FilePath& local_path)>
+      CreateSnapshotFileSuccessCallback;
 
   // A callback to be called when ReadBytes method call succeeds.
   typedef base::Callback<
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index dae7ed1..2bb991d 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -438,8 +438,7 @@
 
  private:
   void OnDisconnect(uint32_t reason, const std::string& message) {
-    if (reason == network::mojom::WebSocket::kInternalFailure &&
-        message == "Browser sent a text frame containing invalid UTF-8") {
+    if (message == "Browser sent a text frame containing invalid UTF-8") {
       std::move(success_closure_).Run();
     } else {
       ADD_FAILURE() << "Unexpected disconnect: reason=" << reason
diff --git a/chrome/browser/policy/assistant_policy_browsertest.cc b/chrome/browser/policy/assistant_policy_browsertest.cc
index 97192fc..0a6146c 100644
--- a/chrome/browser/policy/assistant_policy_browsertest.cc
+++ b/chrome/browser/policy/assistant_policy_browsertest.cc
@@ -93,45 +93,4 @@
       prefs->GetBoolean(chromeos::assistant::prefs::kAssistantHotwordEnabled));
 }
 
-IN_PROC_BROWSER_TEST_F(AssistantPolicyTest, AssistantQuickAnswersEnabled) {
-  PrefService* prefs = browser()->profile()->GetPrefs();
-  EXPECT_FALSE(prefs->IsManagedPreference(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  EXPECT_TRUE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  prefs->SetBoolean(chromeos::assistant::prefs::kAssistantQuickAnswersEnabled,
-                    false);
-  EXPECT_FALSE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-
-  // Verifies that the Quick Answers setting can be forced to always disabled.
-  PolicyMap policies;
-  policies.Set(key::kVoiceInteractionQuickAnswersEnabled,
-               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::Value(false), nullptr);
-  UpdateProviderPolicy(policies);
-  EXPECT_TRUE(prefs->IsManagedPreference(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  EXPECT_FALSE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  prefs->SetBoolean(chromeos::assistant::prefs::kAssistantQuickAnswersEnabled,
-                    true);
-  EXPECT_FALSE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-
-  // Verifies that the Quick Answers setting can be forced to always enabled.
-  policies.Set(key::kVoiceInteractionQuickAnswersEnabled,
-               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::Value(true), nullptr);
-  UpdateProviderPolicy(policies);
-  EXPECT_TRUE(prefs->IsManagedPreference(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  EXPECT_TRUE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-  prefs->SetBoolean(chromeos::assistant::prefs::kAssistantQuickAnswersEnabled,
-                    false);
-  EXPECT_TRUE(prefs->GetBoolean(
-      chromeos::assistant::prefs::kAssistantQuickAnswersEnabled));
-}
-
 }  // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 58a38df..0b57b1e 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -989,9 +989,6 @@
   { key::kVoiceInteractionHotwordEnabled,
     chromeos::assistant::prefs::kAssistantHotwordEnabled,
     base::Value::Type::BOOLEAN },
-  { key::kVoiceInteractionQuickAnswersEnabled,
-    chromeos::assistant::prefs::kAssistantQuickAnswersEnabled,
-    base::Value::Type::BOOLEAN },
   { key::kDevicePowerPeakShiftEnabled,
     ash::prefs::kPowerPeakShiftEnabled,
     base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/messaging_layer/encryption/decryption.cc b/chrome/browser/policy/messaging_layer/encryption/decryption.cc
index 0f0ffc6..c3ad5be 100644
--- a/chrome/browser/policy/messaging_layer/encryption/decryption.cc
+++ b/chrome/browser/policy/messaging_layer/encryption/decryption.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <limits>
 #include <string>
 
 #include "base/containers/span.h"
@@ -154,8 +155,8 @@
               // Assign a random number to be public key id for testing purposes
               // only (in production it will be Java Fingerprint2011 which is
               // 'long').
-              Encryptor::PublicKeyId public_key_id;
-              base::RandBytes(&public_key_id, sizeof(public_key_id));
+              const Encryptor::PublicKeyId public_key_id = base::RandGenerator(
+                  std::numeric_limits<Encryptor::PublicKeyId>::max());
               if (!decryptor->keys_.emplace(public_key_id, key_info).second) {
                 result = Status(error::ALREADY_EXISTS,
                                 base::StrCat({"Public key='", public_key,
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc
index e87d29d..805991f 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.cc
+++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -118,7 +118,7 @@
   void ProcessRecord(EncryptedRecord data,
                      base::OnceCallback<void(bool)> processed_cb) override;
   void ProcessGap(SequencingInformation start,
-                  uint64_t count,
+                  int64_t count,
                   base::OnceCallback<void(bool)> processed_cb) override;
 
   void Completed(bool need_encryption_key, Status final_status) override;
@@ -172,7 +172,7 @@
 
 void ReportingClient::Uploader::ProcessGap(
     SequencingInformation start,
-    uint64_t count,
+    int64_t count,
     base::OnceCallback<void(bool)> processed_cb) {
   if (completed_) {
     std::move(processed_cb).Run(false);
@@ -183,10 +183,10 @@
       FROM_HERE,
       base::BindOnce(
           [](std::vector<EncryptedRecord>* records, SequencingInformation start,
-             uint64_t count, base::OnceCallback<void(bool)> processed_cb) {
+             int64_t count, base::OnceCallback<void(bool)> processed_cb) {
             EncryptedRecord record;
             *record.mutable_sequencing_information() = std::move(start);
-            for (uint64_t i = 0; i < count; ++i) {
+            for (int64_t i = 0; i < count; ++i) {
               records->emplace_back(record);
               record.mutable_sequencing_information()->set_sequencing_id(
                   record.sequencing_information().sequencing_id() + 1);
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.cc b/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.cc
index 482433f..5c35ee9be 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.cc
+++ b/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.cc
@@ -20,8 +20,8 @@
 
 DiskResourceImpl::~DiskResourceImpl() = default;
 
-bool DiskResourceImpl::Reserve(uint64_t size) {
-  uint64_t old_used = used_.fetch_add(size);
+bool DiskResourceImpl::Reserve(int64_t size) {
+  int64_t old_used = used_.fetch_add(size);
   if (old_used + size > total_) {
     used_.fetch_sub(size);
     return false;
@@ -29,20 +29,20 @@
   return true;
 }
 
-void DiskResourceImpl::Discard(uint64_t size) {
+void DiskResourceImpl::Discard(int64_t size) {
   DCHECK_LE(size, used_.load());
   used_.fetch_sub(size);
 }
 
-uint64_t DiskResourceImpl::GetTotal() {
+int64_t DiskResourceImpl::GetTotal() {
   return total_;
 }
 
-uint64_t DiskResourceImpl::GetUsed() {
+int64_t DiskResourceImpl::GetUsed() {
   return used_.load();
 }
 
-void DiskResourceImpl::Test_SetTotal(uint64_t test_total) {
+void DiskResourceImpl::Test_SetTotal(int64_t test_total) {
   total_ = test_total;
 }
 
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.h b/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.h
index 6e0e4ea..1336d3d9 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.h
+++ b/chrome/browser/policy/messaging_layer/storage/resources/disk_resource_impl.h
@@ -21,15 +21,15 @@
   ~DiskResourceImpl() override;
 
   // Implementation of ResourceInterface methods.
-  bool Reserve(uint64_t size) override;
-  void Discard(uint64_t size) override;
-  uint64_t GetTotal() override;
-  uint64_t GetUsed() override;
-  void Test_SetTotal(uint64_t test_total) override;
+  bool Reserve(int64_t size) override;
+  void Discard(int64_t size) override;
+  int64_t GetTotal() override;
+  int64_t GetUsed() override;
+  void Test_SetTotal(int64_t test_total) override;
 
  private:
-  uint64_t total_;
-  std::atomic<uint64_t> used_;
+  int64_t total_;
+  std::atomic<int64_t> used_;
 };
 
 }  // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.cc b/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.cc
index 41c1e13..aa851c3 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.cc
+++ b/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.cc
@@ -20,8 +20,9 @@
 
 MemoryResourceImpl::~MemoryResourceImpl() = default;
 
-bool MemoryResourceImpl::Reserve(uint64_t size) {
-  uint64_t old_used = used_.fetch_add(size);
+bool MemoryResourceImpl::Reserve(int64_t size) {
+  DCHECK_GE(size, 0);
+  int64_t old_used = used_.fetch_add(size);
   if (old_used + size > total_) {
     used_.fetch_sub(size);
     return false;
@@ -29,20 +30,20 @@
   return true;
 }
 
-void MemoryResourceImpl::Discard(uint64_t size) {
+void MemoryResourceImpl::Discard(int64_t size) {
   DCHECK_LE(size, used_.load());
   used_.fetch_sub(size);
 }
 
-uint64_t MemoryResourceImpl::GetTotal() {
+int64_t MemoryResourceImpl::GetTotal() {
   return total_;
 }
 
-uint64_t MemoryResourceImpl::GetUsed() {
+int64_t MemoryResourceImpl::GetUsed() {
   return used_.load();
 }
 
-void MemoryResourceImpl::Test_SetTotal(uint64_t test_total) {
+void MemoryResourceImpl::Test_SetTotal(int64_t test_total) {
   total_ = test_total;
 }
 
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.h b/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.h
index db927f0..7dd2d16 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.h
+++ b/chrome/browser/policy/messaging_layer/storage/resources/memory_resource_impl.h
@@ -21,15 +21,15 @@
   ~MemoryResourceImpl() override;
 
   // Implementation of ResourceInterface methods.
-  bool Reserve(uint64_t size) override;
-  void Discard(uint64_t size) override;
-  uint64_t GetTotal() override;
-  uint64_t GetUsed() override;
-  void Test_SetTotal(uint64_t test_total) override;
+  bool Reserve(int64_t size) override;
+  void Discard(int64_t size) override;
+  int64_t GetTotal() override;
+  int64_t GetUsed() override;
+  void Test_SetTotal(int64_t test_total) override;
 
  private:
-  uint64_t total_;
-  std::atomic<uint64_t> used_;
+  int64_t total_;
+  std::atomic<int64_t> used_;
 };
 
 }  // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.cc b/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.cc
index 54acd04f8..5ee2770 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.cc
+++ b/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.cc
@@ -8,7 +8,7 @@
 
 namespace reporting {
 
-ScopedReservation::ScopedReservation(uint64_t size,
+ScopedReservation::ScopedReservation(int64_t size,
                                      ResourceInterface* resource_interface)
     : resource_interface_(resource_interface) {
   if (!resource_interface->Reserve(size)) {
diff --git a/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.h b/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.h
index 3e1840b..43e23f3a 100644
--- a/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.h
+++ b/chrome/browser/policy/messaging_layer/storage/resources/resource_interface.h
@@ -22,20 +22,20 @@
   // Returns true if requested amount can be allocated.
   // After that the caller can actually allocate it or must call
   // |Discard| if decided not to allocate.
-  virtual bool Reserve(uint64_t size) = 0;
+  virtual bool Reserve(int64_t size) = 0;
 
   // Reverts reservation.
   // Must be called after the specified amount is released.
-  virtual void Discard(uint64_t size) = 0;
+  virtual void Discard(int64_t size) = 0;
 
   // Returns total amount.
-  virtual uint64_t GetTotal() = 0;
+  virtual int64_t GetTotal() = 0;
 
   // Returns current used amount.
-  virtual uint64_t GetUsed() = 0;
+  virtual int64_t GetUsed() = 0;
 
   // Test only: Sets non-default usage limit.
-  virtual void Test_SetTotal(uint64_t test_total) = 0;
+  virtual void Test_SetTotal(int64_t test_total) = 0;
 
  protected:
   ResourceInterface() = default;
@@ -57,7 +57,7 @@
 // Can be handed over to another owner.
 class ScopedReservation {
  public:
-  ScopedReservation(uint64_t size, ResourceInterface* resource_interface);
+  ScopedReservation(int64_t size, ResourceInterface* resource_interface);
   ScopedReservation(ScopedReservation&& other);
   ScopedReservation(const ScopedReservation& other) = delete;
   ScopedReservation& operator=(const ScopedReservation& other) = delete;
@@ -67,7 +67,7 @@
 
  private:
   ResourceInterface* const resource_interface_;
-  base::Optional<uint64_t> size_;
+  base::Optional<int64_t> size_;
 };
 
 ResourceInterface* GetMemoryResource();
diff --git a/chrome/browser/policy/messaging_layer/storage/storage.cc b/chrome/browser/policy/messaging_layer/storage/storage.cc
index 9e5a41f..41565be 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage.cc
+++ b/chrome/browser/policy/messaging_layer/storage/storage.cc
@@ -134,7 +134,7 @@
   }
 
   void ProcessGap(SequencingInformation start,
-                  uint64_t count,
+                  int64_t count,
                   base::OnceCallback<void(bool)> processed_cb) override {
     // Update sequencing information: add Priority.
     start.set_priority(priority_);
@@ -167,7 +167,7 @@
   // key is updated.
   Status UploadKeyFile(const SignedEncryptionInfo& signed_encryption_key) {
     // Atomically reserve file index (none else will get the same index).
-    uint64_t new_file_index = next_key_file_index_.fetch_add(1);
+    int64_t new_file_index = next_key_file_index_.fetch_add(1);
     // Write into file.
     RETURN_IF_ERROR(WriteKeyInfoFile(new_file_index, signed_encryption_key));
 
@@ -194,7 +194,7 @@
     // Enumerate possible key files, collect the ones that have valid name,
     // set next_key_file_index_ to a value that is definitely not used.
     base::flat_set<base::FilePath> all_key_files;
-    base::flat_map<uint64_t, base::FilePath> found_key_files;
+    base::flat_map<int64_t, base::FilePath> found_key_files;
     EnumerateKeyFiles(&all_key_files, &found_key_files);
 
     // Try to unserialize the key from each found file (latest first).
@@ -221,7 +221,7 @@
 
  private:
   // Writes key into file. Called during key upload.
-  Status WriteKeyInfoFile(uint64_t new_file_index,
+  Status WriteKeyInfoFile(int64_t new_file_index,
                           const SignedEncryptionInfo& signed_encryption_key) {
     base::FilePath key_file_path =
         directory_.Append(kEncryptionKeyFilePrefix)
@@ -250,7 +250,7 @@
                         key_file.ErrorToString(key_file.GetLastFileError()),
                         " file=", key_file_path.MaybeAsASCII()}));
     }
-    if (static_cast<size_t>(write_result) != serialized_key.size()) {
+    if (write_result != static_cast<int32_t>(serialized_key.size())) {
       return Status(error::DATA_LOSS,
                     base::StrCat({"Failed to seralize key into file='",
                                   key_file_path.MaybeAsASCII(), "'"}));
@@ -260,7 +260,7 @@
 
   // Enumerates key files and deletes those with index lower than
   // |new_file_index|. Called during key upload.
-  void RemoveKeyFilesWithLowerIndexes(uint64_t new_file_index) {
+  void RemoveKeyFilesWithLowerIndexes(int64_t new_file_index) {
     base::flat_set<base::FilePath> key_files_to_remove;
     base::FileEnumerator dir_enum(
         directory_,
@@ -278,8 +278,8 @@
         // Should not happen, will remove this file.
         continue;
       }
-      uint64_t file_index = 0;
-      if (!base::StringToUint64(extension.substr(1), &file_index)) {
+      int64_t file_index = 0;
+      if (!base::StringToInt64(extension.substr(1), &file_index)) {
         // Bad extension - not a number. Should not happen, will remove this
         // file.
         continue;
@@ -302,7 +302,7 @@
   // Called once, during initialization.
   void EnumerateKeyFiles(
       base::flat_set<base::FilePath>* all_key_files,
-      base::flat_map<uint64_t, base::FilePath>* found_key_files) {
+      base::flat_map<int64_t, base::FilePath>* found_key_files) {
     base::FileEnumerator dir_enum(
         directory_,
         /*recursive=*/false, base::FileEnumerator::FILES,
@@ -318,8 +318,8 @@
         // Should not happen.
         continue;
       }
-      uint64_t file_index = 0;
-      bool success = base::StringToUint64(extension.substr(1), &file_index);
+      int64_t file_index = 0;
+      bool success = base::StringToInt64(extension.substr(1), &file_index);
       if (!success) {
         // Bad extension - not a number. Should not happen (file is corrupt).
         continue;
@@ -341,7 +341,7 @@
   // Called once, during initialization.
   base::Optional<std::pair<base::FilePath, SignedEncryptionInfo>>
   LocateValidKeyAndParse(
-      const base::flat_map<uint64_t, base::FilePath>& found_key_files) {
+      const base::flat_map<int64_t, base::FilePath>& found_key_files) {
     // Try to unserialize the key from each found file (latest first).
     for (auto key_file_it = found_key_files.rbegin();
          key_file_it != found_key_files.rend(); ++key_file_it) {
@@ -390,7 +390,7 @@
   // Every time a new key is received, it is stored in a file with the next
   // index; however, any file found with the matching signature can be used
   // to successfully encrypt records and for the server to then decrypt them.
-  std::atomic<uint64_t> next_key_file_index_{0};
+  std::atomic<int64_t> next_key_file_index_{0};
 
   const base::FilePath directory_;
 };
@@ -553,13 +553,13 @@
 }
 
 void Storage::Confirm(Priority priority,
-                      uint64_t seq_number,
+                      int64_t sequencing_id,
                       base::OnceCallback<void(Status)> completion_cb) {
   // Note: queues_ never change after initialization is finished, so there is
   // no need to protect or serialize access to it.
   ASSIGN_OR_ONCE_CALLBACK_AND_RETURN(scoped_refptr<StorageQueue> queue,
                                      completion_cb, GetQueue(priority));
-  queue->Confirm(seq_number, std::move(completion_cb));
+  queue->Confirm(sequencing_id, std::move(completion_cb));
 }
 
 Status Storage::Flush(Priority priority) {
diff --git a/chrome/browser/policy/messaging_layer/storage/storage.h b/chrome/browser/policy/messaging_layer/storage/storage.h
index 91b559b..cb74499 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage.h
+++ b/chrome/browser/policy/messaging_layer/storage/storage.h
@@ -57,7 +57,7 @@
   // |sequencing_id| (inclusively). All records with sequeincing ids <= this
   // one can be removed from the Storage, and can no longer be uploaded.
   void Confirm(Priority priority,
-               uint64_t sequencing_id,
+               int64_t sequencing_id,
                base::OnceCallback<void(Status)> completion_cb);
 
   // Initiates upload of collected records according to the priority.
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_configuration.h b/chrome/browser/policy/messaging_layer/storage/storage_configuration.h
index 8c847bd..402ca2a 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage_configuration.h
+++ b/chrome/browser/policy/messaging_layer/storage/storage_configuration.h
@@ -10,9 +10,9 @@
 // Storage options class allowing to set parameters individually, e.g.:
 // Storage::Create(Options()
 //                     .set_directory("/var/cache/reporting")
-//                     .set_max_record_size(4 * 1024u)
-//                     .set_max_total_files_size(64 * 1024u * 1024u)
-//                     .set_max_total_memory_size(256 * 1024u),
+//                     .set_max_record_size(4 * 1024)
+//                     .set_max_total_files_size(64 * 1024 * 1024)
+//                     .set_max_total_memory_size(256 * 1024),
 //                 callback);
 class StorageOptions {
  public:
@@ -27,42 +27,42 @@
     max_record_size_ = max_record_size;
     return *this;
   }
-  StorageOptions& set_max_total_files_size(uint64_t max_total_files_size) {
+  StorageOptions& set_max_total_files_size(int64_t max_total_files_size) {
     max_total_files_size_ = max_total_files_size;
     return *this;
   }
-  StorageOptions& set_max_total_memory_size(uint64_t max_total_memory_size) {
+  StorageOptions& set_max_total_memory_size(int64_t max_total_memory_size) {
     max_total_memory_size_ = max_total_memory_size;
     return *this;
   }
-  StorageOptions& set_single_file_size(uint64_t single_file_size) {
+  StorageOptions& set_single_file_size(int64_t single_file_size) {
     single_file_size_ = single_file_size;
     return *this;
   }
   const base::FilePath& directory() const { return directory_; }
   size_t max_record_size() const { return max_record_size_; }
-  uint64_t max_total_files_size() const { return max_total_files_size_; }
-  uint64_t max_total_memory_size() const { return max_total_memory_size_; }
-  uint64_t single_file_size() const { return single_file_size_; }
+  int64_t max_total_files_size() const { return max_total_files_size_; }
+  int64_t max_total_memory_size() const { return max_total_memory_size_; }
+  int64_t single_file_size() const { return single_file_size_; }
 
  private:
   // Subdirectory of the location assigned for this Storage.
   base::FilePath directory_;
 
   // Maximum record size.
-  size_t max_record_size_ = 1 * 1024LL * 1024LL;  // 1 MiB
+  int64_t max_record_size_ = 1 * 1024LL * 1024LL;  // 1 MiB
 
   // Maximum total size of all files in all queues.
-  uint64_t max_total_files_size_ = 64 * 1024LL * 1024LL;  // 64 MiB
+  int64_t max_total_files_size_ = 64 * 1024LL * 1024LL;  // 64 MiB
 
   // Maximum memory usage (reading buffers).
-  uint64_t max_total_memory_size_ = 4 * 1024LL * 1024LL;  // 4 MiB
+  int64_t max_total_memory_size_ = 4 * 1024LL * 1024LL;  // 4 MiB
 
   // Cut-off size of an individual file in all queues.
   // When file exceeds this size, the new file is created
   // for further records. Note that each file must have at least
   // one record before it is closed, regardless of that record size.
-  uint64_t single_file_size_ = 1 * 1024LL * 1024LL;  // 1 MiB
+  int64_t single_file_size_ = 1 * 1024LL * 1024LL;  // 1 MiB
 };
 
 // Single queue options class allowing to set parameters individually, e.g.:
@@ -99,7 +99,7 @@
   size_t max_total_memory_size() const {
     return storage_options_.max_total_memory_size();
   }
-  uint64_t single_file_size() const {
+  int64_t single_file_size() const {
     return storage_options_.single_file_size();
   }
   base::TimeDelta upload_period() const { return upload_period_; }
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue.cc b/chrome/browser/policy/messaging_layer/storage/storage_queue.cc
index 7cfac06..766bd06c 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage_queue.cc
+++ b/chrome/browser/policy/messaging_layer/storage/storage_queue.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cstring>
 #include <iterator>
+#include <limits>
 #include <map>
 #include <memory>
 #include <string>
@@ -66,7 +67,7 @@
 
 // Internal structure of the record header. Must fit in FRAME_SIZE.
 struct RecordHeader {
-  uint64_t record_sequencing_id;
+  int64_t record_sequencing_id;
   uint32_t record_size;  // Size of the blob, not including RecordHeader
   uint32_t record_hash;  // Hash of the blob, not including RecordHeader
   // Data starts right after the header.
@@ -161,7 +162,9 @@
   base::flat_set<base::FilePath> used_files_set;
   RETURN_IF_ERROR(EnumerateDataFiles(&used_files_set));
   RETURN_IF_ERROR(ScanLastFile());
-  generation_id_ = base::RandUint64();  // reset it in case of inavaliability.
+  generation_id_ = base::RandGenerator(
+      std::numeric_limits<int64_t>::max());  // reset it in case of
+                                             // inavaliability.
   if (next_sequencing_id_ > 0) {
     // Enumerate metadata files to determine what sequencing ids have
     // last record digest. They might have metadata for sequencing ids
@@ -227,7 +230,7 @@
   last_record_digest_ = wrapped_record->record_digest();
 }
 
-StatusOr<uint64_t> StorageQueue::AddDataFile(
+StatusOr<int64_t> StorageQueue::AddDataFile(
     const base::FilePath& full_name,
     const base::FileEnumerator::FileInfo& file_info) {
   const auto extension = full_name.Extension();
@@ -236,8 +239,8 @@
                   base::StrCat({"File has no extension: '",
                                 full_name.MaybeAsASCII(), "'"}));
   }
-  uint64_t file_sequencing_id = 0;
-  bool success = base::StringToUint64(extension.substr(1), &file_sequencing_id);
+  int64_t file_sequencing_id = 0;
+  bool success = base::StringToInt64(extension.substr(1), &file_sequencing_id);
   if (!success) {
     return Status(error::INTERNAL,
                   base::StrCat({"File extension does not parse: '",
@@ -260,7 +263,7 @@
   // We need to set first_sequencing_id_ to 0 if this is the initialization
   // of an empty StorageQueue, and to the lowest sequencing id among all
   // existing files, if it was already used.
-  base::Optional<uint64_t> first_sequencing_id;
+  base::Optional<int64_t> first_sequencing_id;
   base::FileEnumerator dir_enum(
       options_.directory(),
       /*recursive=*/false, base::FileEnumerator::FILES,
@@ -396,7 +399,8 @@
   }
   scoped_refptr<SingleFile> last_file = files_.rbegin()->second;
   if (last_file->size() > 0 &&  // Cannot have a file with no records.
-      last_file->size() + size + sizeof(RecordHeader) + FRAME_SIZE >
+      last_file->size() +
+              static_cast<int64_t>(size + sizeof(RecordHeader) + FRAME_SIZE) >
           options_.single_file_size()) {
     // The last file will become too large, asynchronously close it and add
     // new.
@@ -534,7 +538,7 @@
 Status StorageQueue::RestoreMetadata(
     base::flat_set<base::FilePath>* used_files_set) {
   // Enumerate all meta-files into a map sequencing_id->file_path.
-  std::map<uint64_t, std::pair<base::FilePath, size_t>> meta_files;
+  std::map<int64_t, std::pair<base::FilePath, size_t>> meta_files;
   base::FileEnumerator dir_enum(
       options_.directory(),
       /*recursive=*/false, base::FileEnumerator::FILES,
@@ -545,8 +549,8 @@
     if (extension.empty()) {
       continue;
     }
-    uint64_t sequencing_id = 0;
-    bool success = base::StringToUint64(
+    int64_t sequencing_id = 0;
+    bool success = base::StringToInt64(
         dir_enum.GetInfo().GetName().Extension().substr(1), &sequencing_id);
     if (!success) {
       continue;
@@ -582,8 +586,8 @@
                   base::StrCat({"Cannot read metafile=", meta_file->name(),
                                 " status=", read_result.status().ToString()}));
   }
-  const uint64_t generation_id =
-      *reinterpret_cast<const uint64_t*>(read_result.ValueOrDie().data());
+  const int64_t generation_id =
+      *reinterpret_cast<const int64_t*>(read_result.ValueOrDie().data());
   // Read last record digest.
   read_result = meta_file->Read(/*pos=*/sizeof(generation_id_),
                                 crypto::kSHA256Length, max_buffer_size);
@@ -621,8 +625,8 @@
   }
 }
 
-void StorageQueue::DeleteOutdatedMetadata(uint64_t sequencing_id_to_keep) {
-  std::vector<std::pair<base::FilePath, uint64_t>> files_to_delete;
+void StorageQueue::DeleteOutdatedMetadata(int64_t sequencing_id_to_keep) {
+  std::vector<std::pair<base::FilePath, int64_t>> files_to_delete;
   base::FileEnumerator dir_enum(
       options_.directory(),
       /*recursive=*/false, base::FileEnumerator::FILES,
@@ -633,8 +637,8 @@
     if (extension.empty()) {
       continue;
     }
-    uint64_t sequencing_id = 0;
-    bool success = base::StringToUint64(
+    int64_t sequencing_id = 0;
+    bool success = base::StringToInt64(
         dir_enum.GetInfo().GetName().Extension().substr(1), &sequencing_id);
     if (!success) {
       continue;
@@ -743,7 +747,7 @@
   void StartUploading(base::WeakPtr<StorageQueue> storage_queue) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
     // Read from it until the specified sequencing id is found.
-    for (uint64_t sequencing_id = current_file_->first;
+    for (int64_t sequencing_id = current_file_->first;
          sequencing_id < sequencing_info_.sequencing_id(); ++sequencing_id) {
       auto blob = EnsureBlob(storage_queue, sequencing_id);
       if (blob.status().error_code() == error::OUT_OF_RANGE) {
@@ -761,10 +765,11 @@
         // file, if present.
         ++current_file_;
         current_pos_ = 0;
-        uint64_t count =
+        int64_t count =
             (current_file_ == files_.end())
                 ? 1
                 : current_file_->first - sequencing_info_.sequencing_id();
+        DCHECK_GT(count, 0L);
         CallGapUpload(count);
         // Resume at ScheduleNextRecord.
         return;
@@ -830,8 +835,9 @@
     sequencing_info_.set_sequencing_id(sequencing_info_.sequencing_id() + 1);
   }
 
-  void CallGapUpload(uint64_t count) {
+  void CallGapUpload(int64_t count) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_GE(count, 0);
     if (count == 0u) {
       // No records skipped.
       NextRecord(/*more_records=*/true);
@@ -884,7 +890,7 @@
   // not match), returns error.
   StatusOr<base::StringPiece> EnsureBlob(
       base::WeakPtr<StorageQueue> storage_queue,
-      uint64_t sequencing_id) {
+      int64_t sequencing_id) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
 
     // Test only: simulate error, if requested.
@@ -965,7 +971,7 @@
   }
 
   void CallRecordOrGap(base::WeakPtr<StorageQueue> storage_queue,
-                       uint64_t sequencing_id) {
+                       int64_t sequencing_id) {
     auto blob = EnsureBlob(storage_queue, sequencing_info_.sequencing_id());
     if (blob.status().error_code() == error::OUT_OF_RANGE) {
       // Reached end of file, switch to the next one (if present).
@@ -982,7 +988,7 @@
       // file, if present.
       ++current_file_;
       current_pos_ = 0;
-      uint64_t count =
+      int64_t count =
           (current_file_ == files_.end())
               ? 1
               : current_file_->first - sequencing_info_.sequencing_id();
@@ -995,10 +1001,10 @@
   }
 
   // Files that will be read (in order of sequencing ids).
-  std::map<uint64_t, scoped_refptr<SingleFile>> files_;
+  std::map<int64_t, scoped_refptr<SingleFile>> files_;
   SequencingInformation sequencing_info_;
   uint32_t current_pos_;
-  std::map<uint64_t, scoped_refptr<SingleFile>>::iterator current_file_;
+  std::map<int64_t, scoped_refptr<SingleFile>>::iterator current_file_;
   const std::unique_ptr<UploaderInterface> uploader_;
   base::WeakPtrFactory<StorageQueue> storage_queue_weakptr_factory_;
 
@@ -1189,8 +1195,8 @@
   return Status::StatusOK();
 }
 
-std::map<uint64_t, scoped_refptr<StorageQueue::SingleFile>>
-StorageQueue::CollectFilesForUpload(uint64_t sequencing_id) const {
+std::map<int64_t, scoped_refptr<StorageQueue::SingleFile>>
+StorageQueue::CollectFilesForUpload(int64_t sequencing_id) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(storage_queue_sequence_checker_);
   // Locate the first file based on sequencing id.
   auto file_it = files_.find(sequencing_id);
@@ -1203,7 +1209,7 @@
 
   // Create references to the files that will be uploaded.
   // Exclude the last file (still being written).
-  std::map<uint64_t, scoped_refptr<SingleFile>> files;
+  std::map<int64_t, scoped_refptr<SingleFile>> files;
   for (; file_it != files_.end() &&
          file_it->second.get() != files_.rbegin()->second.get();
        ++file_it) {
@@ -1214,7 +1220,7 @@
 
 class StorageQueue::ConfirmContext : public TaskRunnerContext<Status> {
  public:
-  ConfirmContext(uint64_t sequencing_id,
+  ConfirmContext(int64_t sequencing_id,
                  base::OnceCallback<void(Status)> end_callback,
                  scoped_refptr<StorageQueue> storage_queue)
       : TaskRunnerContext<Status>(std::move(end_callback),
@@ -1235,19 +1241,19 @@
   }
 
   // Confirmed sequencing id.
-  uint64_t sequencing_id_;
+  int64_t sequencing_id_;
 
   scoped_refptr<StorageQueue> storage_queue_;
 
   SEQUENCE_CHECKER(confirm_sequence_checker_);
 };
 
-void StorageQueue::Confirm(uint64_t sequencing_id,
+void StorageQueue::Confirm(int64_t sequencing_id,
                            base::OnceCallback<void(Status)> completion_cb) {
   Start<ConfirmContext>(sequencing_id, std::move(completion_cb), this);
 }
 
-Status StorageQueue::RemoveConfirmedData(uint64_t sequencing_id) {
+Status StorageQueue::RemoveConfirmedData(int64_t sequencing_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(storage_queue_sequence_checker_);
   // Update first unconfirmed id, unless new one is lower.
   if (!first_unconfirmed_sequencing_id_.has_value() ||
@@ -1304,7 +1310,7 @@
 }
 
 void StorageQueue::TestInjectBlockReadErrors(
-    std::initializer_list<uint64_t> sequencing_ids) {
+    std::initializer_list<int64_t> sequencing_ids) {
   test_injected_fail_sequencing_ids_ = sequencing_ids;
 }
 
@@ -1341,7 +1347,7 @@
       return Status(error::DATA_LOSS,
                     base::StrCat({"Cannot get size of file=", name()}));
     }
-    size_ = static_cast<uint64_t>(file_size);
+    size_ = file_size;
   }
   return Status::StatusOK();
 }
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue.h b/chrome/browser/policy/messaging_layer/storage/storage_queue.h
index 170dff0..0332151 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage_queue.h
+++ b/chrome/browser/policy/messaging_layer/storage/storage_queue.h
@@ -59,7 +59,7 @@
     // if next record needs to be delivered and false if the Uploader should
     // stop.
     virtual void ProcessGap(SequencingInformation start,
-                            uint64_t count,
+                            int64_t count,
                             base::OnceCallback<void(bool)> processed_cb) = 0;
 
     // Finalizes the upload (e.g. sends the message to server and gets
@@ -98,7 +98,7 @@
   // All records with sequencing ids <= this one can be removed from
   // the StorageQueue, and can no longer be uploaded.
   // Helper methods: RemoveConfirmedData.
-  void Confirm(uint64_t sequencing_id,
+  void Confirm(int64_t sequencing_id,
                base::OnceCallback<void(Status)> completion_cb);
 
   // Initiates upload of collected records. Called periodically by timer, based
@@ -124,8 +124,7 @@
   void Flush();
 
   // Test only: makes specified records fail on reading.
-  void TestInjectBlockReadErrors(
-      std::initializer_list<uint64_t> sequencing_ids);
+  void TestInjectBlockReadErrors(std::initializer_list<int64_t> sequencing_ids);
 
   // Access queue options.
   const QueueOptions& options() const { return options_; }
@@ -173,7 +172,7 @@
       DCHECK(is_opened());
       return is_readonly_.value();
     }
-    uint64_t size() const { return size_; }
+    int64_t size() const { return size_; }
     std::string name() const { return filename_.MaybeAsASCII(); }
 
    protected:
@@ -187,7 +186,7 @@
     base::Optional<bool> is_readonly_;
 
     const base::FilePath filename_;  // relative to the StorageQueue directory
-    uint64_t size_ = 0;  // tracked internally rather than by filesystem
+    int64_t size_ = 0;  // tracked internally rather than by filesystem
 
     std::unique_ptr<base::File> handle_;  // Set only when opened/created.
 
@@ -198,7 +197,7 @@
     // the buffer is reset.
     size_t data_start_ = 0;
     size_t data_end_ = 0;
-    uint64_t file_position_ = 0;
+    int64_t file_position_ = 0;
     size_t buffer_size_ = 0;
     std::unique_ptr<char[]> buffer_;
   };
@@ -224,7 +223,7 @@
   // Helper method for Init(): process single data file.
   // Return sequencing_id from <prefix>.<sequencing_id> file name, or Status
   // in case there is any error.
-  StatusOr<uint64_t> AddDataFile(
+  StatusOr<int64_t> AddDataFile(
       const base::FilePath& full_name,
       const base::FileEnumerator::FileInfo& file_info);
 
@@ -269,7 +268,7 @@
 
   // Helper method for Write(): deletes meta files up to, but not including
   // |sequencing_id_to_keep|. Any errors are ignored.
-  void DeleteOutdatedMetadata(uint64_t sequencing_id_to_keep);
+  void DeleteOutdatedMetadata(int64_t sequencing_id_to_keep);
 
   // Helper method for Write(): composes record header and writes it to the
   // file, followed by data.
@@ -284,13 +283,13 @@
   // Helper method for Upload: collects and sets aside |files| in the
   // StorageQueue that have data for the Upload (all files that have records
   // with sequencing ids equal or higher than |sequencing_id|).
-  std::map<uint64_t, scoped_refptr<SingleFile>> CollectFilesForUpload(
-      uint64_t sequencing_id) const;
+  std::map<int64_t, scoped_refptr<SingleFile>> CollectFilesForUpload(
+      int64_t sequencing_id) const;
 
   // Helper method for Confirm: Moves |first_sequencing_id_| to
   // (|sequencing_id|+1) and removes files that only have records with seq
   // ids below or equal to |sequencing_id| (below |first_sequencing_id_|).
-  Status RemoveConfirmedData(uint64_t sequencing_id);
+  Status RemoveConfirmedData(int64_t sequencing_id);
 
   // Immutable options, stored at the time of creation.
   const QueueOptions options_;
@@ -299,18 +298,18 @@
   // Set up once during initialization by reading from the 'gen_id.NNNN' file
   // matching the last sequencing id, or generated anew as a random number if no
   // such file found (files do not match the id).
-  uint64_t generation_id_ = 0;
+  int64_t generation_id_ = 0;
 
   // Digest of the last written record (loaded at queue initialization, absent
   // if the new generation has just started, and no records where stored yet).
   base::Optional<std::string> last_record_digest_;
 
   // Next sequencing id to store (not assigned yet).
-  uint64_t next_sequencing_id_ = 0;
+  int64_t next_sequencing_id_ = 0;
 
   // First sequencing id store still has (no records with lower
   // sequencing id exist in store).
-  uint64_t first_sequencing_id_ = 0;
+  int64_t first_sequencing_id_ = 0;
 
   // First unconfirmed sequencing id (no records with lower
   // sequencing id will be ever uploaded). Set by the first
@@ -318,10 +317,10 @@
   // If first_unconfirmed_sequencing_id_ < first_sequencing_id_,
   // [first_unconfirmed_sequencing_id_, first_sequencing_id_) is a gap
   // that cannot be filled in and is uploaded as such.
-  base::Optional<uint64_t> first_unconfirmed_sequencing_id_;
+  base::Optional<int64_t> first_unconfirmed_sequencing_id_;
 
   // Ordered map of the files by ascending sequencing id.
-  std::map<uint64_t, scoped_refptr<SingleFile>> files_;
+  std::map<int64_t, scoped_refptr<SingleFile>> files_;
 
   // Counter of the Read operations. When not 0, none of the files_ can be
   // deleted. Incremented by |ReadContext::OnStart|, decremented by
@@ -339,7 +338,7 @@
   scoped_refptr<EncryptionModule> encryption_module_;
 
   // Test only: records specified to fail on reading.
-  base::flat_set<uint64_t> test_injected_fail_sequencing_ids_;
+  base::flat_set<int64_t> test_injected_fail_sequencing_ids_;
 
   // Sequential task runner for all activities in this StorageQueue.
   scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc b/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc
index ada8497..8846c91 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc
@@ -85,9 +85,9 @@
   // should have that digest already recorded. Only the first record in a
   // generation is uploaded without last record digest. "Optional" is set to
   // no-value if there was a gap record instead of a real one.
-  using LastRecordDigestMap = std::map<
-      std::pair<uint64_t /*generation id */, uint64_t /*sequencing id*/>,
-      base::Optional<std::string /*digest*/>>;
+  using LastRecordDigestMap =
+      std::map<std::pair<int64_t /*generation id */, int64_t /*sequencing id*/>,
+               base::Optional<std::string /*digest*/>>;
 
   explicit MockUploadClient(LastRecordDigestMap* last_record_digest_map)
       : last_record_digest_map_(last_record_digest_map) {}
@@ -161,7 +161,7 @@
   }
 
   void ProcessGap(SequencingInformation sequencing_information,
-                  uint64_t count,
+                  int64_t count,
                   base::OnceCallback<void(bool)> processed_cb) override {
     // Verify generation match.
     if (generation_id_.has_value() &&
@@ -195,9 +195,9 @@
     UploadComplete(need_encryption_key, status);
   }
 
-  MOCK_METHOD(bool, UploadRecord, (uint64_t, base::StringPiece), (const));
-  MOCK_METHOD(bool, UploadRecordFailure, (uint64_t, Status), (const));
-  MOCK_METHOD(bool, UploadGap, (uint64_t, uint64_t), (const));
+  MOCK_METHOD(bool, UploadRecord, (int64_t, base::StringPiece), (const));
+  MOCK_METHOD(bool, UploadRecordFailure, (int64_t, Status), (const));
+  MOCK_METHOD(bool, UploadGap, (int64_t, int64_t), (const));
   MOCK_METHOD(void, UploadComplete, (bool, Status), (const));
 
   // Helper class for setting up mock client expectations of a successful
@@ -211,40 +211,40 @@
           .InSequence(client_->test_upload_sequence_);
     }
 
-    SetUp& Required(uint64_t sequence_number, base::StringPiece value) {
+    SetUp& Required(int64_t sequencing_id, base::StringPiece value) {
       EXPECT_CALL(*client_,
-                  UploadRecord(Eq(sequence_number), StrEq(std::string(value))))
+                  UploadRecord(Eq(sequencing_id), StrEq(std::string(value))))
           .InSequence(client_->test_upload_sequence_)
           .WillOnce(Return(true));
       return *this;
     }
 
-    SetUp& Possible(uint64_t sequence_number, base::StringPiece value) {
+    SetUp& Possible(int64_t sequencing_id, base::StringPiece value) {
       EXPECT_CALL(*client_,
-                  UploadRecord(Eq(sequence_number), StrEq(std::string(value))))
+                  UploadRecord(Eq(sequencing_id), StrEq(std::string(value))))
           .Times(Between(0, 1))
           .InSequence(client_->test_upload_sequence_)
           .WillRepeatedly(Return(true));
       return *this;
     }
 
-    SetUp& RequiredGap(uint64_t sequence_number, uint64_t count) {
-      EXPECT_CALL(*client_, UploadGap(Eq(sequence_number), Eq(count)))
+    SetUp& RequiredGap(int64_t sequencing_id, int64_t count) {
+      EXPECT_CALL(*client_, UploadGap(Eq(sequencing_id), Eq(count)))
           .InSequence(client_->test_upload_sequence_)
           .WillOnce(Return(true));
       return *this;
     }
 
-    SetUp& PossibleGap(uint64_t sequence_number, uint64_t count) {
-      EXPECT_CALL(*client_, UploadGap(Eq(sequence_number), Eq(count)))
+    SetUp& PossibleGap(int64_t sequencing_id, int64_t count) {
+      EXPECT_CALL(*client_, UploadGap(Eq(sequencing_id), Eq(count)))
           .Times(Between(0, 1))
           .InSequence(client_->test_upload_sequence_)
           .WillRepeatedly(Return(true));
       return *this;
     }
 
-    SetUp& Failure(uint64_t sequence_number, Status error) {
-      EXPECT_CALL(*client_, UploadRecordFailure(Eq(sequence_number), Eq(error)))
+    SetUp& Failure(int64_t sequencing_id, Status error) {
+      EXPECT_CALL(*client_, UploadRecordFailure(Eq(sequencing_id), Eq(error)))
           .InSequence(client_->test_upload_sequence_)
           .WillOnce(Return(true));
       return *this;
@@ -255,7 +255,7 @@
   };
 
  private:
-  base::Optional<uint64_t> generation_id_;
+  base::Optional<int64_t> generation_id_;
   LastRecordDigestMap* const last_record_digest_map_;
 
   Sequence test_upload_sequence_;
@@ -285,8 +285,8 @@
     storage_queue_ = std::move(storage_queue_result.ValueOrDie());
   }
 
-  void InjectFailures(std::initializer_list<uint64_t> seq_numbers) {
-    storage_queue_->TestInjectBlockReadErrors(seq_numbers);
+  void InjectFailures(std::initializer_list<int64_t> sequencing_ids) {
+    storage_queue_->TestInjectBlockReadErrors(sequencing_ids);
   }
 
   QueueOptions BuildStorageQueueOptionsImmediate() const {
@@ -328,9 +328,9 @@
     ASSERT_OK(write_result) << write_result;
   }
 
-  void ConfirmOrDie(std::uint64_t seq_number) {
+  void ConfirmOrDie(int64_t sequencing_id) {
     TestEvent<Status> c;
-    storage_queue_->Confirm(seq_number, c.cb());
+    storage_queue_->Confirm(sequencing_id, c.cb());
     const Status c_result = c.result();
     ASSERT_OK(c_result) << c_result;
   }
@@ -647,7 +647,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #0 and forward time again, removing record #0
-  ConfirmOrDie(/*seq_number=*/0);
+  ConfirmOrDie(/*sequencing_id=*/0);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -659,7 +659,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #1 and forward time again, removing record #1
-  ConfirmOrDie(/*seq_number=*/1);
+  ConfirmOrDie(/*sequencing_id=*/1);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -685,7 +685,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #2 and forward time again, removing record #2
-  ConfirmOrDie(/*seq_number=*/2);
+  ConfirmOrDie(/*sequencing_id=*/2);
 
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
@@ -718,7 +718,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #0 and forward time again, removing record #0
-  ConfirmOrDie(/*seq_number=*/0);
+  ConfirmOrDie(/*sequencing_id=*/0);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -730,7 +730,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #1 and forward time again, removing record #1
-  ConfirmOrDie(/*seq_number=*/1);
+  ConfirmOrDie(/*sequencing_id=*/1);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -761,7 +761,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #2 and forward time again, removing record #2
-  ConfirmOrDie(/*seq_number=*/2);
+  ConfirmOrDie(/*sequencing_id=*/2);
 
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
@@ -795,7 +795,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #0 and forward time again, removing record #0
-  ConfirmOrDie(/*seq_number=*/0);
+  ConfirmOrDie(/*sequencing_id=*/0);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -807,7 +807,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #1 and forward time again, removing record #1
-  ConfirmOrDie(/*seq_number=*/1);
+  ConfirmOrDie(/*sequencing_id=*/1);
   // Set uploader expectations.
   EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
       .WillOnce(Invoke([](MockUploadClient* mock_upload_client) {
@@ -843,7 +843,7 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
 
   // Confirm #2 and forward time again, removing record #2
-  ConfirmOrDie(/*seq_number=*/2);
+  ConfirmOrDie(/*sequencing_id=*/2);
 
   // Reset simulated failures.
   InjectFailures({});
@@ -924,7 +924,7 @@
   WriteStringOrDie(data[2]);
 
   // Confirm #1, removing data #0 and #1
-  ConfirmOrDie(/*seq_number=*/1);
+  ConfirmOrDie(/*sequencing_id=*/1);
 
   // Add more data and verify that #2 and new data are returned.
   // Upload is initiated asynchronously, so it may happen after the next
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc b/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc
index 4487e2c..989b518 100644
--- a/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc
@@ -205,8 +205,8 @@
   // should have that digest already recorded. Only the first record in a
   // generation is uploaded without last record digest.
   using LastRecordDigestMap = std::map<std::tuple<Priority,
-                                                  uint64_t /*generation id*/,
-                                                  uint64_t /*sequencing id*/>,
+                                                  int64_t /*generation id*/,
+                                                  int64_t /*sequencing id*/>,
                                        std::string /*digest*/>;
 
   explicit MockUploadClient(LastRecordDigestMap* last_record_digest_map,
@@ -249,7 +249,7 @@
   }
 
   void ProcessGap(SequencingInformation start,
-                  uint64_t count,
+                  int64_t count,
                   base::OnceCallback<void(bool)> processed_cb) override {
     LOG(FATAL) << "Gap not implemented yet";
   }
@@ -260,7 +260,7 @@
 
   MOCK_METHOD(bool,
               UploadRecord,
-              (Priority, uint64_t, base::StringPiece),
+              (Priority, int64_t, base::StringPiece),
               (const));
   MOCK_METHOD(bool, UploadRecordFailure, (Status), (const));
   MOCK_METHOD(void, UploadComplete, (bool, Status), (const));
@@ -282,7 +282,7 @@
           .InSequence(client_->test_upload_sequence_);
     }
 
-    SetUp& Required(uint64_t sequencing_id, base::StringPiece value) {
+    SetUp& Required(int64_t sequencing_id, base::StringPiece value) {
       EXPECT_CALL(*client_, UploadRecord(Eq(priority_), Eq(sequencing_id),
                                          StrEq(std::string(value))))
           .InSequence(client_->test_upload_sequence_)
@@ -290,7 +290,7 @@
       return *this;
     }
 
-    SetUp& Possible(uint64_t sequencing_id, base::StringPiece value) {
+    SetUp& Possible(int64_t sequencing_id, base::StringPiece value) {
       EXPECT_CALL(*client_, UploadRecord(Eq(priority_), Eq(sequencing_id),
                                          StrEq(std::string(value))))
           .Times(Between(0, 1))
@@ -404,7 +404,7 @@
                           wrapped_record.record().data()));
   }
 
-  base::Optional<uint64_t> generation_id_;
+  base::Optional<int64_t> generation_id_;
   LastRecordDigestMap* const last_record_digest_map_;
   const scoped_refptr<Decryptor> decryptor_;
 
@@ -508,7 +508,7 @@
     ASSERT_OK(write_result) << write_result;
   }
 
-  void ConfirmOrDie(Priority priority, std::uint64_t sequencing_id) {
+  void ConfirmOrDie(Priority priority, int64_t sequencing_id) {
     TestEvent<Status> c;
     storage_->Confirm(priority, sequencing_id, c.cb());
     const Status c_result = c.result();
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
index 73a281a01..f422a30 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
@@ -107,9 +107,9 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   Status process_status;
 
-  const uint64_t expected_generation_id =
+  const int64_t expected_generation_id =
       encrypted_records_->front().sequencing_information().generation_id();
-  uint64_t expected_sequencing_id =
+  int64_t expected_sequencing_id =
       encrypted_records_->front().sequencing_information().sequencing_id();
 
   // Will stop processing records on the first record that fails to pass.
@@ -151,8 +151,8 @@
 
 Status DmServerUploader::IsRecordValid(
     const EncryptedRecord& encrypted_record,
-    const uint64_t expected_generation_id,
-    const uint64_t expected_sequencing_id) const {
+    const int64_t expected_generation_id,
+    const int64_t expected_sequencing_id) const {
   // Test to ensure all records are in the same generation.
   if (encrypted_record.sequencing_information().generation_id() !=
       expected_generation_id) {
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
index d9d0ffbf..b2765d6 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
@@ -122,8 +122,8 @@
 
     // Helper function for determining if an EncryptedRecord is valid.
     Status IsRecordValid(const EncryptedRecord& encrypted_record,
-                         const uint64_t expected_generation_id,
-                         const uint64_t expected_sequencing_id) const;
+                         const int64_t expected_generation_id,
+                         const int64_t expected_sequencing_id) const;
 
     // Helper function for tracking the highest sequencing information per
     // generation id. Schedules ProcessSuccessfulUploadAddition.
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
index 6ab03779..02b18a800f 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
@@ -202,10 +202,10 @@
 }
 
 TEST_P(DmServerUploaderTest, ProcessesRecords) {
-  uint64_t kNumberOfRecords = 10;
-  uint64_t kGenerationId = 1234;
+  const int64_t kNumberOfRecords = 10;
+  const int64_t kGenerationId = 1234;
 
-  for (uint64_t i = 0; i < kNumberOfRecords; i++) {
+  for (int64_t i = 0; i < kNumberOfRecords; i++) {
     EncryptedRecord encrypted_record;
     encrypted_record.set_encrypted_wrapped_record(
         base::StrCat({"Record Number ", base::NumberToString(i)}));
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
index b6ac897..64af268 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
@@ -347,15 +347,13 @@
   const auto priority = value.FindIntKey("priority");
 
   // If any of the previous values don't exist, or are malformed, return error.
-  // TODO(chromium:1158036) Once SequencingId starts at 1 instead of 0, we
-  // should use 0 as an error value.
-  uint64_t seq_id;
-  uint64_t gen_id;
-  if (!sequencing_id || sequencing_id->empty() ||
-      !base::StringToUint64(*sequencing_id, &seq_id) || !generation_id ||
-      generation_id->empty() ||
-      !base::StringToUint64(*generation_id, &gen_id) || gen_id == 0 ||
-      !priority.has_value() || !Priority_IsValid(priority.value())) {
+  int64_t seq_id;
+  int64_t gen_id;
+  if (!sequencing_id || sequencing_id->empty() || !generation_id ||
+      generation_id->empty() || !priority.has_value() ||
+      !Priority_IsValid(priority.value()) ||
+      !base::StringToInt64(*sequencing_id, &seq_id) ||
+      !base::StringToInt64(*generation_id, &gen_id)) {
     return Status(error::INVALID_ARGUMENT,
                   base::StrCat({"Provided value did not conform to a valid "
                                 "SequencingInformation proto: ",
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
index 4480501..9ad1094 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
@@ -153,9 +153,9 @@
 
   // |seq_info| has been built by RetrieveFinalSequencingInforamation and is
   // guaranteed to have these keys.
-  uint64_t sequencing_id;
-  ASSERT_TRUE(base::StringToUint64(*seq_info.FindStringKey("sequencingId"),
-                                   &sequencing_id));
+  int64_t sequencing_id;
+  ASSERT_TRUE(base::StringToInt64(*seq_info.FindStringKey("sequencingId"),
+                                  &sequencing_id));
   // The lastSucceedUploadedRecord should be the record before the one
   // indicated in seq_info.
   response.SetStringPath("lastSucceedUploadedRecord.sequencingId",
@@ -197,7 +197,7 @@
 
 std::unique_ptr<std::vector<EncryptedRecord>> BuildTestRecordsVector(
     size_t number_of_test_records,
-    uint64_t generation_id) {
+    int64_t generation_id) {
   std::unique_ptr<std::vector<EncryptedRecord>> test_records =
       std::make_unique<std::vector<EncryptedRecord>>();
   test_records->reserve(number_of_test_records);
@@ -217,7 +217,7 @@
 
 TEST_P(RecordHandlerImplTest, ForwardsRecordsToCloudPolicyClient) {
   constexpr size_t kNumTestRecords = 10;
-  constexpr uint64_t kGenerationId = 1234;
+  constexpr int64_t kGenerationId = 1234;
   auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
 
   TestCallbackWaiterWithCounter client_waiter{kNumTestRecords};
@@ -263,9 +263,9 @@
 }
 
 TEST_P(RecordHandlerImplTest, ReportsEarlyFailure) {
-  uint64_t kNumSuccessfulUploads = 5;
-  uint64_t kNumTestRecords = 10;
-  uint64_t kGenerationId = 1234;
+  const int64_t kNumSuccessfulUploads = 5;
+  const int64_t kNumTestRecords = 10;
+  const int64_t kGenerationId = 1234;
   auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
 
   // Wait kNumSuccessfulUploads times + 1 for the failure.
@@ -322,11 +322,11 @@
 }
 
 TEST_P(RecordHandlerImplTest, UploadsGapRecordOnServerFailure) {
-  uint64_t kNumInitialSuccessfulUploads = 5;
-  uint64_t kNumTestRecords = 10;
-  uint64_t kNumFinalSuccessfulUploads =
+  const int64_t kNumInitialSuccessfulUploads = 5;
+  const int64_t kNumTestRecords = 10;
+  const int64_t kNumFinalSuccessfulUploads =
       kNumTestRecords - kNumInitialSuccessfulUploads;
-  uint64_t kGenerationId = 1234;
+  const int64_t kGenerationId = 1234;
   auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
 
   // Wait kNumTestRecords times + 1 for the failure.
@@ -400,7 +400,7 @@
 // report an internal error.
 TEST_P(RecordHandlerImplTest, HandleUnknownResponseFromServer) {
   constexpr size_t kNumTestRecords = 10;
-  constexpr uint64_t kGenerationId = 1234;
+  constexpr int64_t kGenerationId = 1234;
   auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
 
   TestCallbackWaiterWithCounter client_waiter{kNumTestRecords};
diff --git a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc
index 73b880dc..6b0b8e08 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc
@@ -18,12 +18,12 @@
 namespace reporting {
 namespace {
 
-constexpr uint64_t kGenerationId = 4321;
+constexpr int64_t kGenerationId = 4321;
 constexpr Priority kPriority = Priority::IMMEDIATE;
 
 // Default values for EncryptionInfo
 constexpr char kEncryptionKey[] = "abcdef";
-constexpr uint64_t kPublicKeyId = 9876;
+constexpr int64_t kPublicKeyId = 9876;
 
 class RecordUploadRequestBuilderTest : public ::testing::TestWithParam<bool> {
  public:
@@ -48,8 +48,8 @@
     return record;
   }
 
-  static uint64_t GetNextSequencingId() {
-    static uint64_t sequencing_id = 0;
+  static int64_t GetNextSequencingId() {
+    static int64_t sequencing_id = 0;
     return sequencing_id++;
   }
 
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
index 7b415dc..63020d3f 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
@@ -208,7 +208,7 @@
 
 TEST_P(UploadClientTest, CreateUploadClientAndUploadRecords) {
   const int kExpectedCallTimes = 10;
-  const uint64_t kGenerationId = 1234;
+  const int64_t kGenerationId = 1234;
 
   base::Value data{base::Value::Type::DICTIONARY};
   data.SetKey("TEST_KEY", base::Value("TEST_VALUE"));
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index bda1631..613b397 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -465,6 +465,13 @@
     public static final String INCOGNITO_SHORTCUT_ADDED = "incognito-shortcut-added";
 
     /**
+     * The last version the dex compile workaround ran on. See SplitChromeApplication for more
+     * details.
+     */
+    public static final String ISOLATED_SPLITS_DEX_COMPILE_VERSION =
+            "Chrome.IsolatedSplits.DexCompileVersion";
+
+    /**
      * When the user is shown a badge that the current Android OS version is unsupported, and they
      * tap it to display the menu (which has additional information), we store the current version
      * of Chrome to this preference to ensure we only show the badge once. The value is cleared
@@ -851,6 +858,7 @@
                 HOMEPAGE_USE_CHROME_NTP,
                 IMAGE_DESCRIPTIONS_JUST_ONCE_COUNT,
                 IMAGE_DESCRIPTIONS_DONT_ASK_AGAIN,
+                ISOLATED_SPLITS_DEX_COMPILE_VERSION,
                 PERSISTENT_OFFLINE_CONTENT_AVAILABILITY_STATUS,
                 PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD,
                 PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 516be64a..25803f34 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -522,6 +522,10 @@
     "ash.launcher.assistant_privacy_info_dismissed";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+// Deprecated 12/2020
+const char kAssistantQuickAnswersEnabled[] =
+    "settings.voice_interaction.quick_answers.enabled";
+
 // Register local state used only for migration (clearing or moving to a new
 // key).
 void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) {
@@ -618,6 +622,8 @@
   registry->RegisterBooleanPref(kAssistantPrivacyInfoDismissedInLauncher,
                                 false);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+  registry->RegisterBooleanPref(kAssistantQuickAnswersEnabled, true);
 }
 
 }  // namespace
@@ -1271,6 +1277,9 @@
   // Added 12/2020
   profile_prefs->ClearPref(prefs::kWebAppsUserDisplayModeCleanedUp);
 
+  // Added 12/2020
+  profile_prefs->ClearPref(kAssistantQuickAnswersEnabled);
+
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
 }
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index 7cb328a..b12be3e5 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -191,6 +191,7 @@
     "components:oobe_dialog_host_behavior",
     "components/oobe_dialog:oobe_dialog",
     "components/oobe_i18n_behavior:oobe_i18n_behavior",
+    "//ui/login:login_ui_tools",
   ]
 }
 
@@ -367,6 +368,7 @@
     "components:oobe_modal_dialog",
     "components/oobe_dialog:oobe_dialog",
     "components/oobe_i18n_behavior:oobe_i18n_behavior",
+    "//ui/login:login_ui_tools",
   ]
 }
 
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_dialog_host_behavior.js b/chrome/browser/resources/chromeos/login/components/oobe_dialog_host_behavior.js
index 3e9174d32..1f784570 100644
--- a/chrome/browser/resources/chromeos/login/components/oobe_dialog_host_behavior.js
+++ b/chrome/browser/resources/chromeos/login/components/oobe_dialog_host_behavior.js
@@ -18,7 +18,7 @@
    */
   propagateOnBeforeShow(selector) {
     if (!selector)
-      selector = 'oobe-dialog';
+      selector = 'oobe-dialog,oobe-adaptive-dialog';
 
     var screens = Polymer.dom(this.root).querySelectorAll(selector);
     for (var i = 0; i < screens.length; ++i) {
@@ -45,17 +45,6 @@
     }
   },
 
-  addSubmitListener(element, id) {
-    element.addEventListener('keydown', (function(id, e) {
-                                          if (e.keyCode != 13)
-                                            return;
-                                          this.onFieldSubmit(id);
-                                        }).bind(this, id));
-  },
-
-  onFieldSubmit(id) {
-    console.error('Override this method in your element.');
-  },
 };
 
 /**
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.js b/chrome/browser/resources/chromeos/login/gaia_password_changed.js
index 403cd06..9375282 100644
--- a/chrome/browser/resources/chromeos/login/gaia_password_changed.js
+++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.js
@@ -58,7 +58,8 @@
       resetAllowed: false,
     });
 
-    this.addSubmitListener(this.$.oldPasswordInput, 'password');
+    cr.ui.LoginUITools.addSubmitListener(
+        this.$.oldPasswordInput, this.submit_.bind(this));
   },
 
   /** Initial UI State for screen */
@@ -91,10 +92,6 @@
     chrome.send('migrateUserData', [this.$.oldPasswordInput.value]);
   },
 
-  onFieldSubmit(id) {
-    this.submit_();
-  },
-
   /** @private */
   onForgotPasswordClicked_() {
     this.setUIStep(UIState.FORGOT);
diff --git a/chrome/browser/resources/chromeos/login/gesture_navigation.css b/chrome/browser/resources/chromeos/login/gesture_navigation.css
deleted file mode 100644
index 6d34a45..0000000
--- a/chrome/browser/resources/chromeos/login/gesture_navigation.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2020 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.gesture-animation {
-  height: 300px;
-  margin-top: -75px;
-  position: absolute;
-  width: 300px;
-}
-
-.gesture-animation-container {
-  height: 225px;
-  overflow: hidden;
-  position: relative;
-  top: 50%;
-  transform: translate(0, -50%);
-  width: 300px;
-}
-
-.gesture-list-item {
-  display: flex;
-  height: 46px;
-  padding-bottom: 4px;
-}
-
-.gesture-list-item-icon {
-  align-self: flex-start;
-  height: 24px;
-  margin: auto;
-  width: 24px;
-}
-
-.gesture-list-item-text {
-  flex: 1 1 auto;
-  margin: auto;
-  padding-inline-start: 16px;
-}
diff --git a/chrome/browser/resources/chromeos/login/gesture_navigation.html b/chrome/browser/resources/chromeos/login/gesture_navigation.html
index 3ee4c05..753c85c 100644
--- a/chrome/browser/resources/chromeos/login/gesture_navigation.html
+++ b/chrome/browser/resources/chromeos/login/gesture_navigation.html
@@ -12,11 +12,39 @@
 
 <dom-module id="gesture-navigation-element">
   <template>
-    <style include="oobe-common"></style>
-    <link rel="stylesheet" href="gesture_navigation.css">
+    <style include="oobe-common">
+      .gesture-animation {
+        height: 300px;
+        width: 300px;
+      }
 
-    <oobe-dialog id="gestureIntro" has-buttons class="step hidden"
-        hidden="[[!isEqual_(currentPage_, 'gestureIntro')]]"
+      .gesture-animation-container {
+        height: 300px;
+        margin-top: -22px;
+        overflow: hidden;
+        width: 300px;
+      }
+
+      .gesture-list-item {
+        display: flex;
+        height: 46px;
+        padding-bottom: 4px;
+      }
+
+      .gesture-list-item-icon {
+        align-self: flex-start;
+        height: 24px;
+        margin: auto;
+        width: 24px;
+      }
+
+      .gesture-list-item-text {
+        flex: 1 1 auto;
+        margin: auto;
+        padding-inline-start: 16px;
+      }
+    </style>
+    <oobe-dialog id="gestureIntro" has-buttons for-step="gestureIntro"
         title-key="gestureNavigationIntroTitle"
         aria-label$="[[i18nDynamic(locale, 'gestureNavigationIntroTitle')]]">
       <img slot="oobe-icon" src="images/gestures.svg" width="32" height="32">
@@ -48,8 +76,7 @@
       </div>
     </oobe-dialog>
 
-    <oobe-dialog id="gestureHome" has-buttons  class="step hidden"
-        hidden="[[!isEqual_(currentPage_, 'gestureHome')]]"
+    <oobe-dialog id="gestureHome" has-buttons for-step="gestureHome"
         title-key="gestureNavigationHomeTitle"
         subtitle-key="gestureNavigationHomeDescription"
         aria-label$="[[i18nDynamic(locale, 'gestureNavigationHomeTitle')]]">
@@ -71,8 +98,7 @@
       </div>
     </oobe-dialog>
 
-    <oobe-dialog id="gestureOverview" has-buttons class="step hidden"
-        hidden="[[!isEqual_(currentPage_, 'gestureOverview')]]"
+    <oobe-dialog id="gestureOverview" has-buttons for-step="gestureOverview"
         title-key="gestureNavigationOverviewTitle"
         subtitle-key="gestureNavigationOverviewDescription"
         aria-label$="[[i18nDynamic(locale, 'gestureNavigationOverviewTitle')]]">
@@ -94,8 +120,7 @@
       </div>
     </oobe-dialog>
 
-    <oobe-dialog id="gestureBack" has-buttons class="step hidden"
-        hidden="[[!isEqual_(currentPage_, 'gestureBack')]]"
+    <oobe-dialog id="gestureBack" has-buttons for-step="gestureBack"
         title-key="gestureNavigationBackTitle"
         subtitle-key="gestureNavigationBackDescription"
         aria-label$="[[i18nDynamic(locale, 'gestureNavigationBackTitle')]]">
diff --git a/chrome/browser/resources/chromeos/login/gesture_navigation.js b/chrome/browser/resources/chromeos/login/gesture_navigation.js
index e8614e4e..21c2811 100644
--- a/chrome/browser/resources/chromeos/login/gesture_navigation.js
+++ b/chrome/browser/resources/chromeos/login/gesture_navigation.js
@@ -18,11 +18,12 @@
 Polymer({
   is: 'gesture-navigation-element',
 
-  behaviors: [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
+  behaviors: [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior],
 
-  properties: {
-    /** @private */
-    currentPage_: {type: String, value: GesturePage.INTRO},
+  UI_STEPS: GesturePage,
+
+  defaultUIStep() {
+    return GesturePage.INTRO;
   },
 
   /** @override */
@@ -34,26 +35,12 @@
   },
 
   /**
-   * Called before the screen is shown.
-   */
-  onBeforeShow() {
-    this.currentPage_ = GesturePage.INTRO;
-  },
-
-  focus() {
-    let current = this.$[this.currentPage_];
-    if (current) {
-      current.show();
-    }
-  },
-
-  /**
    * This is the 'on-tap' event handler for the 'next' or 'get started' button.
    * @private
    *
    */
   onNext_() {
-    switch (this.currentPage_) {
+    switch (this.uiStep) {
       case GesturePage.INTRO:
         this.setCurrentPage_(GesturePage.HOME);
         break;
@@ -78,7 +65,7 @@
    * @private
    */
   onBack_() {
-    switch (this.currentPage_) {
+    switch (this.uiStep) {
       case GesturePage.HOME:
         this.setCurrentPage_(GesturePage.INTRO);
         break;
@@ -99,21 +86,9 @@
    */
   setCurrentPage_(newPage) {
     this.setPlayCurrentScreenAnimation(false);
-    this.currentPage_ = newPage;
+    this.setUIStep(newPage);
     chrome.send('handleGesturePageChange', [newPage]);
     this.setPlayCurrentScreenAnimation(true);
-
-    let screen = this.$[this.currentPage_];
-    assert(screen);
-    screen.show();
-  },
-
-  /**
-   * Comparison function for the current page.
-   * @private
-   */
-  isEqual_(currentPage_, page_) {
-    return currentPage_ == page_;
   },
 
   /**
@@ -122,8 +97,7 @@
    * @private
    */
   setPlayCurrentScreenAnimation(enabled) {
-    var animation =
-        this.$[this.currentPage_].querySelector('.gesture-animation');
+    var animation = this.$[this.uiStep].querySelector('.gesture-animation');
     if (animation) {
       animation.setPlay(enabled);
     }
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.js b/chrome/browser/resources/chromeos/login/saml_confirm_password.js
index 153a1c0..249b13a1 100644
--- a/chrome/browser/resources/chromeos/login/saml_confirm_password.js
+++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.js
@@ -52,8 +52,11 @@
     this.initializeLoginScreen('ConfirmSamlPasswordScreen', {
       resetAllowed: true,
     });
-    this.addSubmitListener(this.$.passwordInput, 'password');
-    this.addSubmitListener(this.$.confirmPasswordInput, 'confirm');
+
+    cr.ui.LoginUITools.addSubmitListener(
+        this.$.passwordInput, this.submit_.bind(this));
+    cr.ui.LoginUITools.addSubmitListener(
+        this.$.confirmPasswordInput, this.submit_.bind(this));
   },
 
   /** Initial UI State for screen */
@@ -128,10 +131,6 @@
     this.reset();
   },
 
-  onFieldSubmit(id) {
-    this.submit_();
-  },
-
   onDialogOverlayClosed_() {
     this.disabled = false;
   },
diff --git a/chrome/browser/resources/discards/discards_tab.html b/chrome/browser/resources/discards/discards_tab.html
index c4d1e255..21dc8d85 100644
--- a/chrome/browser/resources/discards/discards_tab.html
+++ b/chrome/browser/resources/discards/discards_tab.html
@@ -26,6 +26,12 @@
         white-space: nowrap;
       }
 
+      @media (prefers-color-scheme: dark) {
+        table th {
+          background: var(--google-grey-800);
+        }
+      }
+
       table th[data-sort-key] {
         cursor: pointer;
       }
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html
index e25a4ff..e31e6b1 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -27,7 +27,7 @@
           <cr-link-row class="first" hidden="[[!pageVisibility.setTheme]]"
               label="$i18n{themes}" sub-label="[[themeSublabel_]]"
               on-click="openThemeUrl_" external></cr-link-row>
-<if expr="not is_linux or chromeos">
+<if expr="not is_linux or chromeos or lacros">
           <template is="dom-if" if="[[prefs.extensions.theme.id.value]]">
             <div class="separator"></div>
             <cr-button id="useDefault" on-click="onUseDefaultTap_">
@@ -35,7 +35,7 @@
             </cr-button>
           </template>
 </if>
-<if expr="is_linux and not chromeos">
+<if expr="is_linux and not chromeos and not lacros">
           <div class="settings-row continuation"
               hidden="[[!showThemesSecondary_(
                   prefs.extensions.theme.id.value, useSystemTheme_)]]"
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chrome/browser/resources/settings/appearance_page/appearance_page.js
index e6fd3a0..084ad3a9 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -299,10 +299,10 @@
     }
 
     let i18nId;
-    // <if expr="is_linux and not chromeos">
+    // <if expr="is_linux and not chromeos and not lacros">
     i18nId = useSystemTheme ? 'systemTheme' : 'classicTheme';
     // </if>
-    // <if expr="not is_linux or chromeos">
+    // <if expr="not is_linux or chromeos or lacros">
     i18nId = 'chooseFromWebStore';
     // </if>
     this.themeSublabel_ = this.i18n(i18nId);
diff --git a/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.js b/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.js
index e8b3148..b8a59df 100644
--- a/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.js
+++ b/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.js
@@ -33,6 +33,11 @@
     accountEmail: String,
   },
 
+  /** @return {boolean} Whether the user confirmed the dialog. */
+  wasConfirmed() {
+    return this.$.dialog.getNative().returnValue === 'success';
+  },
+
   /** @override */
   attached() {
     chrome.metricsPrivate.recordEnumerationValue(
@@ -60,6 +65,6 @@
 
   /** @private */
   onCancelButtonClick_() {
-    this.$.dialog.close();
+    this.$.dialog.cancel();
   },
 });
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_device_section.html b/chrome/browser/resources/settings/autofill_page/passwords_device_section.html
index 9d28bc78..a57cf75a 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_device_section.html
+++ b/chrome/browser/resources/settings/autofill_page/passwords_device_section.html
@@ -95,6 +95,9 @@
   </div>
   <cr-icon-button iron-icon="cr:open-in-new"></cr-icon-button>
 </div>
+<cr-toast id="toast" duration="5000">
+  <div>$i18nRaw{devicePasswordsMoved}</div>
+</cr-toast>
 <template is="dom-if" if="[[showMoveMultiplePasswordsDialog_]]" restamp>
   <password-move-multiple-passwords-to-account-dialog
       passwords-to-move="[[allDevicePasswords_]]"
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_device_section.js b/chrome/browser/resources/settings/autofill_page/passwords_device_section.js
index 4b18c21..dd9356b 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_device_section.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_device_section.js
@@ -18,6 +18,7 @@
 import './passwords_shared_css.js';
 import './password_list_item.js';
 import './password_move_multiple_passwords_to_account_dialog.js';
+import 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 
@@ -366,6 +367,10 @@
 
   /** @private */
   onMoveMultiplePasswordsDialogClose_() {
+    if ((this.$$('password-move-multiple-passwords-to-account-dialog'))
+            .wasConfirmed()) {
+      this.$.toast.show();
+    }
     this.showMoveMultiplePasswordsDialog_ = false;
   },
 
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chrome/browser/resources/settings/autofill_page/passwords_section.html
index 6bbb244..39174529 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.html
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -74,6 +74,9 @@
         padding-top: 11px;
         width: 22px;
       }
+      #devicePasswordsLinkLabel {
+        flex-grow: 1;
+      }
    </style>
     <settings-toggle-button id="passwordToggle"
         aria-label="$i18n{passwords}" no-extension-indicator
@@ -198,13 +201,8 @@
               on-click="onDevicePasswordsLinkClicked_">
             <iron-icon id="devicePasswordsLinkIcon" icon="cr:computer">
             </iron-icon>
-            <div>
-              <div id="devicePasswordsLinkLabel">
-                [[devicePasswordsLinkLabel_]]
-              </div>
-              <div class="cr-secondary-text">
-                $i18n{devicePasswordsLinkSubLabel}
-              </div>
+            <div id="devicePasswordsLinkLabel">
+                $i18n{devicePasswordsLinkLabel}
             </div>
             <cr-icon-button iron-icon="cr:arrow-right"
                 aria-roledescription="$i18n{subpageArrowRoleDescription}">
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js
index 57d731a..40e3bcb 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -229,13 +229,6 @@
     },
 
     /** @private */
-    devicePasswordsLinkLabel_: {
-      type: String,
-      value: '',
-      computed: 'computeDevicePasswordsLinkLabel_(numberOfDevicePasswords_)',
-    },
-
-    /** @private */
     profileEmail_: {
       type: String,
       value: '',
@@ -466,17 +459,6 @@
   },
 
   /**
-   * @private
-   * @return {string}
-   */
-  computeDevicePasswordsLinkLabel_() {
-    return this.numberOfDevicePasswords_ === 1 ?
-        this.i18n('devicePasswordsLinkLabelSingular') :
-        this.i18n(
-            'devicePasswordsLinkLabelPlural', this.numberOfDevicePasswords_);
-  },
-
-  /**
    * Shows the check passwords sub page.
    * @private
    */
diff --git a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
index 20f3064..b509d5d 100644
--- a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
@@ -33,14 +33,6 @@
       cr-policy-pref-indicator {
         margin-inline-end: var(--cr-controlled-by-spacing);
       }
-
-      #quick-answers-container {
-        padding-inline-end: 0;
-      }
-
-      #quick-answers-container settings-toggle-button {
-        padding-inline-start: 0;
-      }
     </style>
     <settings-toggle-button id="google-assistant-enable"
         class="primary-toggle"
@@ -59,18 +51,6 @@
           sub-label="$i18n{googleAssistantEnableContextDescription}"
           deep-link-focus-id$="[[Setting.kAssistantRelatedInfo]]">
       </settings-toggle-button>
-      <template is="dom-if" if="[[quickAnswersAvailable_]]">
-        <div class="settings-box continuation embedded"
-             id="quick-answers-container">
-          <settings-toggle-button class="start"
-              id="google-assistant-quick-answers-enable"
-              pref="{{prefs.settings.voice_interaction.quick_answers.enabled}}"
-              label="$i18n{googleAssistantEnableQuickAnswers}"
-              sub-label="$i18n{googleAssistantEnableQuickAnswersDescription}"
-              deep-link-focus-id$="[[Setting.kAssistantQuickAnswers]]">
-          </settings-toggle-button>
-        </div>
-      </template>
       <template is="dom-if" if="[[hotwordDspAvailable_]]" restamp>
         <settings-toggle-button id="google-assistant-hotword-enable"
             class="hr"
diff --git a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
index a588aaf2..372b8d17 100644
--- a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
@@ -94,12 +94,6 @@
     /** @private {DspHotwordState} */
     dspHotwordState_: Number,
 
-    /** @private */
-    quickAnswersAvailable_: {
-      type: Boolean,
-      value: false,
-    },
-
     /**
      * Used by DeepLinkingBehavior to focus this page's deep links.
      * @type {!Set<!chromeos.settings.mojom.Setting>}
@@ -109,7 +103,6 @@
       value: () => new Set([
         chromeos.settings.mojom.Setting.kAssistantOnOff,
         chromeos.settings.mojom.Setting.kAssistantRelatedInfo,
-        chromeos.settings.mojom.Setting.kAssistantQuickAnswers,
         chromeos.settings.mojom.Setting.kAssistantOkGoogle,
         chromeos.settings.mojom.Setting.kAssistantNotifications,
         chromeos.settings.mojom.Setting.kAssistantVoiceInput,
@@ -124,8 +117,7 @@
         'prefs.settings.voice_interaction.hotword.always_on.value, ' +
         'prefs.settings.voice_interaction.activity_control.consent_status' +
         '.value, ' +
-        'prefs.settings.assistant.disabled_by_policy.value, ' +
-        'prefs.settings.voice_interaction.context.enabled.value)',
+        'prefs.settings.assistant.disabled_by_policy.value)',
   ],
 
   /** @private {?settings.GoogleAssistantBrowserProxy} */
@@ -238,10 +230,6 @@
 
     this.hotwordEnforced_ = hotwordEnabled.enforcement ===
         chrome.settingsPrivate.Enforcement.ENFORCED;
-
-    this.quickAnswersAvailable_ =
-        loadTimeData.getBoolean('quickAnswersAvailable') &&
-        !!this.getPref('settings.voice_interaction.context.enabled').value;
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
index 0cf9769..41a5a46 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
@@ -15,6 +15,11 @@
 <dom-module id="settings-multidevice-notification-access-setup-dialog">
   <template>
     <style include="cr-shared-style settings-shared">
+      :host {
+        --cr-dialog-font-family: 'Google Sans';
+        --cr-dialog-title-font-size: 16px;
+      }
+
       cr-dialog::part(dialog) {
         width: 512px;
       }
@@ -30,7 +35,6 @@
         flex-direction: column;
         height: auto;
         justify-content: center;
-        margin-bottom: 16px;
         width: 464px;
       }
 
@@ -45,6 +49,16 @@
         gap: 12px;
       }
 
+      :host(:not([did-setup-attempt-fail_])) #description {
+        /* Larger height to account for the lack of #failureIcon */
+        height: 93px;
+      }
+
+      :host([did-setup-attempt-fail_]) #description {
+        /* Smaller height to account for the presence of #failureIcon */
+        height: 60px;
+      }
+
       #illustration {
         background-position: center center;
         background-repeat: no-repeat;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h
index 0109ab8..fef3ee91 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h
@@ -49,8 +49,10 @@
 
   const std::vector<base::FilePath>& created_file_paths() const;
 
- private:
+ protected:
   base::test::ScopedFeatureList scoped_feature_list_;
+
+ private:
   base::RepeatingClosure quit_closure_;
   enterprise_connectors::ContentAnalysisResponse
       connector_status_callback_response_;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
index faf17c7e..e85bf92 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h"
+#include "components/policy/core/common/policy_types.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "content/public/browser/browser_context.h"
@@ -343,16 +344,22 @@
 
 void SetAnalysisConnector(PrefService* prefs,
                           enterprise_connectors::AnalysisConnector connector,
-                          const std::string& pref_value) {
+                          const std::string& pref_value,
+                          bool machine_scope) {
   ListPrefUpdate settings_list(prefs, ConnectorPref(connector));
   DCHECK(settings_list.Get());
   if (!settings_list->empty())
     settings_list->Clear();
 
   settings_list->Append(*base::JSONReader::Read(pref_value));
+  prefs->SetInteger(
+      ConnectorScopePref(connector),
+      machine_scope ? policy::POLICY_SCOPE_MACHINE : policy::POLICY_SCOPE_USER);
 }
 
-void SetOnSecurityEventReporting(PrefService* prefs, bool enabled) {
+void SetOnSecurityEventReporting(PrefService* prefs,
+                                 bool enabled,
+                                 bool machine_scope) {
   ListPrefUpdate settings_list(prefs,
                                enterprise_connectors::kOnSecurityEventPref);
   DCHECK(settings_list.Get());
@@ -364,18 +371,22 @@
                       base::Value("google"));
       settings_list->Append(std::move(settings));
     }
+    prefs->SetInteger(enterprise_connectors::kOnSecurityEventScopePref,
+                      machine_scope ? policy::POLICY_SCOPE_MACHINE
+                                    : policy::POLICY_SCOPE_USER);
   } else {
     settings_list->ClearList();
+    prefs->ClearPref(enterprise_connectors::kOnSecurityEventScopePref);
   }
 }
 
 void ClearAnalysisConnector(
     PrefService* prefs,
-
     enterprise_connectors::AnalysisConnector connector) {
   ListPrefUpdate settings_list(prefs, ConnectorPref(connector));
   DCHECK(settings_list.Get());
   settings_list->Clear();
+  prefs->ClearPref(ConnectorScopePref(connector));
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
index 7fd6b00..84dac14 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
@@ -148,8 +148,11 @@
 // Helper functions that set Connector policies for testing.
 void SetAnalysisConnector(PrefService* prefs,
                           enterprise_connectors::AnalysisConnector connector,
-                          const std::string& pref_value);
-void SetOnSecurityEventReporting(PrefService* prefs, bool enabled);
+                          const std::string& pref_value,
+                          bool machine_scope = true);
+void SetOnSecurityEventReporting(PrefService* prefs,
+                                 bool enabled,
+                                 bool machine_scope = true);
 void ClearAnalysisConnector(PrefService* prefs,
                             enterprise_connectors::AnalysisConnector connector);
 
diff --git a/chrome/browser/search/ntp_icon_source.cc b/chrome/browser/search/ntp_icon_source.cc
index 5ad480b..15911d63 100644
--- a/chrome/browser/search/ntp_icon_source.cc
+++ b/chrome/browser/search/ntp_icon_source.cc
@@ -164,7 +164,7 @@
 void DrawFavicon(const SkBitmap& bitmap, gfx::Canvas* canvas, int size) {
   int x_origin = (size - bitmap.width()) / 2;
   int y_origin = (size - bitmap.height()) / 2;
-  canvas->DrawImageInt(gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, /*scale=*/1.0)),
+  canvas->DrawImageInt(gfx::ImageSkia::CreateFromBitmap(bitmap, /*scale=*/1.f),
                        x_origin, y_origin);
 }
 
diff --git a/chrome/browser/sync/session_sync_service_factory.cc b/chrome/browser/sync/session_sync_service_factory.cc
index 846bae7c..7cd8bfd 100644
--- a/chrome/browser/sync/session_sync_service_factory.cc
+++ b/chrome/browser/sync/session_sync_service_factory.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/device_info_sync_service_factory.h"
 #include "chrome/browser/sync/glue/sync_start_util.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
 #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router.h"
@@ -20,6 +21,8 @@
 #include "components/history/core/browser/history_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/sync/model/model_type_store_service.h"
+#include "components/sync_device_info/device_info_sync_service.h"
+#include "components/sync_device_info/device_info_tracker.h"
 #include "components/sync_sessions/session_sync_prefs.h"
 #include "components/sync_sessions/session_sync_service_impl.h"
 #include "components/sync_sessions/sync_sessions_client.h"
@@ -84,6 +87,12 @@
     return ShouldSyncURLImpl(url);
   }
 
+  bool IsRecentLocalCacheGuid(const std::string& cache_guid) const override {
+    return DeviceInfoSyncServiceFactory::GetForProfile(profile_)
+        ->GetDeviceInfoTracker()
+        ->IsRecentLocalCacheGuid(cache_guid);
+  }
+
   sync_sessions::SyncedWindowDelegatesGetter* GetSyncedWindowDelegatesGetter()
       override {
     return window_delegates_getter_.get();
diff --git a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
index fd1179ef1..ffa44a8 100644
--- a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
+++ b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/navigation_metrics_recorder.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 21c47fe7..a41587d 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -780,6 +780,12 @@
       <message name="IDS_CONTEXTUAL_SEARCH_NO_THANKS_BUTTON" desc="A button to confirm and dismiss opt out promo">
         No thanks
       </message>
+      <message name="IDS_CONTEXTUAL_SEARCH_HELP_BODY" desc="Some help text that is shown in the body of a paragraph. The text tells the user what gesture to use instead of a previous gesture in order to search.">
+        To search for a word or phrase, touch and hold it instead of tapping it
+      </message>
+      <message name="IDS_CONTEXTUAL_SEARCH_HELP_HEADER" desc="Summary help text that is shown at the top of a paragraph. The text tells the user what gesture to use in order to search.">
+        Touch &amp; hold to search
+      </message>
       <message name="IDS_DO_NOT_TRACK_TITLE" desc="Title for 'Do Not Track' preference">
         “Do Not Track”
       </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_BODY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_BODY.png.sha1
new file mode 100644
index 0000000..6c99f38
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_BODY.png.sha1
@@ -0,0 +1 @@
+a14031cb166d1bb00a3afa1537ebc45e5a62a57e
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_HEADER.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_HEADER.png.sha1
new file mode 100644
index 0000000..86501c4c
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SEARCH_HELP_HEADER.png.sha1
@@ -0,0 +1 @@
+2039c6a096954ab0c097e4604c5946bbb70aac3a
\ No newline at end of file
diff --git a/chrome/browser/ui/app_list/icon_standardizer_unittest.cc b/chrome/browser/ui/app_list/icon_standardizer_unittest.cc
index 3c3b41bf..81ba60b 100644
--- a/chrome/browser/ui/app_list/icon_standardizer_unittest.cc
+++ b/chrome/browser/ui/app_list/icon_standardizer_unittest.cc
@@ -87,7 +87,7 @@
 
   // Get the standard icon version of the red circle icon.
   gfx::ImageSkia generated_standard_icon = app_list::CreateStandardIconImage(
-      gfx::ImageSkia(gfx::ImageSkiaRep(circle_icon_bitmap, 2.0f)));
+      gfx::ImageSkia::CreateFromBitmap(circle_icon_bitmap, 2.0f));
 
   // Scale the bitmap to fit the size of a standardized circle icon.
   SkBitmap scaled_bitmap = skia::ImageOperations::Resize(
@@ -123,7 +123,7 @@
 
   // Get the standard icon version of the red circle icon.
   gfx::ImageSkia standard_icon = app_list::CreateStandardIconImage(
-      gfx::ImageSkia(gfx::ImageSkiaRep(circle_icon_bitmap, 2.0f)));
+      gfx::ImageSkia::CreateFromBitmap(circle_icon_bitmap, 2.0f));
 
   EXPECT_TRUE(AreBitmapsEqual(*standard_icon.bitmap(), circle_icon_bitmap));
 }
diff --git a/chrome/browser/ui/app_list/md_icon_normalizer.cc b/chrome/browser/ui/app_list/md_icon_normalizer.cc
index 9e05674..4fccbf7 100644
--- a/chrome/browser/ui/app_list/md_icon_normalizer.cc
+++ b/chrome/browser/ui/app_list/md_icon_normalizer.cc
@@ -219,8 +219,8 @@
   }
 
   // Add padding.
-  gfx::Canvas canvas(required_size, 1, /* transparent */ false);
-  canvas.DrawImageInt(gfx::ImageSkia(gfx::ImageSkiaRep(resized, 1)),
+  gfx::Canvas canvas(required_size, 1, /*transparent=*/false);
+  canvas.DrawImageInt(gfx::ImageSkia::CreateFromBitmap(resized, 1),
                       padding.width(), padding.height());
   *bitmap_out = canvas.GetBitmap();
   return;
diff --git a/chrome/browser/ui/app_list/search/common/url_icon_source.cc b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
index f53e79a..c179b87 100644
--- a/chrome/browser/ui/app_list/search/common/url_icon_source.cc
+++ b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
@@ -100,7 +100,7 @@
 
 void UrlIconSource::OnImageDecoded(const SkBitmap& decoded_image) {
   const float scale = decoded_image.width() / icon_size_;
-  icon_ = gfx::ImageSkia(gfx::ImageSkiaRep(decoded_image, scale));
+  icon_ = gfx::ImageSkia::CreateFromBitmap(decoded_image, scale);
   icon_loaded_callback_.Run();
 }
 
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index 6219f403..331ca503 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -660,8 +660,7 @@
 
   if (web_app::SystemWebAppManager::IsAppEnabled(
           web_app::SystemAppType::CAMERA)) {
-    ChromeCameraAppUIDelegate::CameraAppDialog::ShowIntent(
-        queries, arc::GetArcWindow(task_id));
+    ChromeCameraAppUIDelegate::ShowIntent(queries, arc::GetArcWindow(task_id));
     return;
   }
 
diff --git a/chrome/browser/ui/views/elevation_icon_setter.cc b/chrome/browser/ui/views/elevation_icon_setter.cc
index b7f99b6..46fb192 100644
--- a/chrome/browser/ui/views/elevation_icon_setter.cc
+++ b/chrome/browser/ui/views/elevation_icon_setter.cc
@@ -77,7 +77,7 @@
 #endif
     button_->SetImage(
         views::Button::STATE_NORMAL,
-        gfx::ImageSkia(gfx::ImageSkiaRep(icon, device_scale_factor)));
+        gfx::ImageSkia::CreateFromBitmap(icon, device_scale_factor));
     button_->SizeToPreferredSize();
     if (button_->parent())
       button_->parent()->Layout();
diff --git a/chrome/browser/ui/views/global_media_controls/media_notification_container_impl_view.cc b/chrome/browser/ui/views/global_media_controls/media_notification_container_impl_view.cc
index 708ef29d..82756a7 100644
--- a/chrome/browser/ui/views/global_media_controls/media_notification_container_impl_view.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_notification_container_impl_view.cc
@@ -264,7 +264,7 @@
                         true /* is_pixel_canvas */)
           .context(),
       GetPreferredSize()));
-  gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, 1.f));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(bitmap, 1.f);
   image_view->SetImage(image);
 
   drag_image_widget_->Show();
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
index aaec79d..8a3aad62 100644
--- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
+++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
@@ -71,7 +71,7 @@
   bitmap.allocN32Pixels(kQRImageSizePx, kQRImageSizePx);
   bitmap.eraseARGB(0xFF, 0xFF, 0xFF, 0xFF);
   bitmap.eraseColor(color);
-  return gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, 1.0f));
+  return gfx::ImageSkia::CreateFromBitmap(bitmap, 1.0f);
 }
 
 // Adds a new small vertical padding row to the current bottom of |layout|.
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
index d41e8c40..2ac15dc8 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
@@ -30,7 +30,7 @@
   }
   // All status icon implementations want the image in pixel coordinates, so use
   // a scale factor of 1.
-  return gfx::ImageSkia(gfx::ImageSkiaRep(best_rep, 1.0f));
+  return gfx::ImageSkia::CreateFromBitmap(best_rep, 1.0f);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/tab_icon_view.cc b/chrome/browser/ui/views/tab_icon_view.cc
index dfe1128..6d71e986 100644
--- a/chrome/browser/ui/views/tab_icon_view.cc
+++ b/chrome/browser/ui/views/tab_icon_view.cc
@@ -36,8 +36,8 @@
 #if defined(OS_WIN)
   // The default window icon is the application icon, not the default favicon.
   HICON app_icon = GetAppIcon();
-  icon = gfx::ImageSkia(gfx::ImageSkiaRep(
-      IconUtil::CreateSkBitmapFromHICON(app_icon, gfx::Size(16, 16)), 1.0f));
+  icon = gfx::ImageSkia::CreateFromBitmap(
+      IconUtil::CreateSkBitmapFromHICON(app_icon, gfx::Size(16, 16)), 1.0f);
   DestroyIcon(app_icon);
 #else
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
index 905c2b8d..f4c8bd92 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -15,11 +15,13 @@
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_menu_model.h"
+#include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -43,7 +45,9 @@
     "assert_install_icon_not_shown",
     "navigate_installable,install_omnibox_or_menu,launch_internal,"
     "uninstall_internal,navigate_browser_in_scope,"
-    "assert_install_icon_shown,assert_launch_icon_not_shown"};
+    "assert_install_icon_shown,assert_launch_icon_not_shown",
+    "navigate_installable, install_create_shortcut_tabbed, "
+    "set_open_in_window_internal, launch_internal, assert_window_created"};
 #else
     "navigate_installable,assert_install_icon_shown,"
     "assert_launch_icon_not_shown",
@@ -53,7 +57,9 @@
     "assert_install_icon_not_shown",
     "navigate_installable,install_omnibox_or_menu,launch_internal,"
     "uninstall_from_menu,navigate_browser_in_scope,"
-    "assert_install_icon_shown,assert_launch_icon_not_shown"};
+    "assert_install_icon_shown,assert_launch_icon_not_shown",
+    "navigate_installable, install_create_shortcut_tabbed, "
+    "set_open_in_window_internal, launch_internal, assert_window_created"};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // anonymous namespace
@@ -128,6 +134,10 @@
       UninstallFromMenu();
     } else if (action_string == "uninstall_internal") {
       UninstallInternal();
+    } else if (action_string == "install_create_shortcut_tabbed") {
+      InstallCreateShortcutTabbed();
+    } else if (action_string == "set_open_in_window_internal") {
+      SetOpenInWindowInternal();
     } else if (action_string == "assert_installable") {
       AssertInstallable();
     } else if (action_string == "assert_install_icon_shown") {
@@ -138,6 +148,8 @@
       AssertLaunchIconShown();
     } else if (action_string == "assert_launch_icon_not_shown") {
       AssertLaunchIconNotShown();
+    } else if (action_string == "assert_window_created") {
+      AssertWindowCreated();
     } else {
       FAIL() << "Unimplemented action: " << action_string;
     }
@@ -246,6 +258,22 @@
     run_loop.Run();
   }
 
+  void InstallCreateShortcutTabbed() {
+    chrome::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true,
+                                                /*auto_open_in_window=*/false);
+    WebAppInstallObserver observer(browser()->profile());
+    CHECK(chrome::ExecuteCommand(browser(), IDC_CREATE_SHORTCUT));
+    app_id_ = observer.AwaitNextInstall();
+    chrome::SetAutoAcceptWebAppDialogForTesting(false, false);
+  }
+
+  void SetOpenInWindowInternal() {
+    auto& app_registry_controller =
+        WebAppProvider::Get(browser()->profile())->registry_controller();
+    app_registry_controller.SetAppUserDisplayMode(
+        app_id_, blink::mojom::DisplayMode::kStandalone, true);
+  }
+
   // Assert Actions
   void AssertInstallable() { EXPECT_TRUE(last_navigation_result_.installable); }
   void AssertInstallIconShown() {
@@ -265,6 +293,8 @@
               kNotPresent);
   }
 
+  void AssertWindowCreated() { EXPECT_TRUE(app_browser_); }
+
   Browser* app_browser() { return app_browser_; }
   std::vector<std::string>& testing_actions() { return testing_actions_; }
   PageActionIconView* pwa_install_view() { return pwa_install_view_; }
diff --git a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
index bbb2f28..34e4f2b 100644
--- a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
+++ b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
@@ -118,19 +118,22 @@
       sheet_view = std::make_unique<AuthenticatorClientPinEntrySheetView>(
           std::make_unique<AuthenticatorClientPinEntrySheetModel>(
               dialog_model,
-              AuthenticatorClientPinEntrySheetModel::Mode::kPinChange));
+              AuthenticatorClientPinEntrySheetModel::Mode::kPinChange,
+              dialog_model->pin_error()));
       break;
     case Step::kClientPinEntry:
       sheet_view = std::make_unique<AuthenticatorClientPinEntrySheetView>(
           std::make_unique<AuthenticatorClientPinEntrySheetModel>(
               dialog_model,
-              AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry));
+              AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry,
+              dialog_model->pin_error()));
       break;
     case Step::kClientPinSetup:
       sheet_view = std::make_unique<AuthenticatorClientPinEntrySheetView>(
           std::make_unique<AuthenticatorClientPinEntrySheetModel>(
               dialog_model,
-              AuthenticatorClientPinEntrySheetModel::Mode::kPinSetup));
+              AuthenticatorClientPinEntrySheetModel::Mode::kPinSetup,
+              dialog_model->pin_error()));
       break;
     case Step::kClientPinTapAgain:
       sheet_view = std::make_unique<AuthenticatorRequestSheetView>(
diff --git a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
index cbb1d70d..a0790b3 100644
--- a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
+++ b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
@@ -21,12 +21,11 @@
 #include "device/fido/authenticator_get_assertion_response.h"
 #include "device/fido/cable/cable_discovery_data.h"
 #include "device/fido/fido_request_handler_base.h"
+#include "device/fido/pin.h"
 #include "device/fido/public_key_credential_user_entity.h"
 
 class AuthenticatorDialogTest : public DialogBrowserTest {
  public:
-  using CollectPINMode =
-      device::FidoRequestHandlerBase::Observer::CollectPINOptions::Mode;
   AuthenticatorDialogTest() = default;
 
   // DialogBrowserTest:
@@ -85,23 +84,25 @@
       model->SetCurrentStep(
           AuthenticatorRequestDialogModel::Step::kCableV2QRCode);
     } else if (name == "set_pin") {
-      model->CollectPIN(CollectPINMode::kSet, 6, 0,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kSet,
+                        device::pin::PINEntryError::kNoError, 6, 0,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "get_pin") {
-      model->CollectPIN(CollectPINMode::kChallenge, 6, 8,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kChallenge,
+                        device::pin::PINEntryError::kNoError, 6, 8,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "get_pin_two_tries_remaining") {
-      model->set_has_attempted_pin_entry_for_testing();
-      model->CollectPIN(CollectPINMode::kChallenge, 6, 2,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kChallenge,
+                        device::pin::PINEntryError::kWrongPIN, 6, 2,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "get_pin_one_try_remaining") {
-      model->set_has_attempted_pin_entry_for_testing();
-      model->CollectPIN(CollectPINMode::kChallenge, 6, 1,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kChallenge,
+                        device::pin::PINEntryError::kWrongPIN, 6, 1,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "get_pin_fallback") {
-      model->set_internal_uv_locked();
-      model->CollectPIN(CollectPINMode::kChallenge, 6, 8,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kChallenge,
+                        device::pin::PINEntryError::kInternalUvLocked, 6, 8,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "inline_bio_enrollment") {
       model->StartInlineBioEnrollment(base::DoNothing());
       timer_.Start(
@@ -123,8 +124,13 @@
     } else if (name == "retry_uv_one_try_remaining") {
       model->OnRetryUserVerification(1);
     } else if (name == "force_pin_change") {
-      model->CollectPIN(CollectPINMode::kChange, 6, 0,
-                        base::BindOnce([](std::string pin) {}));
+      model->CollectPIN(device::pin::PINEntryReason::kChange,
+                        device::pin::PINEntryError::kNoError, 6, 0,
+                        base::BindOnce([](base::string16 pin) {}));
+    } else if (name == "force_pin_change_same_as_current") {
+      model->CollectPIN(device::pin::PINEntryReason::kChange,
+                        device::pin::PINEntryError::kSameAsCurrentPIN, 6, 0,
+                        base::BindOnce([](base::string16 pin) {}));
     } else if (name == "second_tap") {
       model->SetCurrentStep(
           AuthenticatorRequestDialogModel::Step::kClientPinTapAgain);
@@ -230,6 +236,11 @@
   ShowAndVerifyUi();
 }
 
+IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest,
+                       InvokeUi_force_pin_change_same_as_current) {
+  ShowAndVerifyUi();
+}
+
 IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_transports) {
   ShowAndVerifyUi();
 }
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc
index eacfd23..e5d96fc8 100644
--- a/chrome/browser/ui/webauthn/sheet_models.cc
+++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -644,27 +644,37 @@
 
 AuthenticatorClientPinEntrySheetModel::AuthenticatorClientPinEntrySheetModel(
     AuthenticatorRequestDialogModel* dialog_model,
-    Mode mode)
+    Mode mode,
+    device::pin::PINEntryError error)
     : AuthenticatorSheetModelBase(dialog_model), mode_(mode) {
-  if (!dialog_model->has_attempted_pin_entry()) {
-    if (dialog_model->uv_attempts() == 0) {
+  switch (error) {
+    case device::pin::PINEntryError::kNoError:
+      break;
+    case device::pin::PINEntryError::kInternalUvLocked:
       error_ = l10n_util::GetStringUTF16(IDS_WEBAUTHN_UV_ERROR_LOCKED);
-    }
-    return;
+      break;
+    case device::pin::PINEntryError::kInvalidCharacters:
+      error_ = l10n_util::GetStringUTF16(
+          IDS_WEBAUTHN_PIN_ENTRY_ERROR_INVALID_CHARACTERS);
+      break;
+    case device::pin::PINEntryError::kSameAsCurrentPIN:
+      error_ = l10n_util::GetStringUTF16(
+          IDS_WEBAUTHN_PIN_ENTRY_ERROR_SAME_AS_CURRENT);
+      break;
+    case device::pin::PINEntryError::kTooShort:
+      error_ = l10n_util::GetPluralStringFUTF16(
+          IDS_WEBAUTHN_PIN_ENTRY_ERROR_TOO_SHORT,
+          dialog_model->min_pin_length());
+      break;
+    case device::pin::PINEntryError::kWrongPIN:
+      base::Optional<int> attempts = dialog_model->pin_attempts();
+      error_ =
+          attempts && *attempts <= 3
+              ? l10n_util::GetPluralStringFUTF16(
+                    IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED_RETRIES, *attempts)
+              : l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED);
+      break;
   }
-
-  if (mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry) {
-    base::Optional<int> attempts = dialog_model->pin_attempts();
-    error_ =
-        attempts && *attempts <= 3
-            ? l10n_util::GetPluralStringFUTF16(
-                  IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED_RETRIES, *attempts)
-            : l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED);
-    return;
-  }
-
-  DCHECK(mode_ == Mode::kPinSetup || mode_ == Mode::kPinChange);
-  error_ = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_SETUP_ERROR_FAILED);
 }
 
 AuthenticatorClientPinEntrySheetModel::
@@ -721,45 +731,16 @@
   return l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_NEXT);
 }
 
-static bool IsValidUTF16(const base::string16& str16) {
-  std::string unused_str8;
-  return base::UTF16ToUTF8(str16.c_str(), str16.size(), &unused_str8);
-}
-
 void AuthenticatorClientPinEntrySheetModel::OnAccept() {
-  if (mode_ == Mode::kPinSetup || mode_ == Mode::kPinChange) {
-    // Validate a new PIN.
-    base::Optional<base::string16> error;
-    if (!pin_code_.empty() && !IsValidUTF16(pin_code_)) {
-      error = l10n_util::GetStringUTF16(
-          IDS_WEBAUTHN_PIN_ENTRY_ERROR_INVALID_CHARACTERS);
-    } else if (pin_code_.size() < dialog_model()->min_pin_length()) {
-      error = l10n_util::GetPluralStringFUTF16(
-          IDS_WEBAUTHN_PIN_ENTRY_ERROR_TOO_SHORT,
-          dialog_model()->min_pin_length());
-    } else if (pin_code_ != pin_confirmation_) {
-      error = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_MISMATCH);
-    }
-    if (error) {
-      error_ = *error;
-      dialog_model()->OnSheetModelDidChange();
-      return;
-    }
-  } else {
-    // Submit PIN to authenticator for verification.
-    DCHECK(mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry);
-    // TODO: use device::pin::IsValid instead.
-    if (pin_code_.size() < dialog_model()->min_pin_length()) {
-      error_ = l10n_util::GetPluralStringFUTF16(
-          IDS_WEBAUTHN_PIN_ENTRY_ERROR_TOO_SHORT,
-          dialog_model()->min_pin_length());
-      dialog_model()->OnSheetModelDidChange();
-      return;
-    }
+  if ((mode_ == Mode::kPinChange || mode_ == Mode::kPinSetup) &&
+      pin_code_ != pin_confirmation_) {
+    error_ = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_MISMATCH);
+    dialog_model()->OnSheetModelDidChange();
+    return;
   }
 
   if (dialog_model()) {
-    dialog_model()->OnHavePIN(base::UTF16ToUTF8(pin_code_));
+    dialog_model()->OnHavePIN(pin_code_);
   }
 }
 
diff --git a/chrome/browser/ui/webauthn/sheet_models.h b/chrome/browser/ui/webauthn/sheet_models.h
index 285ca20..9973cf2 100644
--- a/chrome/browser/ui/webauthn/sheet_models.h
+++ b/chrome/browser/ui/webauthn/sheet_models.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h"
 #include "chrome/browser/ui/webauthn/transport_hover_list_model.h"
 #include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
+#include "device/fido/pin.h"
 
 namespace gfx {
 struct VectorIcon;
@@ -297,7 +298,8 @@
   enum class Mode { kPinChange, kPinEntry, kPinSetup };
   AuthenticatorClientPinEntrySheetModel(
       AuthenticatorRequestDialogModel* dialog_model,
-      Mode mode);
+      Mode mode,
+      device::pin::PINEntryError error);
   ~AuthenticatorClientPinEntrySheetModel() override;
 
   using AuthenticatorSheetModelBase::AuthenticatorSheetModelBase;
diff --git a/chrome/browser/ui/webui/settings/appearance_handler.cc b/chrome/browser/ui/webui/settings/appearance_handler.cc
index 931649cc..b8fa3d7 100644
--- a/chrome/browser/ui/webui/settings/appearance_handler.cc
+++ b/chrome/browser/ui/webui/settings/appearance_handler.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/notreached.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_service.h"
@@ -30,7 +31,7 @@
                           base::Unretained(this)));
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
   web_ui()->RegisterMessageCallback(
       "useSystemTheme",
       base::BindRepeating(&AppearanceHandler::HandleUseSystemTheme,
@@ -44,7 +45,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 void AppearanceHandler::HandleUseSystemTheme(const base::ListValue* args) {
   if (profile_->IsSupervised())
     NOTREACHED();
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
index d050c870..b5a1ec99 100644
--- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
+++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -142,7 +142,8 @@
   kPreferredSearchEngine = 600,
   kAssistantOnOff = 601,
   kAssistantRelatedInfo = 602,
-  kAssistantQuickAnswers = 603,
+  // Note: Value 603 was for deprecated kAssistantQuickAnswers.
+  // Do not reuse.
   kAssistantOkGoogle = 604,
   kAssistantNotifications = 605,
   kAssistantVoiceInput = 606,
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.cc b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
index f27580f..3648536 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/components/quick_answers/quick_answers_client.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/services/assistant/public/cpp/features.h"
@@ -114,18 +113,6 @@
   return *tags;
 }
 
-const std::vector<SearchConcept>& GetAssistantQuickAnswersSearchConcepts() {
-  static const base::NoDestructor<std::vector<SearchConcept>> tags({
-      {IDS_OS_SETTINGS_TAG_ASSISTANT_QUICK_ANSWERS,
-       mojom::kAssistantSubpagePath,
-       mojom::SearchResultIcon::kAssistant,
-       mojom::SearchResultDefaultRank::kLow,
-       mojom::SearchResultType::kSetting,
-       {.setting = mojom::Setting::kAssistantQuickAnswers}},
-  });
-  return *tags;
-}
-
 const std::vector<SearchConcept>& GetAssistantVoiceMatchSearchConcepts() {
   static const base::NoDestructor<std::vector<SearchConcept>> tags({
       {IDS_OS_SETTINGS_TAG_ASSISTANT_TRAIN_VOICE_MODEL,
@@ -148,10 +135,6 @@
       {"googleAssistantEnableContext", IDS_ASSISTANT_SCREEN_CONTEXT_TITLE},
       {"googleAssistantEnableContextDescription",
        IDS_ASSISTANT_SCREEN_CONTEXT_DESC},
-      {"googleAssistantEnableQuickAnswers",
-       IDS_ASSISTANT_QUICK_ANSWERS_SETTING_TITLE},
-      {"googleAssistantEnableQuickAnswersDescription",
-       IDS_ASSISTANT_QUICK_ANSWERS_SETTING_DESC},
       {"googleAssistantEnableHotword",
        IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD},
       {"googleAssistantEnableHotwordDescription",
@@ -225,7 +208,6 @@
 
   const bool is_assistant_allowed = IsAssistantAllowed();
   html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
-  html_source->AddBoolean("quickAnswersAvailable", IsQuickAnswersAllowed());
   html_source->AddLocalizedString("osSearchPageTitle",
                                   is_assistant_allowed
                                       ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
@@ -278,7 +260,6 @@
   static constexpr mojom::Setting kAssistantSettings[] = {
       mojom::Setting::kAssistantOnOff,
       mojom::Setting::kAssistantRelatedInfo,
-      mojom::Setting::kAssistantQuickAnswers,
       mojom::Setting::kAssistantOkGoogle,
       mojom::Setting::kAssistantNotifications,
       mojom::Setting::kAssistantVoiceInput,
@@ -310,18 +291,12 @@
          chromeos::assistant::AssistantAllowedState::ALLOWED;
 }
 
-bool SearchSection::IsQuickAnswersAllowed() const {
-  // TODO(b/159670857): Clean up Quick Answer settings toggle.
-  return false;
-}
-
 void SearchSection::UpdateAssistantSearchTags() {
   SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
 
   // Start without any Assistant search concepts, then add if needed below.
   updater.RemoveSearchTags(GetAssistantOnSearchConcepts());
   updater.RemoveSearchTags(GetAssistantOffSearchConcepts());
-  updater.RemoveSearchTags(GetAssistantQuickAnswersSearchConcepts());
   updater.RemoveSearchTags(GetAssistantVoiceMatchSearchConcepts());
 
   ash::AssistantState* assistant_state = ash::AssistantState::Get();
@@ -336,11 +311,6 @@
 
   updater.AddSearchTags(GetAssistantOnSearchConcepts());
 
-  if (IsQuickAnswersAllowed() && assistant_state->context_enabled() &&
-      assistant_state->context_enabled().value()) {
-    updater.AddSearchTags(GetAssistantQuickAnswersSearchConcepts());
-  }
-
   if (IsVoiceMatchAllowed() && assistant_state->hotword_enabled() &&
       assistant_state->hotword_enabled().value() &&
       assistant_state->consent_status() &&
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.h b/chrome/browser/ui/webui/settings/chromeos/search_section.h
index e493422..6ab696b1 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search_section.h
+++ b/chrome/browser/ui/webui/settings/chromeos/search_section.h
@@ -45,7 +45,6 @@
   void OnAssistantHotwordEnabled(bool enabled) override;
 
   bool IsAssistantAllowed() const;
-  bool IsQuickAnswersAllowed() const;
   void UpdateAssistantSearchTags();
 };
 
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index d65f2e37e..eae2c75d 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -343,7 +343,7 @@
     {"huge", IDS_SETTINGS_HUGE_FONT_SIZE},
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
     {"systemTheme", IDS_SETTINGS_SYSTEM_THEME},
     {"useSystemTheme", IDS_SETTINGS_USE_SYSTEM_THEME},
     {"classicTheme", IDS_SETTINGS_CLASSIC_THEME},
@@ -1002,12 +1002,9 @@
        IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_FROM_ACCOUNT_CHECKBOX_LABEL},
       {"passwordRemoveDialogFromDeviceCheckboxLabel",
        IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_FROM_DEVICE_CHECKBOX_LABEL},
-      {"devicePasswordsLinkLabelSingular",
-       IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR},
-      {"devicePasswordsLinkLabelPlural",
-       IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL},
-      {"devicePasswordsLinkSubLabel",
-       IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL},
+      {"devicePasswordsLinkLabel", IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL},
+      {"devicePasswordsMoved",
+       IDS_SETTINGS_PASSWORD_MOVE_PASSWORDS_TO_ACCOUNT_SNACKBAR},
       {"passwordRowMoreActionsButton", IDS_SETTINGS_PASSWORD_ROW_MORE_ACTIONS},
       {"passwordRowFederatedMoreActionsButton",
        IDS_SETTINGS_PASSWORD_ROW_FEDERATED_MORE_ACTIONS},
diff --git a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index 245e320..7e11621 100644
--- a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -169,7 +169,8 @@
 
   DCHECK((state_ == State::kGatherNewPIN) == old_pin.empty());
 
-  CHECK(device::pin::IsValid(new_pin));
+  CHECK_EQ(device::pin::ValidatePIN(new_pin),
+           device::pin::PINEntryError::kNoError);
   state_ = State::kSettingPIN;
   set_pin_->ProvidePIN(old_pin, new_pin);
 }
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 1a0d4c64..60231d96 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -53,6 +53,8 @@
     "web_app_installation_utils.cc",
     "web_app_installation_utils.h",
     "web_app_migration_manager.h",
+    "web_app_mover.cc",
+    "web_app_mover.h",
     "web_app_proto_utils.cc",
     "web_app_proto_utils.h",
     "web_app_protocol_handler_manager.cc",
@@ -203,6 +205,7 @@
     "web_app_install_manager_unittest.cc",
     "web_app_install_task_unittest.cc",
     "web_app_installation_utils_unittest.cc",
+    "web_app_mover_unittest.cc",
     "web_app_proto_utils_unittest.cc",
     "web_app_registrar_unittest.cc",
     "web_app_sync_bridge_unittest.cc",
diff --git a/chrome/browser/web_applications/web_app_mover.cc b/chrome/browser/web_applications/web_app_mover.cc
new file mode 100644
index 0000000..3a937eb
--- /dev/null
+++ b/chrome/browser/web_applications/web_app_mover.cc
@@ -0,0 +1,131 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/web_applications/web_app_mover.h"
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/common/chrome_features.h"
+
+namespace {
+
+bool g_disabled_for_testing = false;
+bool g_skip_wait_for_sync_for_testing = false;
+
+base::OnceClosure& GetCompletedCallbackForTesting() {
+  static base::NoDestructor<base::OnceClosure> callback;
+  return *callback;
+}
+
+}  // namespace
+
+namespace web_app {
+
+std::unique_ptr<WebAppMover> WebAppMover::CreateIfNeeded(Profile* profile) {
+  DCHECK(base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions));
+
+  if (g_disabled_for_testing)
+    return nullptr;
+
+  if (!base::FeatureList::IsEnabled(features::kMoveWebApp))
+    return nullptr;
+
+  std::string uninstall_url_prefix_str =
+      features::kMoveWebAppUninstallStartUrlPrefix.Get();
+  std::string install_url_str = features::kMoveWebAppInstallStartUrl.Get();
+  if (uninstall_url_prefix_str.empty() || install_url_str.empty())
+    return nullptr;
+
+  GURL uninstall_url_prefix = GURL(uninstall_url_prefix_str);
+  GURL install_url = GURL(install_url_str);
+  // The URLs have to be valid, and the installation URL cannot be contained in
+  // the uninstall prefix.
+  if (!uninstall_url_prefix.is_valid() || !install_url.is_valid() ||
+      base::StartsWith(install_url.spec(), uninstall_url_prefix.spec())) {
+    return nullptr;
+  }
+
+  return std::make_unique<WebAppMover>(profile, uninstall_url_prefix,
+                                       install_url);
+}
+
+void WebAppMover::DisableForTesting() {
+  g_disabled_for_testing = true;
+}
+
+void WebAppMover::SkipWaitForSyncForTesting() {
+  g_skip_wait_for_sync_for_testing = true;
+}
+
+void WebAppMover::SetCompletedCallbackForTesting(base::OnceClosure callback) {
+  GetCompletedCallbackForTesting() = std::move(callback);
+}
+
+WebAppMover::WebAppMover(Profile* profile,
+                         const GURL& uninstall_url_prefix,
+                         const GURL& install_url)
+    : profile_(profile),
+      uninstall_url_prefix_(uninstall_url_prefix),
+      install_url_(install_url) {}
+
+WebAppMover::~WebAppMover() = default;
+
+void WebAppMover::Start() {
+  // We cannot grab the SyncService in the constructor without creating a
+  // circular KeyedService dependency.
+  sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile_);
+  // This can be a nullptr if the --disable-sync switch is specified.
+  if (sync_service_)
+    sync_observer_.Observe(sync_service_);
+  // We must wait for sync to complete at least one cycle (if it is turned on).
+  // This avoids our local updates accidentally re-installing any web apps that
+  // were uninstalled on other devices. Installing the replacement app will send
+  // that record to sync servers, and if the user had uninstalled the 'source'
+  // app on another computer, we could miss that message and accidentally end up
+  // with the 'destination' app installed when it shouldn't have been installed
+  // in the first place (as the user uninstalled the 'source' app).
+  WaitForFirstSyncCycle(base::BindOnce(&WebAppMover::OnFirstSyncCycleComplete,
+                                       weak_ptr_factory_.GetWeakPtr()));
+}
+
+void WebAppMover::Shutdown() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+  sync_observer_.Reset();
+}
+
+void WebAppMover::OnSyncCycleCompleted(syncer::SyncService* sync_service) {
+  DCHECK_EQ(sync_service_, sync_service);
+  if (sync_ready_callback_)
+    std::move(sync_ready_callback_).Run();
+}
+
+void WebAppMover::OnSyncShutdown(syncer::SyncService* sync_service) {
+  DCHECK_EQ(sync_service_, sync_service);
+  sync_observer_.Reset();
+  sync_service_ = nullptr;
+}
+
+void WebAppMover::WaitForFirstSyncCycle(base::OnceClosure callback) {
+  DCHECK(!sync_ready_callback_);
+  if (g_skip_wait_for_sync_for_testing || !sync_service_ ||
+      sync_service_->HasCompletedSyncCycle() ||
+      !sync_service_->IsSyncFeatureEnabled()) {
+    std::move(callback).Run();
+    return;
+  }
+  sync_ready_callback_ = std::move(callback);
+}
+
+void WebAppMover::OnFirstSyncCycleComplete() {
+  // TODO(dmurph): Implement migration here.
+
+  if (GetCompletedCallbackForTesting())
+    std::move(GetCompletedCallbackForTesting()).Run();
+}
+
+}  // namespace web_app
\ No newline at end of file
diff --git a/chrome/browser/web_applications/web_app_mover.h b/chrome/browser/web_applications/web_app_mover.h
new file mode 100644
index 0000000..8a30f4c
--- /dev/null
+++ b/chrome/browser/web_applications/web_app_mover.h
@@ -0,0 +1,64 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MOVER_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MOVER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/scoped_observation.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_service_observer.h"
+#include "url/gurl.h"
+
+class Profile;
+
+namespace web_app {
+
+// WebAppMover is designed to facilitate a one-off migration for a webapp, from
+// one start_url to another.
+// TODO(dmurph): Finish implementing.
+class WebAppMover final : public syncer::SyncServiceObserver {
+ public:
+  static std::unique_ptr<WebAppMover> CreateIfNeeded(Profile* profile);
+
+  static void DisableForTesting();
+  static void SkipWaitForSyncForTesting();
+  static void SetCompletedCallbackForTesting(base::OnceClosure callback);
+
+  WebAppMover(Profile* profile,
+              const GURL& uninstall_url_prefix,
+              const GURL& install_url);
+  WebAppMover(const WebAppMover&) = delete;
+  WebAppMover& operator=(const WebAppMover&) = delete;
+  ~WebAppMover() final;
+
+  void Start();
+  void Shutdown();
+
+  // syncer::SyncServiceObserver:
+  void OnSyncCycleCompleted(syncer::SyncService* sync_service) final;
+  void OnSyncShutdown(syncer::SyncService* sync_service) final;
+
+ private:
+  void WaitForFirstSyncCycle(base::OnceClosure callback);
+  void OnFirstSyncCycleComplete();
+
+  Profile* profile_;
+  GURL uninstall_url_prefix_;
+  GURL install_url_;
+  syncer::SyncService* sync_service_ = nullptr;
+  base::OnceClosure sync_ready_callback_;
+
+  base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
+      sync_observer_{this};
+
+  base::WeakPtrFactory<WebAppMover> weak_ptr_factory_{this};
+};
+
+}  // namespace web_app
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MOVER_H_
\ No newline at end of file
diff --git a/chrome/browser/web_applications/web_app_mover_unittest.cc b/chrome/browser/web_applications/web_app_mover_unittest.cc
new file mode 100644
index 0000000..f1e8550e
--- /dev/null
+++ b/chrome/browser/web_applications/web_app_mover_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/web_applications/web_app_mover.h"
+
+#include "base/metrics/field_trial_params.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/common/chrome_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace web_app {
+namespace {
+
+class WebAppMoverTestWithParams : public ::testing::Test,
+                                  public ::testing::WithParamInterface<
+                                      std::pair<const char*, const char*>> {
+ public:
+  WebAppMoverTestWithParams() {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{features::kMoveWebApp,
+          {{features::kMoveWebAppUninstallStartUrlPrefix.name,
+            GetParam().first},
+           {features::kMoveWebAppInstallStartUrl.name, GetParam().second}}}},
+        {});
+  }
+  ~WebAppMoverTestWithParams() override = default;
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+using WebAppMoverTestWithInvalidParams = WebAppMoverTestWithParams;
+
+TEST_P(WebAppMoverTestWithInvalidParams, VerifyInvalidParams) {
+  std::unique_ptr<WebAppMover> mover = WebAppMover::CreateIfNeeded(nullptr);
+  EXPECT_FALSE(mover);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    InvalidInputs,
+    WebAppMoverTestWithInvalidParams,
+    ::testing::Values(
+        std::make_pair("", ""),
+        std::make_pair("test", "test"),
+        std::make_pair("www.google.com/a", "www.google.com/b"),
+        std::make_pair("https://www.google.com/a", "https://www.google.com/a"),
+        std::make_pair("https://www.google.com/", "https://www.google.com/a"),
+        std::make_pair("https://www.google.com/foo",
+                       "https://www.google.com/foobar")));
+
+using WebAppMoverTestWithValidParams = WebAppMoverTestWithParams;
+
+TEST_P(WebAppMoverTestWithValidParams, VerifyValidParams) {
+  std::unique_ptr<WebAppMover> mover = WebAppMover::CreateIfNeeded(nullptr);
+  EXPECT_TRUE(mover);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ValidInputs,
+    WebAppMoverTestWithValidParams,
+    ::testing::Values(std::make_pair("https://www.google.com/a",
+                                     "https://www.google.com/b")));
+
+}  // namespace
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc
index 2a2b2868..915aca0 100644
--- a/chrome/browser/web_applications/web_app_provider.cc
+++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
 #include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/browser/web_applications/web_app_migration_manager.h"
+#include "chrome/browser/web_applications/web_app_mover.h"
 #include "chrome/browser/web_applications/web_app_protocol_handler_manager.h"
 #include "chrome/browser/web_applications/web_app_provider_factory.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -161,6 +162,8 @@
   icon_manager_->Shutdown();
   install_finalizer_->Shutdown();
   registrar_->Shutdown();
+  if (web_app_mover_)
+    web_app_mover_->Shutdown();
 }
 
 void WebAppProvider::StartImpl() {
@@ -235,6 +238,7 @@
   migration_manager_ = std::make_unique<WebAppMigrationManager>(
       profile, database_factory_.get(), icon_manager.get(),
       os_integration_manager_.get());
+  web_app_mover_ = WebAppMover::CreateIfNeeded(profile);
 
   // Upcast to unified subsystem types:
   registrar_ = std::move(registrar);
@@ -290,6 +294,8 @@
   manifest_update_manager_->Start();
   os_integration_manager_->Start();
   ui_manager_->Start();
+  if (web_app_mover_)
+    web_app_mover_->Start();
 
   on_registry_ready_.Signal();
 }
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h
index 8354161..b530bfd2 100644
--- a/chrome/browser/web_applications/web_app_provider.h
+++ b/chrome/browser/web_applications/web_app_provider.h
@@ -43,6 +43,7 @@
 // Forward declarations for new extension-independent subsystems.
 class WebAppDatabaseFactory;
 class WebAppMigrationManager;
+class WebAppMover;
 
 // Connects Web App features, such as the installation of default and
 // policy-managed web apps, with Profiles (as WebAppProvider is a
@@ -127,6 +128,7 @@
   std::unique_ptr<WebAppDatabaseFactory> database_factory_;
   // migration_manager_ can be nullptr if no migration needed.
   std::unique_ptr<WebAppMigrationManager> migration_manager_;
+  std::unique_ptr<WebAppMover> web_app_mover_;
 
   // Generalized subsystems:
   std::unique_ptr<AppRegistrar> registrar_;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
index 1e4d256a..0716154 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -15,12 +15,10 @@
 #include "build/build_config.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_authenticator.h"
+#include "device/fido/pin.h"
 
 namespace {
 
-using CollectPINMode =
-    device::FidoRequestHandlerBase::Observer::CollectPINOptions::Mode;
-
 // Attempts to auto-select the most likely transport that will be used to
 // service this request, or returns base::nullopt if unsure.
 base::Optional<device::FidoTransportProtocol> SelectMostLikelyTransport(
@@ -96,7 +94,6 @@
 void AuthenticatorRequestDialogModel::EphemeralState::Reset() {
   selected_authenticator_id_ = base::nullopt;
   saved_authenticators_.RemoveAllAuthenticators();
-  has_attempted_pin_entry_ = false;
   responses_.clear();
 }
 
@@ -436,7 +433,7 @@
   bluetooth_adapter_power_on_callback_ = bluetooth_adapter_power_on_callback;
 }
 
-void AuthenticatorRequestDialogModel::OnHavePIN(const std::string& pin) {
+void AuthenticatorRequestDialogModel::OnHavePIN(base::string16 pin) {
   if (!pin_callback_) {
     // Protect against the view submitting a PIN more than once without
     // receiving a matching response first. |CollectPIN| is called again if
@@ -444,7 +441,6 @@
     return;
   }
   std::move(pin_callback_).Run(pin);
-  ephemeral_state_.has_attempted_pin_entry_ = true;
 }
 
 void AuthenticatorRequestDialogModel::OnRetryUserVerification(int attempts) {
@@ -538,29 +534,26 @@
 }
 
 void AuthenticatorRequestDialogModel::CollectPIN(
-    CollectPINMode mode,
+    device::pin::PINEntryReason reason,
+    device::pin::PINEntryError error,
     uint32_t min_pin_length,
     int attempts,
-    base::OnceCallback<void(std::string)> provide_pin_cb) {
+    base::OnceCallback<void(base::string16)> provide_pin_cb) {
   pin_callback_ = std::move(provide_pin_cb);
   min_pin_length_ = min_pin_length;
-  Step new_step;
-  switch (mode) {
-    case CollectPINMode::kChallenge:
+  pin_error_ = error;
+  switch (reason) {
+    case device::pin::PINEntryReason::kChallenge:
       pin_attempts_ = attempts;
-      new_step = Step::kClientPinEntry;
-      break;
-    case CollectPINMode::kChange:
-      new_step = Step::kClientPinChange;
-      break;
-    case CollectPINMode::kSet:
-      new_step = Step::kClientPinSetup;
-      break;
+      SetCurrentStep(Step::kClientPinEntry);
+      return;
+    case device::pin::PINEntryReason::kChange:
+      SetCurrentStep(Step::kClientPinChange);
+      return;
+    case device::pin::PINEntryReason::kSet:
+      SetCurrentStep(Step::kClientPinSetup);
+      return;
   }
-  if (new_step != current_step_) {
-    ephemeral_state_.has_attempted_pin_entry_ = false;
-  }
-  SetCurrentStep(new_step);
 }
 
 void AuthenticatorRequestDialogModel::StartInlineBioEnrollment(
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h
index db7c1bd..a5baccd 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.h
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -23,6 +23,7 @@
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_request_handler_base.h"
 #include "device/fido/fido_transport_protocol.h"
+#include "device/fido/pin.h"
 
 namespace device {
 class AuthenticatorGetAssertionResponse;
@@ -324,7 +325,7 @@
       base::RepeatingClosure bluetooth_adapter_power_on_callback);
 
   // OnHavePIN is called when the user enters a PIN in the UI.
-  void OnHavePIN(const std::string& pin);
+  void OnHavePIN(base::string16 pin);
 
   // Called when the user needs to retry user verification with the number of
   // |attempts| remaining.
@@ -364,15 +365,13 @@
 
   const std::string& cable_qr_string() const { return *cable_qr_string_; }
 
-  void CollectPIN(
-      device::FidoRequestHandlerBase::Observer::CollectPINOptions::Mode mode,
-      uint32_t min_pin_length,
-      int attempts,
-      base::OnceCallback<void(std::string)> provide_pin_cb);
-  bool has_attempted_pin_entry() const {
-    return ephemeral_state_.has_attempted_pin_entry_;
-  }
+  void CollectPIN(device::pin::PINEntryReason reason,
+                  device::pin::PINEntryError error,
+                  uint32_t min_pin_length,
+                  int attempts,
+                  base::OnceCallback<void(base::string16)> provide_pin_cb);
   uint32_t min_pin_length() const { return min_pin_length_; }
+  device::pin::PINEntryError pin_error() const { return pin_error_; }
   base::Optional<int> pin_attempts() const { return pin_attempts_; }
 
   void StartInlineBioEnrollment(base::OnceClosure next_callback);
@@ -381,8 +380,6 @@
   base::Optional<int> max_bio_samples() { return max_bio_samples_; }
   base::Optional<int> bio_samples_remaining() { return bio_samples_remaining_; }
 
-  // Flags the authenticator's internal user verification as locked.
-  void set_internal_uv_locked() { uv_attempts_ = 0; }
   base::Optional<int> uv_attempts() const { return uv_attempts_; }
 
   void RequestAttestationPermission(base::OnceCallback<void(bool)> callback);
@@ -391,10 +388,6 @@
     return ephemeral_state_.responses_;
   }
 
-  void set_has_attempted_pin_entry_for_testing() {
-    ephemeral_state_.has_attempted_pin_entry_ = true;
-  }
-
   void set_incognito_mode(bool incognito_mode) {
     incognito_mode_ = incognito_mode;
   }
@@ -442,8 +435,6 @@
     // dispatched lazily after the user interacts with the UI element.
     ObservableAuthenticatorList saved_authenticators_;
 
-    bool has_attempted_pin_entry_ = false;
-
     // responses_ contains possible accounts to select between.
     std::vector<device::AuthenticatorGetAssertionResponse> responses_;
   };
@@ -477,8 +468,9 @@
   base::Optional<int> bio_samples_remaining_;
   base::OnceClosure bio_enrollment_callback_;
 
-  base::OnceCallback<void(std::string)> pin_callback_;
+  base::OnceCallback<void(base::string16)> pin_callback_;
   uint32_t min_pin_length_ = device::kMinPinLength;
+  device::pin::PINEntryError pin_error_ = device::pin::PINEntryError::kNoError;
   base::Optional<int> pin_attempts_;
   base::Optional<int> uv_attempts_;
 
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 3dcc011..e450281e 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -577,12 +577,13 @@
 
 void ChromeAuthenticatorRequestDelegate::CollectPIN(
     CollectPINOptions options,
-    base::OnceCallback<void(std::string)> provide_pin_cb) {
+    base::OnceCallback<void(base::string16)> provide_pin_cb) {
   if (!weak_dialog_model_)
     return;
 
-  weak_dialog_model_->CollectPIN(options.mode, options.min_pin_length,
-                                 options.attempts, std::move(provide_pin_cb));
+  weak_dialog_model_->CollectPIN(options.reason, options.error,
+                                 options.min_pin_length, options.attempts,
+                                 std::move(provide_pin_cb));
 }
 
 void ChromeAuthenticatorRequestDelegate::StartBioEnrollment(
@@ -616,13 +617,6 @@
   weak_dialog_model_->OnRetryUserVerification(attempts);
 }
 
-void ChromeAuthenticatorRequestDelegate::OnInternalUserVerificationLocked() {
-  if (!weak_dialog_model_)
-    return;
-
-  weak_dialog_model_->set_internal_uv_locked();
-}
-
 void ChromeAuthenticatorRequestDelegate::SetMightCreateResidentCredential(
     bool v) {
   if (!weak_dialog_model_) {
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
index 722bbd37..1b0b4a2 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -112,12 +112,11 @@
   bool SupportsPIN() const override;
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override;
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override;
   void StartBioEnrollment(base::OnceClosure next_callback) override;
   void OnSampleCollected(int bio_samples_remaining) override;
   void FinishCollectToken() override;
   void OnRetryUserVerification(int attempts) override;
-  void OnInternalUserVerificationLocked() override;
   void SetMightCreateResidentCredential(bool v) override;
 
   // AuthenticatorRequestDialogModel::Observer:
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 7f9fd1e..6991f7a 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1608173994-6a2e9c3f805f7667eca640b2b557f764d57c9690.profdata
+chrome-win64-master-1608195565-bd827a491b21adb0b88af96833fe918adc2826b3.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 4cabeff..7e138216 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -616,6 +616,15 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
+const base::Feature kMoveWebApp{
+    "MoveWebApp", base::FeatureState::FEATURE_DISABLED_BY_DEFAULT};
+const base::FeatureParam<std::string> kMoveWebAppUninstallStartUrlPrefix(
+    &kMoveWebApp,
+    "uninstallStartUrlPrefix",
+    "");
+const base::FeatureParam<std::string>
+    kMoveWebAppInstallStartUrl(&kMoveWebApp, "installStartUrl", "");
+
 // Enables the use of native notification centers instead of using the Message
 // Center for displaying the toasts. The feature is hardcoded to enabled for
 // Chrome OS.
@@ -870,14 +879,6 @@
 // Enable uploading of a zip archive of system logs instead of individual files.
 const base::Feature kUploadZippedSystemLogs{"UploadZippedSystemLogs",
                                             base::FEATURE_ENABLED_BY_DEFAULT};
-
-// Enable USB Bouncer for managing a device whitelist for USBGuard on Chrome OS.
-const base::Feature kUsbbouncer{"USBBouncer",
-                                base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Enable USBGuard at the lockscreen on Chrome OS.
-// TODO(crbug.com/874630): Remove this kill-switch
-const base::Feature kUsbguard{"USBGuard", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index b3aef525..28c6dc1a 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -407,6 +407,13 @@
 extern const base::Feature kMetricsSettingsAndroid;
 #endif
 
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kMoveWebApp;
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::FeatureParam<std::string> kMoveWebAppUninstallStartUrlPrefix;
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::FeatureParam<std::string> kMoveWebAppInstallStartUrl;
+
 #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kNativeNotifications;
@@ -584,12 +591,6 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kUsbbouncer;
-
-COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kUsbguard;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kUserActivityEventLogging;
 #endif
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 5462da8..7d80c529 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1041,6 +1041,7 @@
       "../browser/download/download_frame_policy_browsertest.cc",
       "../browser/download/download_started_animation_browsertest.cc",
       "../browser/download/save_page_browsertest.cc",
+      "../browser/enterprise/connectors/connectors_service_browsertest.cc",
       "../browser/enterprise/connectors/content_analysis_delegate_browsertest.cc",
       "../browser/enterprise/connectors/content_analysis_dialog_browsertest.cc",
       "../browser/enterprise/reporting/report_scheduler_browsertest.cc",
@@ -3489,6 +3490,7 @@
     "../browser/engagement/site_engagement_helper_unittest.cc",
     "../browser/engagement/site_engagement_score_unittest.cc",
     "../browser/engagement/site_engagement_service_unittest.cc",
+    "../browser/enterprise/util/affiliation_unittest.cc",
     "../browser/enterprise/util/managed_browser_utils_unittest.cc",
     "../browser/external_protocol/external_protocol_handler_unittest.cc",
     "../browser/federated_learning/floc_id_provider_unittest.cc",
diff --git a/chrome/test/base/perf/performance_test.cc b/chrome/test/base/perf/performance_test.cc
index bece169e..d18637de 100644
--- a/chrome/test/base/perf/performance_test.cc
+++ b/chrome/test/base/perf/performance_test.cc
@@ -63,7 +63,8 @@
                         /*isOpaque=*/true);
   SkCanvas canvas(bitmap);
   canvas.drawColor(SK_ColorGREEN);
-  gfx::ImageSkia image(gfx::ImageSkiaRep(std::move(bitmap), 1.f));
+  gfx::ImageSkia image =
+      gfx::ImageSkia::CreateFromBitmap(std::move(bitmap), 1.f);
 
   base::RunLoop run_loop;
   TestWallpaperObserver observer(run_loop.QuitClosure());
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index a706393..9f9e71e9 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -6884,19 +6884,7 @@
   },
 
   "VoiceInteractionQuickAnswersEnabled": {
-    "os": ["chromeos"],
-    "policy_pref_mapping_tests": [
-      {
-        "policies": {
-          "VoiceInteractionQuickAnswersEnabled": true
-        },
-        "prefs": {
-          "settings.voice_interaction.quick_answers.enabled": {
-            "value": true
-          }
-        }
-      }
-    ]
+    "note": "This policy is deprecated."
   },
 
   "DeviceRebootOnUserSignout": {
diff --git a/chrome/test/data/webui/engagement/site_engagement_browsertest.js b/chrome/test/data/webui/engagement/site_engagement_browsertest.js
index 6aa96c7..cee7d37 100644
--- a/chrome/test/data/webui/engagement/site_engagement_browsertest.js
+++ b/chrome/test/data/webui/engagement/site_engagement_browsertest.js
@@ -10,6 +10,7 @@
 
 GEN('#include "chrome/browser/engagement/site_engagement_service.h"');
 GEN('#include "chrome/browser/engagement/site_engagement_service_factory.h"');
+GEN('#include "chrome/browser/profiles/profile.h"');
 GEN('#include "chrome/browser/ui/browser.h"');
 GEN('#include "content/public/test/browser_test.h"');
 
diff --git a/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js b/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
index 636506b..3e77a65 100644
--- a/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
@@ -55,7 +55,6 @@
     loadTimeData.overrideValues({
       isAssistantAllowed: true,
       hotwordDspAvailable: true,
-      quickAnswersAvailable: true,
     });
   });
 
@@ -110,38 +109,6 @@
         page.getPref('settings.voice_interaction.context.enabled.value'));
   });
 
-  test('toggleAssistantQuickAnswers', function() {
-    let button = page.$$('#google-assistant-quick-answers-enable');
-    assertFalse(!!button);
-    page.setPrefValue('settings.voice_interaction.enabled', true);
-    page.setPrefValue('settings.voice_interaction.context.enabled', true);
-    page.setPrefValue(
-        'settings.voice_interaction.quick_answers.enabled', false);
-    Polymer.dom.flush();
-    button = page.$$('#google-assistant-quick-answers-enable');
-    assertTrue(!!button);
-    assertFalse(button.disabled);
-    assertFalse(button.checked);
-
-    button.click();
-    Polymer.dom.flush();
-    assertTrue(button.checked);
-    assertTrue(
-        page.getPref('settings.voice_interaction.quick_answers.enabled.value'));
-  });
-
-  test('quickAnswersSettingVisibility', function() {
-    let dropdown = page.$$('#quick-answers-container');
-    assertFalse(!!dropdown);
-
-    page.setPrefValue('settings.voice_interaction.enabled', true);
-    page.setPrefValue('settings.voice_interaction.context.enabled', true);
-    Polymer.dom.flush();
-
-    dropdown = page.$$('#quick-answers-container');
-    assertTrue(!!dropdown);
-  });
-
   test('toggleAssistantHotword', function() {
     let button = page.$$('#google-assistant-hotword-enable');
     assertFalse(!!button);
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.js
index 401e8f4..fd9688f 100644
--- a/chrome/test/data/webui/settings/passwords_section_test.js
+++ b/chrome/test/data/webui/settings/passwords_section_test.js
@@ -1626,8 +1626,7 @@
     });
 
     // Test verifies that the button linking to the 'device passwords' page is
-    // only visible when there is at least one device password, and that it has
-    // the appropriate text.
+    // only visible when there is at least one device password.
     test('verifyDevicePasswordsButtonVisibility', function() {
       // Set up user eligible to the account-scoped password storage, not
       // opted in and with no device passwords. Button should be hidden.
@@ -1646,28 +1645,13 @@
       flush();
       assertTrue(passwordsSection.$.devicePasswordsLink.hidden);
 
-      // Add a device password. The button shows up, with the text in singular
-      // form.
+      // Add a device password. The button shows up.
       passwordList.unshift(
           createPasswordEntry({fromAccountStore: false, id: 20}));
       passwordManager.lastCallback.addSavedPasswordListChangedListener(
           passwordList);
       flush();
       assertFalse(passwordsSection.$.devicePasswordsLink.hidden);
-      assertEquals(
-          passwordsSection.i18n('devicePasswordsLinkLabelSingular'),
-          passwordsSection.$.devicePasswordsLinkLabel.innerText);
-
-      // Add a second device password. The text nows says '2 passwords'.
-      passwordList.unshift(
-          createPasswordEntry({fromAccountStore: false, id: 30}));
-      passwordManager.lastCallback.addSavedPasswordListChangedListener(
-          passwordList);
-      flush();
-      assertFalse(passwordsSection.$.devicePasswordsLink.hidden);
-      assertEquals(
-          passwordsSection.i18n('devicePasswordsLinkLabelPlural', 2),
-          passwordsSection.$.devicePasswordsLinkLabel.innerText);
     });
 
     // Test verifies that, for account-scoped password storage users, removing
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index a9bbeef3..ce9cef5 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -309,6 +309,7 @@
       "test/integration_tests.cc",
       "test/integration_tests.h",
       "unittest_util_unittest.cc",
+      "update_service_unittest.cc",
       "updater_unittest.cc",
     ]
 
diff --git a/chrome/updater/enum_traits.h b/chrome/updater/enum_traits.h
index ca7d823..43ca456 100644
--- a/chrome/updater/enum_traits.h
+++ b/chrome/updater/enum_traits.h
@@ -37,7 +37,7 @@
 template <typename T>
 struct EnumTraits {};
 
-// Returns an optional value of an enun type T if the conversion from an
+// Returns an optional value of an enum type T if the conversion from an
 // integral type V is safe, meaning that |v| is within the bounds of the enum.
 // The enum type must be annotated with traits to specify the lower and upper
 // bounds of the enum values.
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 26f75e1..6c6642d 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -12,6 +12,7 @@
 #include "base/logging.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
+#include "base/strings/strcat.h"
 #include "base/test/task_environment.h"
 #include "base/version.h"
 #include "build/build_config.h"
@@ -52,9 +53,30 @@
     VLOG(0) << "Failed to read updater.log file.";
   }
 }
-
 }  // namespace
 
+const testing::TestInfo* GetTestInfo() {
+  return testing::UnitTest::GetInstance()->current_test_info();
+}
+
+base::FilePath GetLogDestinationDir() {
+  // Fetch path to ${ISOLATED_OUTDIR} env var.
+  // ResultDB reads logs and test artifacts info from there.
+  return base::FilePath::FromUTF8Unsafe(std::getenv("ISOLATED_OUTDIR"));
+}
+
+void CopyLog(const base::FilePath& src_dir) {
+  // TODO(crbug.com/1159189): copy other test artifacts.
+  base::FilePath dest_dir = GetLogDestinationDir();
+  if (base::PathExists(dest_dir) && base::PathExists(src_dir)) {
+    base::FilePath dest_file_path = dest_dir.AppendASCII(
+        base::StrCat({GetTestInfo()->test_suite_name(), ".",
+                      GetTestInfo()->name(), "_updater.log"}));
+    EXPECT_TRUE(
+        base::CopyFile(src_dir.AppendASCII("updater.log"), dest_file_path));
+  }
+}
+
 void RunWake(int expected_exit_code) {
   const base::FilePath installed_executable_path = GetInstalledExecutablePath();
   EXPECT_TRUE(base::PathExists(installed_executable_path));
@@ -134,9 +156,12 @@
   }
 
   void TearDown() override {
-    ExpectClean();
     if (::testing::Test::HasFailure())
       PrintLog();
+    // TODO(crbug.com/1159189): Use a specific test output directory
+    // because Uninstall() deletes the files under GetDataDirPath().
+    CopyLog(GetDataDirPath());
+    ExpectClean();
     Clean();
   }
 
diff --git a/chrome/updater/test/integration_tests.h b/chrome/updater/test/integration_tests.h
index 36977f9..54b0554 100644
--- a/chrome/updater/test/integration_tests.h
+++ b/chrome/updater/test/integration_tests.h
@@ -29,6 +29,9 @@
 // Places the updater into test mode (use local servers and disable CUP).
 void EnterTestMode();
 
+// Copies the logs to a location where they can be retrieved by ResultDB.
+void CopyLog(const base::FilePath& src_dir);
+
 // Sleeps for the given number of seconds. This should be avoided, but in some
 // cases surrounding uninstall it is necessary since the processes can exit
 // prior to completing the actual uninstallation.
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm
index 689ac179..bbed9114c 100644
--- a/chrome/updater/test/integration_tests_mac.mm
+++ b/chrome/updater/test/integration_tests_mac.mm
@@ -200,6 +200,11 @@
 }
 
 void Uninstall() {
+  // Copy logs from GetDataDirPath() before updater uninstalls itself
+  // and deletes the path.
+  CopyLog(GetDataDirPath());
+
+  // Uninstall the updater.
   const base::FilePath path = GetExecutablePath();
   ASSERT_FALSE(path.empty());
   base::CommandLine command_line(path);
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index c24409d6..2a8c0aa 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -139,6 +139,10 @@
 }
 
 void Uninstall() {
+  // Copy logs from GetDataDirPath() before updater uninstalls itself
+  // and deletes the path.
+  CopyLog(GetDataDirPath());
+
   // Note: updater.exe --uninstall is run from the build dir, not the install
   // dir, because it is useful for tests to be able to run it to clean the
   // system even if installation has failed or the installed binaries have
diff --git a/chrome/updater/update_service.h b/chrome/updater/update_service.h
index 2315510..1f09840 100644
--- a/chrome/updater/update_service.h
+++ b/chrome/updater/update_service.h
@@ -46,12 +46,12 @@
     // such as a task failed to post, or allocation of a resource failed.
     kServiceFailed = 4,
 
+    // An error handling the update check occurred.
+    kUpdateCheckFailed = 5,
+
     // This value indicates that required metadata associated with the
     // application was not available for any reason.
-    kAppNotFound = 5,
-
-    // An error handling the update check occurred.
-    kUpdateCheckFailed = 6,
+    kAppNotFound = 6,
 
     // A function argument was invalid.
     kInvalidArgument = 7,
@@ -59,11 +59,10 @@
     // This server is not the active server.
     kInactive = 8,
 
-    // Change the EnumTraits class in this file when adding new values.
     // IPC connection to the remote process failed for some reason.
     kIPCConnectionFailed = 9,
 
-    // Change the traits class in this file when adding new values.
+    // Update EnumTraits<UpdateService::Result> when adding new values.
   };
 
   // Run time errors are organized in specific categories to indicate the
@@ -76,7 +75,7 @@
     kInstall = 3,
     kService = 4,
     kUpdateCheck = 5,
-    // Change the traits class in this file when adding new values.
+    // Update EnumTraits<UpdateService::ErrorCategory> when adding new values.
   };
 
   struct UpdateState {
@@ -115,7 +114,8 @@
       // halted and the state will not change.
       kUpdateError = 8,
 
-      // Change the traits class in this file when adding new values.
+      // Update EnumTraits<UpdateService::UpdateState::State> when adding new
+      // values.
     };
 
     UpdateState();
@@ -222,7 +222,7 @@
 struct EnumTraits<UpdateService::Result> {
   using Result = UpdateService::Result;
   static constexpr Result first_elem = Result::kSuccess;
-  static constexpr Result last_elem = Result::kInactive;
+  static constexpr Result last_elem = Result::kIPCConnectionFailed;
 };
 
 template <>
diff --git a/chrome/updater/update_service_unittest.cc b/chrome/updater/update_service_unittest.cc
new file mode 100644
index 0000000..deed6a6
--- /dev/null
+++ b/chrome/updater/update_service_unittest.cc
@@ -0,0 +1,29 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/updater/update_service.h"
+
+#include "components/update_client/update_client_errors.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Tests value parity between UpdateService::Result and UpdateService::Result.
+TEST(UpdateServiceTest, ResultEnumTest) {
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kSuccess),
+            static_cast<int>(update_client::Error::NONE));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kUpdateInProgress),
+            static_cast<int>(update_client::Error::UPDATE_IN_PROGRESS));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kUpdateCanceled),
+            static_cast<int>(update_client::Error::UPDATE_CANCELED));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kRetryLater),
+            static_cast<int>(update_client::Error::RETRY_LATER));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kServiceFailed),
+            static_cast<int>(update_client::Error::SERVICE_ERROR));
+  EXPECT_EQ(
+      static_cast<int>(updater::UpdateService::Result::kUpdateCheckFailed),
+      static_cast<int>(update_client::Error::UPDATE_CHECK_ERROR));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kAppNotFound),
+            static_cast<int>(update_client::Error::CRX_NOT_FOUND));
+  EXPECT_EQ(static_cast<int>(updater::UpdateService::Result::kInvalidArgument),
+            static_cast<int>(update_client::Error::INVALID_ARGUMENT));
+}
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 768bf04..37f39bfb 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-13669.0.0
\ No newline at end of file
+13670.0.0
\ No newline at end of file
diff --git a/chromeos/components/quick_answers/quick_answers_client.cc b/chromeos/components/quick_answers/quick_answers_client.cc
index e6727f6..66c99b4 100644
--- a/chromeos/components/quick_answers/quick_answers_client.cc
+++ b/chromeos/components/quick_answers/quick_answers_client.cc
@@ -83,11 +83,6 @@
   NotifyEligibilityChanged();
 }
 
-void QuickAnswersClient::OnAssistantQuickAnswersEnabled(bool enabled) {
-  quick_answers_settings_enabled_ = enabled;
-  NotifyEligibilityChanged();
-}
-
 void QuickAnswersClient::OnLocaleChanged(const std::string& locale) {
   locale_supported_ = IsQuickAnswersAllowedForLocale(
       locale, icu::Locale::getDefault().getName());
diff --git a/chromeos/components/quick_answers/quick_answers_client.h b/chromeos/components/quick_answers/quick_answers_client.h
index 6cb2344..3f7d97c 100644
--- a/chromeos/components/quick_answers/quick_answers_client.h
+++ b/chromeos/components/quick_answers/quick_answers_client.h
@@ -82,7 +82,6 @@
   void OnAssistantSettingsEnabled(bool enabled) override;
   void OnAssistantContextEnabled(bool enabled) override;
   void OnLocaleChanged(const std::string& locale) override;
-  void OnAssistantQuickAnswersEnabled(bool enabled) override;
   void OnAssistantStateDestroyed() override;
 
   // ResultLoaderDelegate:
@@ -148,7 +147,6 @@
   std::unique_ptr<IntentGenerator> intent_generator_;
   bool assistant_enabled_ = false;
   bool assistant_context_enabled_ = false;
-  bool quick_answers_settings_enabled_ = false;
   bool locale_supported_ = false;
   chromeos::assistant::AssistantAllowedState assistant_allowed_state_ =
       chromeos::assistant::AssistantAllowedState::ALLOWED;
diff --git a/chromeos/components/quick_answers/quick_answers_client_unittest.cc b/chromeos/components/quick_answers/quick_answers_client_unittest.cc
index 506cd530..d22e8c7b 100644
--- a/chromeos/components/quick_answers/quick_answers_client_unittest.cc
+++ b/chromeos/components/quick_answers/quick_answers_client_unittest.cc
@@ -119,12 +119,10 @@
   void NotifyAssistantStateChange(
       bool setting_enabled,
       bool context_enabled,
-      bool quick_answers_enabled,
       chromeos::assistant::AssistantAllowedState assistant_state,
       const std::string& locale) {
     client_->OnAssistantSettingsEnabled(setting_enabled);
     client_->OnAssistantContextEnabled(context_enabled);
-    client_->OnAssistantQuickAnswersEnabled(quick_answers_enabled);
     client_->OnAssistantFeatureAllowedChanged(assistant_state);
     client_->OnLocaleChanged(locale);
   }
@@ -162,7 +160,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 }
@@ -178,14 +175,12 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/false,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 }
@@ -201,7 +196,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 }
@@ -217,7 +211,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/false,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 }
@@ -233,7 +226,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/false,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-US");
 }
@@ -249,7 +241,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/
       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_POLICY,
       /*locale=*/"en-US");
@@ -263,7 +254,6 @@
   NotifyAssistantStateChange(
       /*setting_enabled=*/true,
       /*context_enabled=*/true,
-      /*quick_answers_enabled=*/true,
       /*assistant_state=*/chromeos::assistant::AssistantAllowedState::ALLOWED,
       /*locale=*/"en-GB");
 }
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 8f29f13..8d807537 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-89-4342.0-1607345364-benchmark-89.0.4351.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-89-4342.0-1607345364-benchmark-89.0.4357.3-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index a3232d8..c714dc9 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-89-4342.0-1607944823-benchmark-89.0.4351.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-89-4342.0-1607944823-benchmark-89.0.4357.3-r1-redacted.afdo.xz
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.cc b/chromeos/services/assistant/public/cpp/assistant_prefs.cc
index 5a931258..90fee60 100644
--- a/chromeos/services/assistant/public/cpp/assistant_prefs.cc
+++ b/chromeos/services/assistant/public/cpp/assistant_prefs.cc
@@ -55,11 +55,6 @@
 // A preference that indicates the mode of the Assistant onboarding experience.
 // This preference should only be changed via policy.
 const char kAssistantOnboardingMode[] = "settings.assistant.onboarding_mode";
-// A preference that indicates the user has allowed the Quick Answers
-// to show info related to the selected content. This preference can be
-// overridden by the VoiceInteractionQuickAnswersEnabled administrator policy.
-const char kAssistantQuickAnswersEnabled[] =
-    "settings.voice_interaction.quick_answers.enabled";
 
 void RegisterProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterIntegerPref(kAssistantConsentStatus,
@@ -71,7 +66,6 @@
   registry->RegisterBooleanPref(kAssistantHotwordEnabled, false);
   registry->RegisterBooleanPref(kAssistantLaunchWithMicOpen, false);
   registry->RegisterBooleanPref(kAssistantNotificationEnabled, true);
-  registry->RegisterBooleanPref(kAssistantQuickAnswersEnabled, true);
   registry->RegisterStringPref(kAssistantOnboardingMode,
                                kAssistantOnboardingModeDefault);
 }
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.h b/chromeos/services/assistant/public/cpp/assistant_prefs.h
index e9a2787b..81d7a773 100644
--- a/chromeos/services/assistant/public/cpp/assistant_prefs.h
+++ b/chromeos/services/assistant/public/cpp/assistant_prefs.h
@@ -65,8 +65,6 @@
 extern const char kAssistantNotificationEnabled[];
 COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC)
 extern const char kAssistantOnboardingMode[];
-COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC)
-extern const char kAssistantQuickAnswersEnabled[];
 
 // Registers Assistant specific profile preferences for browser prefs.
 COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC)
diff --git a/components/autofill/android/provider/BUILD.gn b/components/autofill/android/provider/BUILD.gn
index f3b3284f..a6de523 100644
--- a/components/autofill/android/provider/BUILD.gn
+++ b/components/autofill/android/provider/BUILD.gn
@@ -29,6 +29,7 @@
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   sources = [
     "java/src/org/chromium/components/autofill/AutofillActionModeCallback.java",
+    "java/src/org/chromium/components/autofill/AutofillHintsService.java",
     "java/src/org/chromium/components/autofill/AutofillManagerWrapper.java",
     "java/src/org/chromium/components/autofill/AutofillProvider.java",
     "java/src/org/chromium/components/autofill/AutofillProviderUMA.java",
diff --git a/components/autofill/android/provider/autofill_provider_android.cc b/components/autofill/android/provider/autofill_provider_android.cc
index d897165d..652a4fe 100644
--- a/components/autofill/android/provider/autofill_provider_android.cc
+++ b/components/autofill/android/provider/autofill_provider_android.cc
@@ -159,7 +159,7 @@
   Java_AutofillProvider_startAutofillSession(
       env, obj, form_obj, index, transformed_bounding.x(),
       transformed_bounding.y(), transformed_bounding.width(),
-      transformed_bounding.height());
+      transformed_bounding.height(), handler->has_server_prediction());
 }
 
 void AutofillProviderAndroid::OnAutofillAvailable(JNIEnv* env,
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillHintsService.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillHintsService.java
new file mode 100644
index 0000000..14fd7b0e
--- /dev/null
+++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillHintsService.java
@@ -0,0 +1,74 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill;
+
+import android.os.IBinder;
+
+import org.chromium.base.Log;
+import org.chromium.components.autofill_public.IAutofillHintsService;
+import org.chromium.components.autofill_public.IViewTypeCallback;
+import org.chromium.components.autofill_public.ViewType;
+
+import java.util.List;
+
+/**
+ * This class is used to talk to autofill service about the view type.
+ */
+public class AutofillHintsService {
+    private static final String TAG = "AutofillHintsService";
+
+    public AutofillHintsService() {
+        mBinder = new IAutofillHintsService.Stub() {
+            @Override
+            public void registerViewTypeCallback(IViewTypeCallback callback) {
+                mCallback = callback;
+                if (mUnsentViewTypes != null) {
+                    invokeOnViewTypeAvailable();
+                } else if (mQueryFailed != null) {
+                    invokeOnQueryFailed();
+                }
+            }
+        };
+    }
+
+    public IBinder getBinder() {
+        return mBinder;
+    }
+
+    public void onViewTypeAvailable(List<ViewType> viewTypes) {
+        if (mUnsentViewTypes != null) return;
+        mUnsentViewTypes = viewTypes;
+        if (mCallback == null) return;
+        invokeOnViewTypeAvailable();
+    }
+
+    public void onQueryFailed() {
+        if (mQueryFailed != null) return;
+        mQueryFailed = Boolean.TRUE;
+        if (mCallback == null) return;
+        invokeOnQueryFailed();
+    }
+
+    private void invokeOnViewTypeAvailable() {
+        try {
+            mCallback.onViewTypeAvailable(mUnsentViewTypes);
+        } catch (Exception e) {
+            Log.e(TAG, "onViewTypeAvailable ", e);
+        }
+    }
+
+    private void invokeOnQueryFailed() {
+        try {
+            mCallback.onQueryFailed();
+        } catch (Exception e) {
+            Log.e(TAG, "onQueryFailed ", e);
+        }
+    }
+
+    private IAutofillHintsService.Stub mBinder;
+    private IViewTypeCallback mCallback;
+    private List<ViewType> mUnsentViewTypes;
+    private Boolean mQueryFailed;
+}
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
index d98148cd..6326536 100644
--- a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
+++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -28,6 +28,7 @@
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.annotations.VerifiesOnO;
 import org.chromium.base.metrics.ScopedSysTraceEvent;
+import org.chromium.components.autofill_public.ViewType;
 import org.chromium.components.version_info.VersionConstants;
 import org.chromium.content_public.browser.RenderCoordinates;
 import org.chromium.content_public.browser.WebContents;
@@ -37,6 +38,8 @@
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.display.DisplayAndroid;
 
+import java.util.ArrayList;
+
 /**
  * This class works with Android autofill service to fill web form, it doesn't use chrome's
  * autofill service or suggestion UI. All methods are supposed to be called in UI thread.
@@ -58,6 +61,9 @@
 @JNINamespace("autofill")
 public class AutofillProvider {
     private static final String TAG = "AutofillProvider";
+
+    // This member is initialize at first use. Not access it directly, always through
+    // isQueryServerFieldTypesEnabled().
     private static Boolean sIsQueryServerFieldTypesEnabled;
 
     private static class FocusField {
@@ -83,11 +89,19 @@
         public final int sessionId;
         private FormData mFormData;
         private FocusField mFocusField;
+        private AutofillHintsService mAutofillHintsService;
 
-        public AutofillRequest(FormData formData, FocusField focus) {
+        /**
+         * @param formData the form of the AutofillRequest.
+         * @param focus the current focused field.
+         * @param hasServerPrediction whether the server type of formData is valid.
+         */
+        public AutofillRequest(FormData formData, FocusField focus, boolean hasServerPrediction) {
             sessionId = getNextClientId();
             mFormData = formData;
             mFocusField = focus;
+            // Don't need to create binder object if server prediction is already available.
+            if (!hasServerPrediction) mAutofillHintsService = new AutofillHintsService();
         }
 
         public void fillViewStructure(ViewStructure structure) {
@@ -101,6 +115,7 @@
                 ViewStructure child = structure.newChild(index++);
                 int virtualId = toVirtualId(sessionId, fieldIndex++);
                 child.setAutofillId(structure.getAutofillId(), virtualId);
+                field.setAutofillId(child.getAutofillId());
                 if (field.mAutocompleteAttr != null && !field.mAutocompleteAttr.isEmpty()) {
                     child.setAutofillHints(field.mAutocompleteAttr.split(" +"));
                 }
@@ -256,6 +271,24 @@
         private static int toVirtualId(int clientId, short index) {
             return (clientId << 16) | index;
         }
+
+        public AutofillHintsService getAutofillHintsService() {
+            return mAutofillHintsService;
+        }
+
+        public void onQueryDone(boolean success) {
+            if (mAutofillHintsService == null) return;
+            if (success) {
+                ArrayList<ViewType> viewTypes = new ArrayList<ViewType>();
+                for (FormFieldData field : mFormData.mFields) {
+                    viewTypes.add(new ViewType(
+                            field.getAutofillId(), field.getServerType(), field.getComputedType()));
+                }
+                mAutofillHintsService.onViewTypeAvailable(viewTypes);
+            } else {
+                mAutofillHintsService.onQueryFailed();
+            }
+        }
     }
 
     private final String mProviderName;
@@ -328,6 +361,13 @@
             bundle.putCharSequence("VIRTUAL_STRUCTURE_PROVIDER_NAME", mProviderName);
             bundle.putCharSequence(
                     "VIRTUAL_STRUCTURE_PROVIDER_VERSION", VersionConstants.PRODUCT_VERSION);
+
+            if (isQueryServerFieldTypesEnabled()) {
+                AutofillHintsService autofillHintsService = mRequest.getAutofillHintsService();
+                if (autofillHintsService != null) {
+                    bundle.putBinder("AUTOFILL_HINTS_SERVICE", autofillHintsService.getBinder());
+                }
+            }
         }
         mRequest.fillViewStructure(structure);
         if (AutofillManagerWrapper.isLoggable()) {
@@ -380,10 +420,11 @@
      * @param y the boundary of focus field.
      * @param width the boundary of focus field.
      * @param height the boundary of focus field.
+     * @param hasServerPrediction whether the server prediction arrived.
      */
     @CalledByNative
-    public void startAutofillSession(
-            FormData formData, int focus, float x, float y, float width, float height) {
+    public void startAutofillSession(FormData formData, int focus, float x, float y, float width,
+            float height, boolean hasServerPrediction) {
         // Check focusField inside short value?
         // Autofill Manager might have session that wasn't started by AutofillProvider,
         // we just always cancel existing session here.
@@ -394,7 +435,8 @@
         Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
         if (mRequest != null) notifyViewExitBeforeDestroyRequest();
         transformFormFieldToContainViewCoordinates(formData);
-        mRequest = new AutofillRequest(formData, new FocusField((short) focus, absBound));
+        mRequest = new AutofillRequest(
+                formData, new FocusField((short) focus, absBound), hasServerPrediction);
         int virtualId = mRequest.getVirtualId((short) focus);
         notifyVirtualViewEntered(mContainerView, virtualId, absBound);
         mAutofillUMA.onSessionStarted(mAutofillManager.isDisabled());
@@ -713,6 +755,7 @@
 
     @CalledByNative
     private void onQueryDone(boolean success) {
+        mRequest.onQueryDone(success);
         mAutofillManager.onQueryDone(success);
     }
 
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java
index 4e01a39..0ab8cdf 100644
--- a/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java
+++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java
@@ -5,6 +5,7 @@
 package org.chromium.components.autofill;
 
 import android.graphics.RectF;
+import android.view.autofill.AutofillId;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.VisibleForTesting;
@@ -67,6 +68,7 @@
     // after the object instantiated.
     private String mServerType;
     private String mComputedType;
+    private AutofillId mAutofillId;
 
     private FormFieldData(String name, String label, String value, String autocompleteAttr,
             boolean shouldAutocomplete, String placeholder, String type, String id,
@@ -172,6 +174,14 @@
         mAutofilled = autofilled;
     }
 
+    public void setAutofillId(AutofillId id) {
+        mAutofillId = id;
+    }
+
+    public AutofillId getAutofillId() {
+        return mAutofillId;
+    }
+
     @CalledByNative
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     public static FormFieldData createFormFieldData(String name, String label, String value,
diff --git a/components/autofill/android/provider/test_support/BUILD.gn b/components/autofill/android/provider/test_support/BUILD.gn
index a3c9804..74b3f5f 100644
--- a/components/autofill/android/provider/test_support/BUILD.gn
+++ b/components/autofill/android/provider/test_support/BUILD.gn
@@ -10,11 +10,14 @@
 android_library("component_autofill_provider_java_test_support") {
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   sources = [
+    "java/src/org/chromium/components/autofill/AutofillHintsServiceTestHelper.java",
     "java/src/org/chromium/components/autofill/AutofillProviderTestHelper.java",
   ]
   deps = [
     "//base:base_java",
+    "//base:base_java_test_support",
     "//base:jni_java",
+    "//components/autofill/android/provider:autofill_aidl",
     "//components/autofill/android/provider:java",
     "//content/public/android:content_java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
diff --git a/components/autofill/android/provider/test_support/java/src/org/chromium/components/autofill/AutofillHintsServiceTestHelper.java b/components/autofill/android/provider/test_support/java/src/org/chromium/components/autofill/AutofillHintsServiceTestHelper.java
new file mode 100644
index 0000000..742e98d7
--- /dev/null
+++ b/components/autofill/android/provider/test_support/java/src/org/chromium/components/autofill/AutofillHintsServiceTestHelper.java
@@ -0,0 +1,57 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill;
+
+import android.os.IBinder;
+
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.components.autofill_public.IAutofillHintsService;
+import org.chromium.components.autofill_public.IViewTypeCallback;
+import org.chromium.components.autofill_public.ViewType;
+
+import java.util.List;
+
+/**
+ * This class implements and registers IViewTypeCallback for testing.
+ */
+public class AutofillHintsServiceTestHelper {
+    public void registerViewTypeService(IBinder binder) throws Exception {
+        IAutofillHintsService.Stub.asInterface(binder).registerViewTypeCallback(getBinder());
+    }
+
+    private IViewTypeCallback.Stub mBinder = new IViewTypeCallback.Stub() {
+        @Override
+        public void onViewTypeAvailable(List<ViewType> viewTypeList) {
+            mViewTypeList = viewTypeList;
+            mCallbackHelper.notifyCalled();
+        }
+
+        @Override
+        public void onQueryFailed() {
+            mQueryFailed = true;
+            mCallbackHelper.notifyCalled();
+        }
+    };
+
+    private List<ViewType> mViewTypeList;
+    private boolean mQueryFailed;
+    private CallbackHelper mCallbackHelper = new CallbackHelper();
+
+    public IViewTypeCallback getBinder() {
+        return mBinder;
+    }
+
+    public List<ViewType> getViewTypes() {
+        return mViewTypeList;
+    }
+
+    public boolean isQueryFailed() {
+        return mQueryFailed;
+    }
+
+    public void waitForCallbackInvoked() throws Exception {
+        mCallbackHelper.waitForCallback(0);
+    }
+}
diff --git a/components/cronet/stale_host_resolver.cc b/components/cronet/stale_host_resolver.cc
index fbbfc7de0a..f064359 100644
--- a/components/cronet/stale_host_resolver.cc
+++ b/components/cronet/stale_host_resolver.cc
@@ -47,6 +47,8 @@
       const override;
   const base::Optional<std::vector<net::HostPortPair>>& GetHostnameResults()
       const override;
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override;
   net::ResolveErrorInfo GetResolveErrorInfo() const override;
   const base::Optional<net::HostCache::EntryStaleness>& GetStaleInfo()
       const override;
@@ -203,6 +205,15 @@
   return cache_request_->GetHostnameResults();
 }
 
+const base::Optional<std::vector<std::string>>&
+StaleHostResolver::RequestImpl::GetDnsAliasResults() const {
+  if (network_request_)
+    return network_request_->GetDnsAliasResults();
+
+  DCHECK(cache_request_);
+  return cache_request_->GetDnsAliasResults();
+}
+
 net::ResolveErrorInfo StaleHostResolver::RequestImpl::GetResolveErrorInfo()
     const {
   if (network_request_)
diff --git a/components/exo/drag_drop_operation.cc b/components/exo/drag_drop_operation.cc
index 9f2bcb90..1f0b100 100644
--- a/components/exo/drag_drop_operation.cc
+++ b/components/exo/drag_drop_operation.cc
@@ -276,7 +276,8 @@
   DCHECK(icon_);
 
   float scale_factor = origin_->get()->window()->layer()->device_scale_factor();
-  gfx::ImageSkia icon_skia(gfx::ImageSkiaRep(icon_bitmap, scale_factor));
+  gfx::ImageSkia icon_skia =
+      gfx::ImageSkia::CreateFromBitmap(icon_bitmap, scale_factor);
   gfx::Vector2d icon_offset = -icon_->get()->GetBufferOffset();
 
   if (os_exchange_data_) {
diff --git a/components/favicon_base/select_favicon_frames.cc b/components/favicon_base/select_favicon_frames.cc
index 6694ddd..6d482593 100644
--- a/components/favicon_base/select_favicon_frames.cc
+++ b/components/favicon_base/select_favicon_frames.cc
@@ -240,7 +240,7 @@
 
   if (desired_size_in_dip == 0) {
     size_t index = results[0].index;
-    return gfx::ImageSkia(gfx::ImageSkiaRep(bitmaps[index], 1.0f));
+    return gfx::ImageSkia::CreateFromBitmap(bitmaps[index], 1.0f);
   }
 
   auto image_source = std::make_unique<FaviconImageSource>();
diff --git a/components/paint_preview/browser/paint_preview_client.cc b/components/paint_preview/browser/paint_preview_client.cc
index d9e7dbd..d518cc3 100644
--- a/components/paint_preview/browser/paint_preview_client.cc
+++ b/components/paint_preview/browser/paint_preview_client.cc
@@ -560,16 +560,18 @@
     // At a minimum one frame was captured successfully, it is up to the
     // caller to decide if a partial success is acceptable based on what is
     // contained in the proto.
-    std::move(document_data->callback)
-        .Run(guid,
-             document_data->had_error
-                 ? mojom::PaintPreviewStatus::kPartialSuccess
-                 : mojom::PaintPreviewStatus::kOk,
-             std::move(*document_data).IntoCaptureResult());
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(std::move(document_data->callback), guid,
+                       document_data->had_error
+                           ? mojom::PaintPreviewStatus::kPartialSuccess
+                           : mojom::PaintPreviewStatus::kOk,
+                       std::move(*document_data).IntoCaptureResult()));
   } else {
     // A proto could not be created indicating all frames failed to capture.
-    std::move(document_data->callback)
-        .Run(guid, mojom::PaintPreviewStatus::kFailed, {});
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(document_data->callback), guid,
+                                  mojom::PaintPreviewStatus::kFailed, nullptr));
   }
   all_document_data_.erase(guid);
 }
diff --git a/components/performance_manager/decorators/freezing_vote_decorator.cc b/components/performance_manager/decorators/freezing_vote_decorator.cc
index b314314e7..ba683602 100644
--- a/components/performance_manager/decorators/freezing_vote_decorator.cc
+++ b/components/performance_manager/decorators/freezing_vote_decorator.cc
@@ -18,9 +18,11 @@
 
 void FreezingVoteDecorator::OnPassedToGraph(Graph* graph) {
   graph->RegisterObject(&freezing_vote_aggregator_);
+  freezing_vote_aggregator_.RegisterNodeDataDescriber(graph);
 }
 
 void FreezingVoteDecorator::OnTakenFromGraph(Graph* graph) {
+  freezing_vote_aggregator_.UnregisterNodeDataDescriber(graph);
   graph->UnregisterObject(&freezing_vote_aggregator_);
 }
 
diff --git a/components/performance_manager/freezing/freezing.cc b/components/performance_manager/freezing/freezing.cc
index 90bb84f7..71c4b0f 100644
--- a/components/performance_manager/freezing/freezing.cc
+++ b/components/performance_manager/freezing/freezing.cc
@@ -137,5 +137,13 @@
                                                  vote_reason);
 }
 
+const char* FreezingVoteValueToString(FreezingVoteValue freezing_vote_value) {
+  if (freezing_vote_value == freezing::FreezingVoteValue::kCanFreeze) {
+    return "kCanFreeze";
+  } else {
+    return "kCannotFreeze";
+  }
+}
+
 }  // namespace freezing
 }  // namespace performance_manager
\ No newline at end of file
diff --git a/components/performance_manager/freezing/freezing_vote_aggregator.cc b/components/performance_manager/freezing/freezing_vote_aggregator.cc
index b6d7da0..07ca8482 100644
--- a/components/performance_manager/freezing/freezing_vote_aggregator.cc
+++ b/components/performance_manager/freezing/freezing_vote_aggregator.cc
@@ -7,10 +7,17 @@
 #include <algorithm>
 
 #include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
+#include "components/performance_manager/public/freezing/freezing.h"
+#include "components/performance_manager/public/graph/node_data_describer_registry.h"
 
 namespace performance_manager {
 namespace freezing {
 
+namespace {
+const char kDescriberName[] = "FreezingVoteAggregator";
+}
+
 FreezingVoteAggregator::FreezingVoteAggregator()
     : vote_consumer_default_impl_(this) {}
 FreezingVoteAggregator::~FreezingVoteAggregator() = default;
@@ -101,6 +108,26 @@
     channel_.ChangeVote(page_node, new_chosen_vote);
 }
 
+void FreezingVoteAggregator::RegisterNodeDataDescriber(Graph* graph) {
+  graph->GetNodeDataDescriberRegistry()->RegisterDescriber(this,
+                                                           kDescriberName);
+}
+
+void FreezingVoteAggregator::UnregisterNodeDataDescriber(Graph* graph) {
+  graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this);
+}
+
+base::Value FreezingVoteAggregator::DescribePageNodeData(
+    const PageNode* node) const {
+  auto votes_for_page = vote_data_map_.find(node);
+  if (votes_for_page == vote_data_map_.end())
+    return base::Value();
+
+  base::Value ret(base::Value::Type::DICTIONARY);
+  votes_for_page->second.DescribeVotes(&ret);
+  return ret;
+}
+
 FreezingVoteAggregator::FreezingVoteData::FreezingVoteData() = default;
 FreezingVoteAggregator::FreezingVoteData::FreezingVoteData(FreezingVoteData&&) =
     default;
@@ -138,6 +165,17 @@
   return votes_.begin()->second;
 }
 
+void FreezingVoteAggregator::FreezingVoteData::DescribeVotes(
+    base::Value* ret) const {
+  size_t i = 0;
+  for (const auto& it : votes_) {
+    ret->SetStringKey(
+        base::StringPrintf("Vote %zu (%s)", i++,
+                           FreezingVoteValueToString(it.second.value())),
+        it.second.reason());
+  }
+}
+
 FreezingVoteAggregator::FreezingVoteData::VotesDeque::iterator
 FreezingVoteAggregator::FreezingVoteData::FindVote(FreezingVoterId voter_id) {
   // TODO(sebmarchand): Consider doing a reverse search for kCanFreeze votes and
diff --git a/components/performance_manager/freezing/freezing_vote_aggregator.h b/components/performance_manager/freezing/freezing_vote_aggregator.h
index 09d9765..3cbb0585 100644
--- a/components/performance_manager/freezing/freezing_vote_aggregator.h
+++ b/components/performance_manager/freezing/freezing_vote_aggregator.h
@@ -10,6 +10,7 @@
 #include "base/containers/flat_map.h"
 #include "components/performance_manager/public/freezing/freezing.h"
 #include "components/performance_manager/public/graph/graph_registered.h"
+#include "components/performance_manager/public/graph/node_data_describer.h"
 #include "components/performance_manager/public/voting/voting.h"
 
 namespace performance_manager {
@@ -33,6 +34,7 @@
 //     graph()->GetRegisteredObjectAs<freezing::FreezingVoteAggregator>();
 class FreezingVoteAggregator final
     : public FreezingVoteObserver,
+      public NodeDataDescriberDefaultImpl,
       public GraphRegisteredImpl<FreezingVoteAggregator> {
  public:
   FreezingVoteAggregator(const FreezingVoteAggregator& rhs) = delete;
@@ -55,6 +57,12 @@
   void OnVoteInvalidated(FreezingVoterId voter_id,
                          const PageNode* page_node) override;
 
+  void RegisterNodeDataDescriber(Graph* graph);
+  void UnregisterNodeDataDescriber(Graph* graph);
+
+  // NodeDataDescriber implementation:
+  base::Value DescribePageNodeData(const PageNode* node) const override;
+
  private:
   friend class performance_manager::FreezingVoteDecorator;
   friend class FreezingVoteAggregatorTest;
@@ -105,6 +113,9 @@
     // Returns the chosen vote. Invalid to call if IsEmpty() is true.
     const FreezingVote& GetChosenVote();
 
+    // Helper for FreezingVoteAggregator::DescribePageNodeData.
+    void DescribeVotes(base::Value* ret) const;
+
    private:
     friend class FreezingVoteAggregatorTestAccess;
 
diff --git a/components/performance_manager/graph/page_node_impl_describer.cc b/components/performance_manager/graph/page_node_impl_describer.cc
index 6fb1f812..d05cd86 100644
--- a/components/performance_manager/graph/page_node_impl_describer.cc
+++ b/components/performance_manager/graph/page_node_impl_describer.cc
@@ -4,8 +4,10 @@
 
 #include "components/performance_manager/graph/page_node_impl_describer.h"
 
+#include "base/optional.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/performance_manager/graph/page_node_impl.h"
+#include "components/performance_manager/public/freezing/freezing.h"
 #include "components/performance_manager/public/graph/node_data_describer_registry.h"
 #include "components/performance_manager/public/graph/node_data_describer_util.h"
 
@@ -15,6 +17,14 @@
 
 const char kDescriberName[] = "PageNodeImpl";
 
+const char* FreezingVoteToString(
+    base::Optional<freezing::FreezingVote> freezing_vote) {
+  if (!freezing_vote)
+    return "None";
+
+  return freezing::FreezingVoteValueToString(freezing_vote->value());
+}
+
 }  // namespace
 
 PageNodeImplDescriber::PageNodeImplDescriber() = default;
@@ -79,6 +89,8 @@
     result.SetStringKey("opened_type",
                         PageNode::ToString(page_node_impl->opened_type_));
   }
+  result.SetStringKey("freezing_vote",
+                      FreezingVoteToString(page_node_impl->freezing_vote()));
 
   return result;
 }
diff --git a/components/performance_manager/graph_features_helper_unittest.cc b/components/performance_manager/graph_features_helper_unittest.cc
index cf0d6b1..353aeb1 100644
--- a/components/performance_manager/graph_features_helper_unittest.cc
+++ b/components/performance_manager/graph_features_helper_unittest.cc
@@ -61,7 +61,7 @@
   features.ConfigureGraph(&graph);
   EXPECT_EQ(graph_owned_count, graph.GraphOwnedCountForTesting());
   EXPECT_EQ(3u, graph.GraphRegisteredCountForTesting());
-  EXPECT_EQ(8u, graph.NodeDataDescriberCountForTesting());
+  EXPECT_EQ(9u, graph.NodeDataDescriberCountForTesting());
   // Ensure the GraphRegistered objects can be queried directly.
   EXPECT_TRUE(
       execution_context::ExecutionContextRegistry::GetFromGraph(&graph));
diff --git a/components/performance_manager/public/freezing/freezing.h b/components/performance_manager/public/freezing/freezing.h
index 10eaadefa..8a12cf8 100644
--- a/components/performance_manager/public/freezing/freezing.h
+++ b/components/performance_manager/public/freezing/freezing.h
@@ -56,6 +56,9 @@
     FreezingVoteValue vote_value,
     const char* vote_reason);
 
+// Converts a FreezingVoteValue to a textual representation.
+const char* FreezingVoteValueToString(FreezingVoteValue freezing_vote_value);
+
 }  // namespace freezing
 }  // namespace performance_manager
 
diff --git a/components/policy/proto/record.proto b/components/policy/proto/record.proto
index 1450db6..7c84adc 100644
--- a/components/policy/proto/record.proto
+++ b/components/policy/proto/record.proto
@@ -66,7 +66,7 @@
   // Hash of the public key used to do encryption. Used to identity the
   // private key for decryption. If no key_id is present, it is assumed that
   // |key| has been transferred in plaintext.
-  optional uint64 public_key_id = 2;
+  optional int64 public_key_id = 2;
 }
 
 // Tracking information for what order a record appears in.
@@ -78,11 +78,11 @@
   // certain number is absent when higher are encountered, it indicates that
   // some records have been lost and there is a gap in the records stream
   // (what to do with that is a decision that the caller needs to make).
-  optional uint64 sequencing_id = 1;
+  optional int64 sequencing_id = 1;
 
   // Generation ID (required). Unique per device and priority. Generated anew
   // when previous record digest is not found at startup (e.g. after powerwash).
-  optional uint64 generation_id = 2;
+  optional int64 generation_id = 2;
 
   // Priority (required).
   optional Priority priority = 3;
@@ -116,7 +116,7 @@
 
   // Public key id (required).
   // Identifies private key matching |public_asymmetric_key| for the server.
-  optional uint64 public_key_id = 2;
+  optional int64 public_key_id = 2;
 
   // Signature of |public_asymmetric_key| (required).
   // Verified by client against a well-known signature.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 7e7aed6..7215584 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -2352,7 +2352,7 @@
       'tags': [],
       'desc': '''Setting the policy to Enabled or leaving it unset lets users print in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>, and users can't change this setting.
 
-      Setting the policy to Disabled means users can't print from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. Printing is off in the wrench menu, extensions, and JavaScript applications. It's only possible to print from plugins that bypass <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> while printing.''',
+      Setting the policy to Disabled means users can't print from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. Printing is off in the three dots menu, extensions, and JavaScript applications.''',
       'arc_support': 'This policy has no effect on Android apps.',
     },
     {
@@ -20327,16 +20327,19 @@
       'owners': ['llin@google.com'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
-      'supported_on': ['chrome_os:84-'],
+      'supported_on': ['chrome_os:84-88'],
       'tags' : ['google-sharing'],
       'features': {
         'dynamic_refresh': True,
         'per_profile': True,
       },
+      'deprecated': True,
       'example_value': True,
       'id': 694,
       'caption': '''Allow Quick Answers to access selected content''',
-      'desc': '''This policy gives Quick Answers permission to access selected content and send the info to server.
+      'desc': '''This policy is deprecated and will be removed in <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> version 89.
+
+      This policy gives Quick Answers permission to access selected content and send the info to server.
 
       If the policy is enabled, Quick Answers will be allowed to access selected content.
       If the policy is disabled, Quick Answers will not be allowed to access selected content.
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
index cc236b1..76523b2 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -13,6 +13,7 @@
 #include "components/safe_browsing/core/browser/url_checker_delegate.h"
 #include "components/safe_browsing/core/common/safebrowsing_constants.h"
 #include "components/safe_browsing/core/common/thread_utils.h"
+#include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/features.h"
 #include "components/safe_browsing/core/realtime/policy_engine.h"
 #include "components/safe_browsing/core/realtime/url_lookup_service_base.h"
@@ -87,8 +88,12 @@
 
 SafeBrowsingUrlCheckerImpl::UrlInfo::UrlInfo(const GURL& in_url,
                                              const std::string& in_method,
-                                             Notifier in_notifier)
-    : url(in_url), method(in_method), notifier(std::move(in_notifier)) {}
+                                             Notifier in_notifier,
+                                             bool in_is_cached_safe_url)
+    : url(in_url),
+      method(in_method),
+      notifier(std::move(in_notifier)),
+      is_cached_safe_url(in_is_cached_safe_url) {}
 
 SafeBrowsingUrlCheckerImpl::UrlInfo::UrlInfo(UrlInfo&& other) = default;
 
@@ -215,6 +220,10 @@
 
   timer_.Stop();
   RecordCheckUrlTimeout(/*timed_out=*/false);
+  if (urls_[next_index_].is_cached_safe_url) {
+    UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.RT.GetCache.FallbackThreatType",
+                              threat_type, SB_THREAT_TYPE_MAX + 1);
+  }
 
   TRACE_EVENT_ASYNC_END1("safe_browsing", "CheckUrl", this, "url", url.spec());
 
@@ -304,7 +313,8 @@
   DCHECK(CurrentlyOnThread(ThreadID::IO));
 
   DVLOG(1) << "SafeBrowsingUrlCheckerImpl checks URL: " << url;
-  urls_.emplace_back(url, method, std::move(notifier));
+  urls_.emplace_back(url, method, std::move(notifier),
+                     /*safe_from_real_time_cache=*/false);
 
   ProcessUrls();
 }
@@ -616,14 +626,12 @@
   if (response && (response->threat_info_size() > 0) &&
       response->threat_info(0).verdict_type() ==
           RTLookupResponse::ThreatInfo::DANGEROUS) {
-    // TODO(crbug.com/1033692): Only take the first threat info into account
-    // because threat infos are returned in decreasing order of severity.
-    // Consider extend it to support multiple threat types.
     sb_threat_type =
         RealTimeUrlLookupServiceBase::GetSBThreatTypeForRTThreatType(
             response->threat_info(0).threat_type());
   }
   if (is_cached_response && sb_threat_type == SB_THREAT_TYPE_SAFE) {
+    urls_[next_index_].is_cached_safe_url = true;
     PerformHashBasedCheck(url);
   } else {
     OnUrlResult(url, sb_threat_type, ThreatMetadata(),
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h
index 0a02615d..6cdbabc7 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h
@@ -230,7 +230,10 @@
   };
 
   struct UrlInfo {
-    UrlInfo(const GURL& url, const std::string& method, Notifier notifier);
+    UrlInfo(const GURL& url,
+            const std::string& method,
+            Notifier notifier,
+            bool is_cached_safe_url);
     UrlInfo(UrlInfo&& other);
 
     ~UrlInfo();
@@ -238,6 +241,9 @@
     GURL url;
     std::string method;
     Notifier notifier;
+    // If the URL is classified as safe in cache manager during real time
+    // lookup.
+    bool is_cached_safe_url;
   };
 
   const net::HttpRequestHeaders headers_;
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
index 2e29688..d1785fd5 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
@@ -7,12 +7,14 @@
 
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "components/safe_browsing/core/browser/url_checker_delegate.h"
 #include "components/safe_browsing/core/common/test_task_environment.h"
 #include "components/safe_browsing/core/common/thread_utils.h"
 #include "components/safe_browsing/core/db/test_database_manager.h"
+#include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/proto/csd.pb.h"
 #include "components/safe_browsing/core/realtime/url_lookup_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -203,19 +205,24 @@
     threat_info.set_threat_type(threat_type);
     threat_info.set_verdict_type(verdict_type);
     *new_threat_info = threat_info;
-    base::PostTask(
-        FROM_HERE, CreateTaskTraits(ThreadID::IO),
-        base::BindOnce(std::move(response_callback),
-                       /* is_rt_lookup_successful */ true,
-                       /* is_cached_response */ false, std::move(response)));
+    base::PostTask(FROM_HERE, CreateTaskTraits(ThreadID::IO),
+                   base::BindOnce(std::move(response_callback),
+                                  /* is_rt_lookup_successful */ true,
+                                  /* is_cached_response */ is_cached_response_,
+                                  std::move(response)));
   }
 
   void SetThreatTypeForUrl(const GURL& gurl, SBThreatType threat_type) {
     urls_threat_type_[gurl.spec()] = threat_type;
   }
 
+  void SetIsCachedResponse(bool is_cached_response) {
+    is_cached_response_ = is_cached_response;
+  }
+
  private:
   base::flat_map<std::string, SBThreatType> urls_threat_type_;
+  bool is_cached_response_ = false;
 };
 
 class SafeBrowsingUrlCheckerTest : public PlatformTest {
@@ -384,6 +391,7 @@
 }
 
 TEST_F(SafeBrowsingUrlCheckerTest, CheckUrl_RealTimeEnabledSafeUrl) {
+  base::HistogramTester histograms;
   auto safe_browsing_url_checker = CreateSafeBrowsingUrlChecker(
       /*real_time_lookup_enabled=*/true, /*can_check_safe_browsing_db=*/true);
 
@@ -401,6 +409,67 @@
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
   task_environment_->RunUntilIdle();
+
+  // The false positive metric should not be logged, because the
+  // verdict is not from cache.
+  histograms.ExpectTotalCount("SafeBrowsing.RT.GetCache.FallbackThreatType",
+                              /* total_count */ 0);
+}
+
+TEST_F(SafeBrowsingUrlCheckerTest, CheckUrl_RealTimeEnabledSafeUrlFromCache) {
+  base::HistogramTester histograms;
+  auto safe_browsing_url_checker = CreateSafeBrowsingUrlChecker(
+      /*real_time_lookup_enabled=*/true, /*can_check_safe_browsing_db=*/true);
+
+  GURL url("https://example.test/");
+  database_manager_->SetAllowlistResultForUrl(url, AsyncMatch::NO_MATCH);
+  database_manager_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_SAFE,
+                                         /*delayed_callback=*/false);
+  url_lookup_service_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_SAFE);
+  url_lookup_service_->SetIsCachedResponse(true);
+
+  base::MockCallback<SafeBrowsingUrlCheckerImpl::NativeCheckUrlCallback>
+      callback;
+  EXPECT_CALL(callback,
+              Run(_, /*proceed=*/true, /*showed_interstitial=*/false));
+  EXPECT_CALL(*url_checker_delegate_,
+              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+      .Times(0);
+  safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
+
+  task_environment_->RunUntilIdle();
+
+  histograms.ExpectUniqueSample("SafeBrowsing.RT.GetCache.FallbackThreatType",
+                                /* sample */ SB_THREAT_TYPE_SAFE,
+                                /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingUrlCheckerTest,
+       CheckUrl_RealTimeEnabledSafeUrlFromCacheFalsePositive) {
+  base::HistogramTester histograms;
+  auto safe_browsing_url_checker = CreateSafeBrowsingUrlChecker(
+      /*real_time_lookup_enabled=*/true, /*can_check_safe_browsing_db=*/true);
+
+  GURL url("https://example.test/");
+  database_manager_->SetAllowlistResultForUrl(url, AsyncMatch::NO_MATCH);
+  database_manager_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_URL_PHISHING,
+                                         /*delayed_callback=*/false);
+  url_lookup_service_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_SAFE);
+  url_lookup_service_->SetIsCachedResponse(true);
+
+  base::MockCallback<SafeBrowsingUrlCheckerImpl::NativeCheckUrlCallback>
+      callback;
+  EXPECT_CALL(*url_checker_delegate_,
+              StartDisplayingBlockingPageHelper(
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+      .Times(1);
+  safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
+
+  task_environment_->RunUntilIdle();
+
+  histograms.ExpectUniqueSample("SafeBrowsing.RT.GetCache.FallbackThreatType",
+                                /* sample */ SB_THREAT_TYPE_URL_PHISHING,
+                                /* expected_count */ 1);
 }
 
 TEST_F(SafeBrowsingUrlCheckerTest,
diff --git a/components/safe_browsing/core/db/v4_protocol_manager_util.h b/components/safe_browsing/core/db/v4_protocol_manager_util.h
index b81ab05..823b6b38 100644
--- a/components/safe_browsing/core/db/v4_protocol_manager_util.h
+++ b/components/safe_browsing/core/db/v4_protocol_manager_util.h
@@ -94,89 +94,93 @@
 
 // Different types of threats that SafeBrowsing protects against. This is the
 // type that's returned to the clients of SafeBrowsing in Chromium.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.safe_browsing
 // GENERATED_JAVA_PREFIX_TO_STRIP: SB_THREAT_TYPE_
 enum SBThreatType {
   // This type can be used for lists that can be checked synchronously so a
   // client callback isn't required, or for whitelists.
-  SB_THREAT_TYPE_UNUSED,
+  SB_THREAT_TYPE_UNUSED = 0,
 
   // No threat at all.
-  SB_THREAT_TYPE_SAFE,
+  SB_THREAT_TYPE_SAFE = 1,
 
   // The URL is being used for phishing.
-  SB_THREAT_TYPE_URL_PHISHING,
+  SB_THREAT_TYPE_URL_PHISHING = 2,
 
   // The URL hosts malware.
-  SB_THREAT_TYPE_URL_MALWARE,
+  SB_THREAT_TYPE_URL_MALWARE = 3,
 
   // The URL hosts unwanted programs.
-  SB_THREAT_TYPE_URL_UNWANTED,
+  SB_THREAT_TYPE_URL_UNWANTED = 4,
 
   // The download URL is malware.
-  SB_THREAT_TYPE_URL_BINARY_MALWARE,
+  SB_THREAT_TYPE_URL_BINARY_MALWARE = 5,
 
   // Url detected by the client-side phishing model.  Note that unlike the
   // above values, this does not correspond to a downloaded list.
-  SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING,
+  SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING = 6,
 
   // The Chrome extension or app (given by its ID) is malware.
-  SB_THREAT_TYPE_EXTENSION,
+  SB_THREAT_TYPE_EXTENSION = 7,
 
   // Url detected by the client-side malware IP list. This IP list is part
   // of the client side detection model.
-  SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE,
+  SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE = 8,
 
   // Url leads to a blacklisted resource script. Note that no warnings should be
   // shown on this threat type, but an incident report might be sent.
-  SB_THREAT_TYPE_BLACKLISTED_RESOURCE,
+  SB_THREAT_TYPE_BLACKLISTED_RESOURCE = 9,
 
   // Url abuses a permission API.
-  SB_THREAT_TYPE_API_ABUSE,
+  SB_THREAT_TYPE_API_ABUSE = 10,
 
   // Activation patterns for the Subresource Filter.
-  SB_THREAT_TYPE_SUBRESOURCE_FILTER,
+  SB_THREAT_TYPE_SUBRESOURCE_FILTER = 11,
 
   // CSD Phishing whitelist.  This "threat" means a URL matched the whitelist.
-  SB_THREAT_TYPE_CSD_WHITELIST,
+  SB_THREAT_TYPE_CSD_WHITELIST = 12,
 
   // DEPRECATED. Url detected by password protection service.
-  DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING,
+  DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING = 13,
 
   // Saved password reuse detected on low reputation page,
-  SB_THREAT_TYPE_SAVED_PASSWORD_REUSE,
+  SB_THREAT_TYPE_SAVED_PASSWORD_REUSE = 14,
 
   // Chrome signed in and syncing gaia password reuse detected on low reputation
   // page,
-  SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE,
+  SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE = 15,
 
   // Chrome signed in non syncing gaia password reuse detected on low reputation
   // page,
-  SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE,
+  SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE = 16,
 
   // A Google ad that caused a blocked autoredirect was collected
-  SB_THREAT_TYPE_BLOCKED_AD_REDIRECT,
+  SB_THREAT_TYPE_BLOCKED_AD_REDIRECT = 17,
 
   // A sample of an ad was collected
-  SB_THREAT_TYPE_AD_SAMPLE,
+  SB_THREAT_TYPE_AD_SAMPLE = 18,
 
   // A report of Google ad that caused a blocked popup was collected.
-  SB_THREAT_TYPE_BLOCKED_AD_POPUP,
+  SB_THREAT_TYPE_BLOCKED_AD_POPUP = 19,
 
   // The page loaded a resource from the Suspicious Site list.
-  SB_THREAT_TYPE_SUSPICIOUS_SITE,
+  SB_THREAT_TYPE_SUSPICIOUS_SITE = 20,
 
   // Enterprise password reuse detected on low reputation page.
-  SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE,
+  SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE = 21,
 
   // Potential billing detected.
-  SB_THREAT_TYPE_BILLING,
+  SB_THREAT_TYPE_BILLING = 22,
 
   // Off-market APK file downloaded, which could be potentially dangerous.
-  SB_THREAT_TYPE_APK_DOWNLOAD,
+  SB_THREAT_TYPE_APK_DOWNLOAD = 23,
 
   // Match found in the local high-confidence allowlist.
-  SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST,
+  SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST = 24,
+
+  SB_THREAT_TYPE_MAX = SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST,
 };
 
 using SBThreatTypeSet = base::flat_set<SBThreatType>;
diff --git a/components/sync/protocol/session_specifics.proto b/components/sync/protocol/session_specifics.proto
index c598a1d..5bd9b73 100644
--- a/components/sync/protocol/session_specifics.proto
+++ b/components/sync/protocol/session_specifics.proto
@@ -19,7 +19,8 @@
 import "components/sync/protocol/sync_enums.proto";
 
 message SessionSpecifics {
-  // Unique id for the client.
+  // Unique id for the client. M89 and higher use sync's cache GUID (client ID)
+  // to populate this tag for *new* sessions.
   optional string session_tag = 1;
   optional SessionHeader header = 2;
   optional SessionTab tab = 3;
diff --git a/components/sync_sessions/mock_sync_sessions_client.h b/components/sync_sessions/mock_sync_sessions_client.h
index 52e4f6b..f7180744 100644
--- a/components/sync_sessions/mock_sync_sessions_client.h
+++ b/components/sync_sessions/mock_sync_sessions_client.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_SYNC_SESSIONS_MOCK_SYNC_SESSIONS_CLIENT_H_
 #define COMPONENTS_SYNC_SESSIONS_MOCK_SYNC_SESSIONS_CLIENT_H_
 
+#include <string>
+
 #include "components/sync_sessions/sync_sessions_client.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "url/gurl.h"
@@ -23,6 +25,10 @@
               (override));
   MOCK_METHOD(void, ClearAllOnDemandFavicons, (), (override));
   MOCK_METHOD(bool, ShouldSyncURL, (const GURL& url), (const override));
+  MOCK_METHOD(bool,
+              IsRecentLocalCacheGuid,
+              (const std::string& cache_guid),
+              (const override));
   MOCK_METHOD(SyncedWindowDelegatesGetter*,
               GetSyncedWindowDelegatesGetter,
               (),
diff --git a/components/sync_sessions/session_store.cc b/components/sync_sessions/session_store.cc
index 8cea1e8..3f4c5a3 100644
--- a/components/sync_sessions/session_store.cc
+++ b/components/sync_sessions/session_store.cc
@@ -12,6 +12,7 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/feature_list.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
@@ -26,6 +27,7 @@
 #include "components/sync/protocol/sync.pb.h"
 #include "components/sync_device_info/local_device_info_util.h"
 #include "components/sync_sessions/session_sync_prefs.h"
+#include "components/sync_sessions/switches.h"
 #include "components/sync_sessions/sync_sessions_client.h"
 
 namespace sync_sessions {
@@ -80,16 +82,24 @@
 std::string GetSessionTagWithPrefs(const std::string& cache_guid,
                                    SessionSyncPrefs* sync_prefs) {
   DCHECK(sync_prefs);
-  const std::string persisted_guid = sync_prefs->GetSyncSessionsGUID();
+
+  // If a legacy GUID exists, keep honoring it.
+  const std::string persisted_guid = sync_prefs->GetLegacySyncSessionsGUID();
   if (!persisted_guid.empty()) {
     DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid;
     return persisted_guid;
   }
 
+  if (base::FeatureList::IsEnabled(
+          switches::kSyncUseCacheGuidAsSyncSessionTag)) {
+    DVLOG(1) << "Using sync cache guid as session sync guid: " << cache_guid;
+    return cache_guid;
+  }
+
   const std::string new_guid =
       base::StringPrintf("session_sync%s", cache_guid.c_str());
   DVLOG(1) << "Creating session sync guid: " << new_guid;
-  sync_prefs->SetSyncSessionsGUID(new_guid);
+  sync_prefs->SetLegacySyncSessionsGUID(new_guid);
   return new_guid;
 }
 
@@ -407,6 +417,7 @@
     SyncSessionsClient* sessions_client)
     : local_session_info_(local_session_info),
       store_(std::move(underlying_store)),
+      sessions_client_(sessions_client),
       session_tracker_(sessions_client) {
   session_tracker_.InitLocalSession(local_session_info_.session_tag,
                                     local_session_info_.client_name,
@@ -542,6 +553,11 @@
   session_tracker_.Clear();
   store_->DeleteAllDataAndMetadata(base::DoNothing());
 
+  if (base::FeatureList::IsEnabled(
+          switches::kSyncUseCacheGuidAsSyncSessionTag)) {
+    sessions_client_->GetSessionSyncPrefs()->ClearLegacySyncSessionsGUID();
+  }
+
   // At all times, the local session must be tracked.
   session_tracker_.InitLocalSession(local_session_info_.session_tag,
                                     local_session_info_.client_name,
diff --git a/components/sync_sessions/session_store.h b/components/sync_sessions/session_store.h
index 42060e6..b209305a 100644
--- a/components/sync_sessions/session_store.h
+++ b/components/sync_sessions/session_store.h
@@ -162,6 +162,8 @@
   // In charge of actually persisting changes to disk.
   const std::unique_ptr<syncer::ModelTypeStore> store_;
 
+  SyncSessionsClient* const sessions_client_;
+
   SyncedSessionTracker session_tracker_;
 
   base::WeakPtrFactory<SessionStore> weak_ptr_factory_{this};
diff --git a/components/sync_sessions/session_store_unittest.cc b/components/sync_sessions/session_store_unittest.cc
index 5f19bee..6b17daa 100644
--- a/components/sync_sessions/session_store_unittest.cc
+++ b/components/sync_sessions/session_store_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/cancelable_callback.h"
 #include "base/run_loop.h"
 #include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/sync/base/hash_util.h"
@@ -22,6 +23,7 @@
 #include "components/sync_device_info/local_device_info_util.h"
 #include "components/sync_sessions/mock_sync_sessions_client.h"
 #include "components/sync_sessions/session_sync_prefs.h"
+#include "components/sync_sessions/switches.h"
 #include "components/sync_sessions/test_matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -185,7 +187,11 @@
 };
 
 TEST_F(SessionStoreOpenTest, ShouldCreateStore) {
-  ASSERT_THAT(session_sync_prefs_.GetSyncSessionsGUID(), IsEmpty());
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(
+      switches::kSyncUseCacheGuidAsSyncSessionTag);
+
+  ASSERT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(), IsEmpty());
 
   MockOpenCallback completion;
   EXPECT_CALL(completion, Run(NoModelError(), /*store=*/NotNull(),
@@ -196,13 +202,36 @@
   ASSERT_THAT(completion.GetResult(), NotNull());
   EXPECT_THAT(completion.GetResult()->local_session_info().client_name,
               Eq(syncer::GetPersonalizableDeviceNameBlocking()));
-  EXPECT_THAT(session_sync_prefs_.GetSyncSessionsGUID(),
+  EXPECT_THAT(completion.GetResult()->local_session_info().session_tag,
               Eq(std::string("session_sync") + kCacheGuid));
+  EXPECT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(),
+              Eq(std::string("session_sync") + kCacheGuid));
+}
+
+TEST_F(SessionStoreOpenTest, ShouldCreateStoreWithoutTagPrefix) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      switches::kSyncUseCacheGuidAsSyncSessionTag);
+
+  ASSERT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(), IsEmpty());
+
+  MockOpenCallback completion;
+  EXPECT_CALL(completion, Run(NoModelError(), /*store=*/NotNull(),
+                              MetadataBatchContains(_, IsEmpty())));
+  SessionStore::Open(kCacheGuid, mock_sync_sessions_client_.get(),
+                     completion.Get());
+  completion.Wait();
+  ASSERT_THAT(completion.GetResult(), NotNull());
+  EXPECT_THAT(completion.GetResult()->local_session_info().client_name,
+              Eq(syncer::GetPersonalizableDeviceNameBlocking()));
+  EXPECT_THAT(completion.GetResult()->local_session_info().session_tag,
+              Eq(kCacheGuid));
+  EXPECT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(), IsEmpty());
 }
 
 TEST_F(SessionStoreOpenTest, ShouldReadSessionsGuidFromPrefs) {
   const std::string kCachedGuid = "cachedguid1";
-  session_sync_prefs_.SetSyncSessionsGUID(kCachedGuid);
+  session_sync_prefs_.SetLegacySyncSessionsGUID(kCachedGuid);
 
   NiceMock<MockOpenCallback> completion;
   SessionStore::Open(kCacheGuid, mock_sync_sessions_client_.get(),
@@ -211,7 +240,7 @@
   ASSERT_THAT(completion.GetResult(), NotNull());
   EXPECT_THAT(completion.GetResult()->local_session_info().session_tag,
               Eq(kCachedGuid));
-  EXPECT_THAT(session_sync_prefs_.GetSyncSessionsGUID(), Eq(kCachedGuid));
+  EXPECT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(), Eq(kCachedGuid));
 }
 
 TEST_F(SessionStoreOpenTest, ShouldNotUseClientIfCancelled) {
@@ -257,7 +286,7 @@
   const std::string kLocalSessionTag = "localsessiontag";
 
   SessionStoreTest() {
-    session_sync_prefs_.SetSyncSessionsGUID(kLocalSessionTag);
+    session_sync_prefs_.SetLegacySyncSessionsGUID(kLocalSessionTag);
     session_store_ = CreateSessionStore();
   }
 
@@ -276,6 +305,16 @@
   std::unique_ptr<SessionStore> session_store_;
 };
 
+TEST_F(SessionStoreTest, ShouldClearSessionsGuidFromPrefs) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      switches::kSyncUseCacheGuidAsSyncSessionTag);
+  ASSERT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(),
+              Eq(kLocalSessionTag));
+  session_store()->DeleteAllDataAndMetadata();
+  EXPECT_THAT(session_sync_prefs_.GetLegacySyncSessionsGUID(), IsEmpty());
+}
+
 TEST_F(SessionStoreTest, ShouldCreateLocalSession) {
   const std::string header_storage_key =
       SessionStore::GetHeaderStorageKey(kLocalSessionTag);
diff --git a/components/sync_sessions/session_sync_bridge_unittest.cc b/components/sync_sessions/session_sync_bridge_unittest.cc
index 5f0a0ec7..3c7a4fe 100644
--- a/components/sync_sessions/session_sync_bridge_unittest.cc
+++ b/components/sync_sessions/session_sync_bridge_unittest.cc
@@ -177,7 +177,7 @@
     ON_CALL(mock_sync_sessions_client_, GetLocalSessionEventRouter())
         .WillByDefault(Return(window_getter_.router()));
 
-    session_sync_prefs_.SetSyncSessionsGUID(kLocalSessionTag);
+    session_sync_prefs_.SetLegacySyncSessionsGUID(kLocalSessionTag);
 
     // Even if we use NiceMock, let's be strict about errors and let tests
     // explicitly list them.
diff --git a/components/sync_sessions/session_sync_prefs.cc b/components/sync_sessions/session_sync_prefs.cc
index 8cb5f266..b8c977a 100644
--- a/components/sync_sessions/session_sync_prefs.cc
+++ b/components/sync_sessions/session_sync_prefs.cc
@@ -10,15 +10,15 @@
 namespace sync_sessions {
 namespace {
 
-// The GUID session sync will use to identify this client, even across sync
-// disable/enable events.
-const char kSyncSessionsGUID[] = "sync.session_sync_guid";
+// Legacy GUID to identify this client, no longer newly populated by modern
+// clients but honored if present.
+const char kLegacySyncSessionsGUID[] = "sync.session_sync_guid";
 
 }  // namespace
 
 // static
 void SessionSyncPrefs::RegisterProfilePrefs(PrefRegistrySimple* registry) {
-  registry->RegisterStringPref(kSyncSessionsGUID, std::string());
+  registry->RegisterStringPref(kLegacySyncSessionsGUID, std::string());
 }
 
 SessionSyncPrefs::SessionSyncPrefs(PrefService* pref_service)
@@ -28,12 +28,16 @@
 
 SessionSyncPrefs::~SessionSyncPrefs() {}
 
-std::string SessionSyncPrefs::GetSyncSessionsGUID() const {
-  return pref_service_->GetString(kSyncSessionsGUID);
+std::string SessionSyncPrefs::GetLegacySyncSessionsGUID() const {
+  return pref_service_->GetString(kLegacySyncSessionsGUID);
 }
 
-void SessionSyncPrefs::SetSyncSessionsGUID(const std::string& guid) {
-  pref_service_->SetString(kSyncSessionsGUID, guid);
+void SessionSyncPrefs::SetLegacySyncSessionsGUID(const std::string& guid) {
+  pref_service_->SetString(kLegacySyncSessionsGUID, guid);
+}
+
+void SessionSyncPrefs::ClearLegacySyncSessionsGUID() {
+  pref_service_->ClearPref(kLegacySyncSessionsGUID);
 }
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/session_sync_prefs.h b/components/sync_sessions/session_sync_prefs.h
index 5e5774a..1611ade 100644
--- a/components/sync_sessions/session_sync_prefs.h
+++ b/components/sync_sessions/session_sync_prefs.h
@@ -22,8 +22,9 @@
   explicit SessionSyncPrefs(PrefService* pref_service);
   ~SessionSyncPrefs();
 
-  std::string GetSyncSessionsGUID() const;
-  void SetSyncSessionsGUID(const std::string& guid);
+  std::string GetLegacySyncSessionsGUID() const;
+  void SetLegacySyncSessionsGUID(const std::string& guid);
+  void ClearLegacySyncSessionsGUID();
 
  private:
   PrefService* const pref_service_;
diff --git a/components/sync_sessions/session_sync_service.h b/components/sync_sessions/session_sync_service.h
index 5d4608ec..8b939d6 100644
--- a/components/sync_sessions/session_sync_service.h
+++ b/components/sync_sessions/session_sync_service.h
@@ -51,7 +51,9 @@
   virtual void ProxyTabsStateChanged(
       syncer::DataTypeController::State state) = 0;
 
-  // Used on Android only, to override the machine tag.
+  // Used on Android only, to override the session tag. This call may be ignored
+  // depending on feature toggles.
+  // TODO(crbug.com/1159455): Delete code when the feature toggle gets deleted.
   virtual void SetSyncSessionsGUID(const std::string& guid) = 0;
 
  private:
diff --git a/components/sync_sessions/session_sync_service_impl.cc b/components/sync_sessions/session_sync_service_impl.cc
index be79d475..89a419c 100644
--- a/components/sync_sessions/session_sync_service_impl.cc
+++ b/components/sync_sessions/session_sync_service_impl.cc
@@ -8,10 +8,12 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/feature_list.h"
 #include "components/sync/base/report_unrecoverable_error.h"
 #include "components/sync/model_impl/client_tag_based_model_type_processor.h"
 #include "components/sync_sessions/session_sync_bridge.h"
 #include "components/sync_sessions/session_sync_prefs.h"
+#include "components/sync_sessions/switches.h"
 #include "components/sync_sessions/sync_sessions_client.h"
 
 namespace sync_sessions {
@@ -65,7 +67,12 @@
 }
 
 void SessionSyncServiceImpl::SetSyncSessionsGUID(const std::string& guid) {
-  sessions_client_->GetSessionSyncPrefs()->SetSyncSessionsGUID(guid);
+  if (base::FeatureList::IsEnabled(
+          switches::kSyncUseCacheGuidAsSyncSessionTag)) {
+    return;
+  }
+
+  sessions_client_->GetSessionSyncPrefs()->SetLegacySyncSessionsGUID(guid);
 }
 
 OpenTabsUIDelegate*
diff --git a/components/sync_sessions/switches.cc b/components/sync_sessions/switches.cc
index bc1df38..23d5999 100644
--- a/components/sync_sessions/switches.cc
+++ b/components/sync_sessions/switches.cc
@@ -11,4 +11,7 @@
 const base::Feature kSyncConsiderEmptyWindowsSyncable{
     "SyncConsiderEmptyWindowsSyncable", base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kSyncUseCacheGuidAsSyncSessionTag{
+    "SyncUseCacheGuidAsSyncSessionTag", base::FEATURE_ENABLED_BY_DEFAULT};
+
 }  // namespace switches
diff --git a/components/sync_sessions/switches.h b/components/sync_sessions/switches.h
index 4f15cd9..f6577030 100644
--- a/components/sync_sessions/switches.h
+++ b/components/sync_sessions/switches.h
@@ -11,6 +11,8 @@
 
 extern const base::Feature kSyncConsiderEmptyWindowsSyncable;
 
+extern const base::Feature kSyncUseCacheGuidAsSyncSessionTag;
+
 }  // namespace switches
 
 #endif  // COMPONENTS_SYNC_SESSIONS_SWITCHES_H_
diff --git a/components/sync_sessions/sync_sessions_client.h b/components/sync_sessions/sync_sessions_client.h
index 5cb23924..3933f6a 100644
--- a/components/sync_sessions/sync_sessions_client.h
+++ b/components/sync_sessions/sync_sessions_client.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_SYNC_SESSIONS_SYNC_SESSIONS_CLIENT_H_
 
 #include <memory>
+#include <string>
 
 #include "base/macros.h"
 #include "components/sync/model/model_type_store.h"
@@ -39,6 +40,10 @@
   // componentized.
   virtual bool ShouldSyncURL(const GURL& url) const = 0;
 
+  // Returns if the provided |cache_guid| is the local device's current cache\
+  // GUID or is known to have been used in the past as local device GUID.
+  virtual bool IsRecentLocalCacheGuid(const std::string& cache_guid) const = 0;
+
   // Returns the SyncedWindowDelegatesGetter for this client.
   virtual SyncedWindowDelegatesGetter* GetSyncedWindowDelegatesGetter() = 0;
 
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc
index dbeed4f..e3355719 100644
--- a/components/sync_sessions/synced_session_tracker.cc
+++ b/components/sync_sessions/synced_session_tracker.cc
@@ -326,7 +326,13 @@
     if (lookup == PRESENTABLE && !IsPresentable(sessions_client_, session)) {
       continue;
     }
-    if (exclude_local_session && session_pair.first == local_session_tag_) {
+    // The comparison against |local_session_tag_| deals with the currently
+    // active sync session (cache GUID or legacy session tag) but in addition
+    // IsRecentLocalCacheGuid() is used to filter out older values of the
+    // local cache GUID.
+    if (exclude_local_session &&
+        (session_pair.first == local_session_tag_ ||
+         sessions_client_->IsRecentLocalCacheGuid(session_pair.first))) {
       continue;
     }
     sessions.push_back(&session);
diff --git a/components/sync_sessions/synced_session_tracker_unittest.cc b/components/sync_sessions/synced_session_tracker_unittest.cc
index e5527a0..b4a5e1ea 100644
--- a/components/sync_sessions/synced_session_tracker_unittest.cc
+++ b/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -243,6 +243,7 @@
   tab->navigations.push_back(
       sessions::SerializedNavigationEntryTestHelper::CreateNavigationForTest());
   tab->navigations.back().set_virtual_url(GURL(kInvalidUrl));
+
   // Only the session with a valid window and tab gets returned.
   EXPECT_THAT(
       tracker_.LookupAllForeignSessions(SyncedSessionTracker::PRESENTABLE),
@@ -250,6 +251,15 @@
   EXPECT_THAT(tracker_.LookupAllForeignSessions(SyncedSessionTracker::RAW),
               ElementsAre(HasSessionTag(kTag), HasSessionTag(kTag2),
                           HasSessionTag(kTag3)));
+
+  // Annotate kTag as local session.
+  ON_CALL(sessions_client_, IsRecentLocalCacheGuid(kTag))
+      .WillByDefault(Return(true));
+  EXPECT_THAT(
+      tracker_.LookupAllForeignSessions(SyncedSessionTracker::PRESENTABLE),
+      IsEmpty());
+  EXPECT_THAT(tracker_.LookupAllForeignSessions(SyncedSessionTracker::RAW),
+              ElementsAre(HasSessionTag(kTag2), HasSessionTag(kTag3)));
 }
 
 TEST_F(SyncedSessionTrackerTest, LookupSessionWindows) {
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index 5f5a017a..8f74ac7 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -2528,7 +2528,7 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
     ExpectNotRestored(
         {BackForwardCacheMetrics::NotRestoredReason::
              kRelatedActiveContentsExist,
@@ -4240,8 +4240,7 @@
     // On Android, navigations to about:blank keeps the same RenderFrameHost.
     // Obviously, it can't enter the BackForwardCache, because it is still used
     // to display the current document.
-    if (test_case.url == blank_url &&
-        !SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) {
+    if (test_case.url == blank_url && !AreStrictSiteInstancesEnabled()) {
       EXPECT_FALSE(delete_observer.deleted());
       EXPECT_FALSE(rfh->IsInBackForwardCache());
       EXPECT_EQ(rfh, current_frame_host());
@@ -5060,13 +5059,13 @@
   RenderFrameHostImpl* rfh_a1 = current_frame_host();
   RenderFrameHostImpl* rfh_b = rfh_a1->child_at(0)->current_frame_host();
   EXPECT_TRUE(ExecJs(rfh_b, "window.onunload = () => {} "));
-  EXPECT_EQ(AreAllSitesIsolatedForTesting(),
+  EXPECT_EQ(AreStrictSiteInstancesEnabled(),
             rfh_a1->GetSiteInstance() != rfh_b->GetSiteInstance());
 
   // 2) Navigate to A2.
   EXPECT_TRUE(NavigateToURL(shell(), url_a2));
   RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
     // We should swap RFH & BIs and A1 should be in the back-forward cache.
     EXPECT_NE(rfh_a1, rfh_a2);
     EXPECT_FALSE(rfh_a1->GetSiteInstance()->IsRelatedSiteInstance(
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc
index 6113591..9619c45e 100644
--- a/content/browser/cross_origin_opener_policy_browsertest.cc
+++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -549,28 +549,21 @@
 IN_PROC_BROWSER_TEST_P(CrossOriginOpenerPolicyBrowserTest,
                        CoopPageCrashIntoNonCoop) {
   IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
+  GURL coop_allow_popups_page(https_server()->GetURL(
+      "a.com",
+      "/set-header?Cross-Origin-Opener-Policy: same-origin-allow-popups"));
   GURL non_coop_page(https_server()->GetURL("a.com", "/title1.html"));
-  GURL coop_page = https_server()->GetURL(
-      "a.com", "/set-header?Cross-Origin-Opener-Policy: same-origin");
+  GURL cross_origin_non_coop_page(
+      https_server()->GetURL("b.com", "/title1.html"));
   // Test a crash before the navigation.
   {
     // Navigate to a COOP page.
-    EXPECT_TRUE(NavigateToURL(shell(), coop_page));
+    EXPECT_TRUE(NavigateToURL(shell(), coop_allow_popups_page));
     scoped_refptr<SiteInstance> initial_site_instance(
         current_frame_host()->GetSiteInstance());
 
     // Ensure it has a RenderFrameHostProxy for another cross-site page.
-    Shell* popup_shell = OpenPopup(current_frame_host(), coop_page, "");
-    GURL cross_site_iframe(https_server()->GetURL("b.com", "/title1.html"));
-    TestNavigationManager iframe_navigation(popup_shell->web_contents(),
-                                            cross_site_iframe);
-    EXPECT_TRUE(
-        ExecJs(popup_shell->web_contents(),
-               JsReplace("var iframe = document.createElement('iframe');"
-                         "iframe.src = $1;"
-                         "document.body.appendChild(iframe);",
-                         cross_site_iframe)));
-    iframe_navigation.WaitForNavigationFinished();
+    OpenPopup(current_frame_host(), cross_origin_non_coop_page, "");
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
@@ -607,22 +600,12 @@
   // Test a crash during the navigation.
   {
     // Navigate to a COOP page.
-    EXPECT_TRUE(NavigateToURL(shell(), coop_page));
+    EXPECT_TRUE(NavigateToURL(shell(), coop_allow_popups_page));
     scoped_refptr<SiteInstance> initial_site_instance(
         current_frame_host()->GetSiteInstance());
 
     // Ensure it has a RenderFrameHostProxy for another cross-site page.
-    Shell* popup_shell = OpenPopup(current_frame_host(), coop_page, "");
-    GURL cross_site_iframe(https_server()->GetURL("b.com", "/title1.html"));
-    TestNavigationManager iframe_navigation(popup_shell->web_contents(),
-                                            cross_site_iframe);
-    EXPECT_TRUE(
-        ExecJs(popup_shell->web_contents(),
-               JsReplace("var iframe = document.createElement('iframe');"
-                         "iframe.src = $1;"
-                         "document.body.appendChild(iframe);",
-                         cross_site_iframe)));
-    iframe_navigation.WaitForNavigationFinished();
+    OpenPopup(current_frame_host(), cross_origin_non_coop_page, "");
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
@@ -666,31 +649,24 @@
 IN_PROC_BROWSER_TEST_P(CrossOriginOpenerPolicyBrowserTest,
                        CoopPageCrashIntoCoop) {
   IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
-  GURL non_coop_page(https_server()->GetURL("a.com", "/title1.html"));
-  GURL coop_page = https_server()->GetURL(
-      "a.com", "/set-header?Cross-Origin-Opener-Policy: same-origin");
+  GURL coop_allow_popups_page(https_server()->GetURL(
+      "a.com",
+      "/set-header?Cross-Origin-Opener-Policy: same-origin-allow-popups"));
+  GURL cross_origin_non_coop_page(
+      https_server()->GetURL("b.com", "/title1.html"));
 
   // Test a crash before the navigation.
   {
     // Navigate to a COOP page.
-    EXPECT_TRUE(NavigateToURL(shell(), coop_page));
+    EXPECT_TRUE(NavigateToURL(shell(), coop_allow_popups_page));
     scoped_refptr<SiteInstance> initial_site_instance(
         current_frame_host()->GetSiteInstance());
     EXPECT_EQ(current_frame_host()->cross_origin_opener_policy(),
-              CoopSameOrigin());
+              CoopSameOriginAllowPopups());
 
     // Ensure it has a RenderFrameHostProxy for another cross-site page.
-    Shell* popup_shell = OpenPopup(current_frame_host(), coop_page, "");
-    GURL cross_site_iframe(https_server()->GetURL("b.com", "/title1.html"));
-    TestNavigationManager iframe_navigation(popup_shell->web_contents(),
-                                            cross_site_iframe);
-    EXPECT_TRUE(
-        ExecJs(popup_shell->web_contents(),
-               JsReplace("var iframe = document.createElement('iframe');"
-                         "iframe.src = $1;"
-                         "document.body.appendChild(iframe);",
-                         cross_site_iframe)));
-    iframe_navigation.WaitForNavigationFinished();
+    OpenPopup(current_frame_host(), cross_origin_non_coop_page, "");
+
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
@@ -709,40 +685,29 @@
     crash_observer.reset();
 
     // Navigate to a COOP page.
-    EXPECT_TRUE(NavigateToURL(shell(), coop_page));
+    EXPECT_TRUE(NavigateToURL(shell(), coop_allow_popups_page));
     EXPECT_TRUE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
         initial_site_instance.get()));
     EXPECT_EQ(current_frame_host()->cross_origin_opener_policy(),
-              CoopSameOrigin());
+              CoopSameOriginAllowPopups());
 
-    // TODO(pmeuleman): The COOP page should still have RenderFrameHostProxies.
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
                   ->render_manager()
                   ->GetProxyCount(),
-              0u);
+              1u);
   }
 
   // Test a crash during the navigation.
   {
     // Navigate to a COOP page.
-    EXPECT_TRUE(NavigateToURL(shell(), coop_page));
+    EXPECT_TRUE(NavigateToURL(shell(), coop_allow_popups_page));
     scoped_refptr<SiteInstance> initial_site_instance(
         current_frame_host()->GetSiteInstance());
 
     // Ensure it has a RenderFrameHostProxy for another cross-site page.
-    Shell* popup_shell = OpenPopup(current_frame_host(), coop_page, "");
-    GURL cross_site_iframe(https_server()->GetURL("b.com", "/title1.html"));
-    TestNavigationManager iframe_navigation(popup_shell->web_contents(),
-                                            cross_site_iframe);
-    EXPECT_TRUE(
-        ExecJs(popup_shell->web_contents(),
-               JsReplace("var iframe = document.createElement('iframe');"
-                         "iframe.src = $1;"
-                         "document.body.appendChild(iframe);",
-                         cross_site_iframe)));
-    iframe_navigation.WaitForNavigationFinished();
+    OpenPopup(current_frame_host(), cross_origin_non_coop_page, "");
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
@@ -751,8 +716,9 @@
               1u);
 
     // Start navigating to a COOP page.
-    TestNavigationManager coop_navigation(web_contents(), coop_page);
-    shell()->LoadURL(coop_page);
+    TestNavigationManager coop_navigation(web_contents(),
+                                          coop_allow_popups_page);
+    shell()->LoadURL(coop_allow_popups_page);
     EXPECT_TRUE(coop_navigation.WaitForRequestStart());
 
     // Simulate the renderer process crashing.
@@ -771,15 +737,14 @@
     EXPECT_TRUE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
         initial_site_instance.get()));
     EXPECT_EQ(current_frame_host()->cross_origin_opener_policy(),
-              CoopSameOrigin());
+              CoopSameOriginAllowPopups());
 
-    // TODO(pmeuleman): The COOP page should still have RenderFrameHostProxies.
     EXPECT_EQ(web_contents()
                   ->GetFrameTree()
                   ->root()
                   ->render_manager()
                   ->GetProxyCount(),
-              0u);
+              1u);
   }
 }
 
diff --git a/content/browser/devtools/devtools_video_consumer.cc b/content/browser/devtools/devtools_video_consumer.cc
index 38ac3b8..8ca2835 100644
--- a/content/browser/devtools/devtools_video_consumer.cc
+++ b/content/browser/devtools/devtools_video_consumer.cc
@@ -28,6 +28,11 @@
 // Allow variable aspect ratio.
 const bool kDefaultUseFixedAspectRatio = false;
 
+constexpr media::VideoPixelFormat kDefaultPixelFormat =
+    media::PIXEL_FORMAT_I420;
+
+constexpr gfx::ColorSpace kDefaultColorSpace = gfx::ColorSpace::CreateREC709();
+
 // Creates a ClientFrameSinkVideoCapturer via HostFrameSinkManager.
 std::unique_ptr<viz::ClientFrameSinkVideoCapturer> CreateCapturer() {
   return GetHostFrameSinkManager()->CreateVideoCapturer();
@@ -45,7 +50,9 @@
     : callback_(std::move(callback)),
       min_capture_period_(kDefaultMinCapturePeriod),
       min_frame_size_(kDefaultMinFrameSize),
-      max_frame_size_(kDefaultMaxFrameSize) {}
+      max_frame_size_(kDefaultMaxFrameSize),
+      pixel_format_(kDefaultPixelFormat),
+      color_space_(kDefaultColorSpace) {}
 
 DevToolsVideoConsumer::~DevToolsVideoConsumer() = default;
 
@@ -102,6 +109,15 @@
   }
 }
 
+void DevToolsVideoConsumer::SetFormat(media::VideoPixelFormat format,
+                                      gfx::ColorSpace color_space) {
+  pixel_format_ = format;
+  color_space_ = color_space;
+  if (capturer_) {
+    capturer_->SetFormat(pixel_format_, color_space_);
+  }
+}
+
 void DevToolsVideoConsumer::InnerStartCapture(
     std::unique_ptr<viz::ClientFrameSinkVideoCapturer> capturer) {
   capturer_ = std::move(capturer);
@@ -111,6 +127,7 @@
   capturer_->SetMinSizeChangePeriod(kDefaultMinPeriod);
   capturer_->SetResolutionConstraints(min_frame_size_, max_frame_size_,
                                       kDefaultUseFixedAspectRatio);
+  capturer_->SetFormat(pixel_format_, color_space_);
   if (frame_sink_id_.is_valid())
     capturer_->ChangeTarget(frame_sink_id_);
 
diff --git a/content/browser/devtools/devtools_video_consumer.h b/content/browser/devtools/devtools_video_consumer.h
index fe4ab8181..0b6a587 100644
--- a/content/browser/devtools/devtools_video_consumer.h
+++ b/content/browser/devtools/devtools_video_consumer.h
@@ -42,12 +42,11 @@
 
   // These functions cache the values passed to them and if we're currently
   // capturing, they call the corresponding |capturer_| functions.
-  // TODO(samans): Add a SetFormat function here so that ARGB pixel format can
-  // be used.
   void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id);
   void SetMinCapturePeriod(base::TimeDelta min_capture_period);
   void SetMinAndMaxFrameSize(gfx::Size min_frame_size,
                              gfx::Size max_frame_size);
+  void SetFormat(media::VideoPixelFormat format, gfx::ColorSpace color_space);
 
  private:
   friend class DevToolsVideoConsumerTest;
@@ -86,6 +85,8 @@
   gfx::Size min_frame_size_;
   gfx::Size max_frame_size_;
   viz::FrameSinkId frame_sink_id_;
+  media::VideoPixelFormat pixel_format_;
+  gfx::ColorSpace color_space_;
 
   // If |capturer_| is alive, then we are currently capturing.
   std::unique_ptr<viz::ClientFrameSinkVideoCapturer> capturer_;
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index ab2235d..6d08d6d 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -212,6 +212,8 @@
     video_consumer_ = std::make_unique<DevToolsVideoConsumer>(
         base::BindRepeating(&PageHandler::OnFrameFromVideoConsumer,
                             weak_factory_.GetWeakPtr()));
+    video_consumer_->SetFormat(media::PIXEL_FORMAT_ARGB,
+                               gfx::ColorSpace::CreateREC709());
   }
   DCHECK(emulation_handler_);
 }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index c7d159a..a3171a40 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -272,9 +272,12 @@
     // here that there is no other agent host.
     g_agent_host_instances.Get()[frame_tree_node] = this;
   }
-  WebContentsObserver::Observe(
-      frame_tree_node_ ? WebContentsImpl::FromFrameTreeNode(frame_tree_node_)
-                       : nullptr);
+  auto* wc = frame_tree_node_
+                 ? WebContentsImpl::FromFrameTreeNode(frame_tree_node_)
+                 : nullptr;
+  if (wc)
+    page_scale_factor_ = wc->page_scale_factor();
+  WebContentsObserver::Observe(wc);
 }
 
 BrowserContext* RenderFrameDevToolsAgentHost::GetBrowserContext() {
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index dd9b3fc..089194245 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -107,6 +107,15 @@
 
 }  // namespace
 
+// static
+void IndexedDBContextImpl::ReleaseOnIDBSequence(
+    scoped_refptr<IndexedDBContextImpl> context) {
+  if (!context->idb_task_runner_->RunsTasksInCurrentSequence()) {
+    IndexedDBContextImpl* context_ptr = context.get();
+    context_ptr->IDBTaskRunner()->ReleaseSoon(FROM_HERE, std::move(context));
+  }
+}
+
 IndexedDBContextImpl::IndexedDBContextImpl(
     const base::FilePath& data_path,
     scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
@@ -117,7 +126,7 @@
         native_file_system_context,
     scoped_refptr<base::SequencedTaskRunner> io_task_runner,
     scoped_refptr<base::SequencedTaskRunner> custom_task_runner)
-    : base::RefCountedDeleteOnSequence<IndexedDBContextImpl>(
+    : idb_task_runner_(
           custom_task_runner
               ? custom_task_runner
               : (base::ThreadPool::CreateSequencedTaskRunner(
@@ -141,7 +150,7 @@
   // This is safe because the IndexedDBContextImpl must be destructed on the
   // IDBTaskRunner, and this task will always happen before that.
   if (blob_storage_context || native_file_system_context) {
-    IDBTaskRunner()->PostTask(
+    idb_task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
             [](mojo::Remote<storage::mojom::BlobStorageContext>*
@@ -886,9 +895,4 @@
   return origin_set_.get();
 }
 
-base::SequencedTaskRunner* IndexedDBContextImpl::IDBTaskRunner() {
-  DCHECK(owning_task_runner());
-  return owning_task_runner();
-}
-
 }  // namespace content
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 52ef7d5..9b52926e 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -17,7 +17,7 @@
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
 #include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
 #include "components/services/storage/public/mojom/indexed_db_control.mojom.h"
@@ -49,13 +49,16 @@
 class IndexedDBFactoryImpl;
 
 class CONTENT_EXPORT IndexedDBContextImpl
-    : public base::RefCountedDeleteOnSequence<IndexedDBContextImpl>,
+    : public base::RefCountedThreadSafe<IndexedDBContextImpl>,
       public storage::mojom::IndexedDBControl,
       public storage::mojom::IndexedDBControlTest {
  public:
   // The indexed db directory.
   static const base::FilePath::CharType kIndexedDBDirectory[];
 
+  // Release |context| on the IDBTaskRunner.
+  static void ReleaseOnIDBSequence(scoped_refptr<IndexedDBContextImpl> context);
+
   // If |data_path| is empty, nothing will be saved to disk.
   // |task_runner| is optional, and only set during testing.
   // This is *not* called on the IDBTaskRunner, unlike most other functions.
@@ -145,7 +148,7 @@
   int64_t GetOriginDiskUsage(const url::Origin& origin);
 
   // This getter is thread-safe.
-  base::SequencedTaskRunner* IDBTaskRunner();
+  base::SequencedTaskRunner* IDBTaskRunner() { return idb_task_runner_.get(); }
 
   // Methods called by IndexedDBFactoryImpl or IndexedDBDispatcherHost for
   // quota support.
@@ -199,12 +202,8 @@
                                      const base::string16& database_name,
                                      const base::string16& object_store_name);
 
- protected:
-  ~IndexedDBContextImpl() override;
-
  private:
-  friend class base::RefCountedDeleteOnSequence<IndexedDBContextImpl>;
-  friend class base::DeleteHelper<IndexedDBContextImpl>;
+  friend class base::RefCountedThreadSafe<IndexedDBContextImpl>;
 
   FRIEND_TEST_ALL_PREFIXES(IndexedDBTest, ClearLocalState);
   FRIEND_TEST_ALL_PREFIXES(IndexedDBTest, ClearSessionOnlyDatabases);
@@ -218,6 +217,8 @@
       const base::FilePath& indexeddb_path,
       scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy);
 
+  ~IndexedDBContextImpl() override;
+
   base::FilePath GetBlobStorePath(const url::Origin& origin) const;
   base::FilePath GetLevelDBPath(const url::Origin& origin) const;
 
@@ -233,6 +234,7 @@
   // backing stores); the cache will be primed as needed by checking disk.
   std::set<url::Origin>* GetOriginSet();
 
+  scoped_refptr<base::SequencedTaskRunner> idb_task_runner_;
   IndexedDBDispatcherHost dispatcher_host_;
 
   // Bound and accessed on the |idb_task_runner_|.
diff --git a/content/browser/indexed_db/indexed_db_control_wrapper.cc b/content/browser/indexed_db/indexed_db_control_wrapper.cc
index e45e150..b43def3d 100644
--- a/content/browser/indexed_db/indexed_db_control_wrapper.cc
+++ b/content/browser/indexed_db/indexed_db_control_wrapper.cc
@@ -70,6 +70,8 @@
 
 IndexedDBControlWrapper::~IndexedDBControlWrapper() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  IndexedDBContextImpl::ReleaseOnIDBSequence(std::move(context_));
 }
 
 void IndexedDBControlWrapper::BindIndexedDB(
diff --git a/content/browser/indexed_db/indexed_db_quota_client.cc b/content/browser/indexed_db/indexed_db_quota_client.cc
index 6e05d01..7e0066d9 100644
--- a/content/browser/indexed_db/indexed_db_quota_client.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client.cc
@@ -88,6 +88,8 @@
 
 IndexedDBQuotaClient::~IndexedDBQuotaClient() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  IndexedDBContextImpl::ReleaseOnIDBSequence(std::move(indexed_db_context_));
 }
 
 void IndexedDBQuotaClient::OnQuotaManagerDestroyed() {
diff --git a/content/browser/indexed_db/indexed_db_quota_client.h b/content/browser/indexed_db/indexed_db_quota_client.h
index c7636fc..d055a89 100644
--- a/content/browser/indexed_db/indexed_db_quota_client.h
+++ b/content/browser/indexed_db/indexed_db_quota_client.h
@@ -52,7 +52,7 @@
  private:
   ~IndexedDBQuotaClient() override;
 
-  const scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
+  scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 };
diff --git a/content/browser/isolated_origin_browsertest.cc b/content/browser/isolated_origin_browsertest.cc
index da27a033..88731fd4 100644
--- a/content/browser/isolated_origin_browsertest.cc
+++ b/content/browser/isolated_origin_browsertest.cc
@@ -2019,14 +2019,24 @@
             child->current_frame_host()->GetSiteInstance()->GetSiteURL());
 
   // Navigate the child frame cross-site, but to a non-isolated origin. When
-  // not in --site-per-process, this should bring the subframe back into the
-  // main frame's SiteInstance.
+  // strict SiteInstaces are not enabled, this should bring the subframe back
+  // into the main frame's SiteInstance. If strict SiteInstances are enabled,
+  // we expect the SiteInstances to be different because a SiteInstance is not
+  // allowed to contain multiple sites in that mode. In all cases though we
+  // expect the navigation to end up in the same process.
   GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
   EXPECT_FALSE(IsIsolatedOrigin(bar_url));
   NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
-  EXPECT_EQ(web_contents()->GetSiteInstance(),
-            child->current_frame_host()->GetSiteInstance());
-  EXPECT_FALSE(child->current_frame_host()->IsCrossProcessSubframe());
+
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(web_contents()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  } else {
+    EXPECT_EQ(web_contents()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  }
+  EXPECT_EQ(web_contents()->GetSiteInstance()->GetProcess(),
+            child->current_frame_host()->GetSiteInstance()->GetProcess());
 }
 
 // Check that a new isolated origin subframe will attempt to reuse an existing
@@ -2125,12 +2135,13 @@
   FrameTreeNode* child = root->child_at(0);
 
   // Navigate iframe cross-site, but not to an isolated origin.  This should
-  // stay in the main frame's SiteInstance, unless we're in --site-per-process
-  // mode.  (Note that the bug for which this test is written is exclusive to
-  // --isolate-origins and does not happen with --site-per-process.)
+  // stay in the main frame's SiteInstance, unless we're in a strict
+  // SiteInstance mode (including --site-per-process). (Note that the bug for
+  // which this test is written is exclusive to --isolate-origins and does not
+  // happen with --site-per-process.)
   GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
   NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
     EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
               child->current_frame_host()->GetSiteInstance());
   } else {
@@ -2236,8 +2247,7 @@
     // At this point, the popup and the opener should still be in separate
     // SiteInstances.
     EXPECT_NE(newshell_site_instance_impl, root_site_instance_impl);
-    EXPECT_NE(AreAllSitesIsolatedForTesting(),
-              newshell_site_instance_impl->IsDefaultSiteInstance());
+    EXPECT_FALSE(newshell_site_instance_impl->IsDefaultSiteInstance());
     EXPECT_FALSE(root_site_instance_impl->IsDefaultSiteInstance());
   }
 
@@ -3060,7 +3070,11 @@
   if (!AreAllSitesIsolatedForTesting()) {
     EXPECT_EQ(main_frame->GetProcess()->GetID(),
               subframe3->GetProcess()->GetID());
-    EXPECT_EQ(main_frame->GetSiteInstance(), subframe3->GetSiteInstance());
+    if (AreStrictSiteInstancesEnabled()) {
+      EXPECT_NE(main_frame->GetSiteInstance(), subframe3->GetSiteInstance());
+    } else {
+      EXPECT_EQ(main_frame->GetSiteInstance(), subframe3->GetSiteInstance());
+    }
   }
 
   // isolated.foo.com and foo999.com are on the list of origins to isolate -
@@ -3115,7 +3129,7 @@
     observer.Wait();
     EXPECT_EQ(child2->current_url(), regular_url);
     EXPECT_TRUE(handle_observer.is_error());
-    if (AreAllSitesIsolatedForTesting()) {
+    if (AreStrictSiteInstancesEnabled()) {
       EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
                 child2->current_frame_host()->GetSiteInstance());
       EXPECT_EQ(SiteInstance::GetSiteForURL(web_contents()->GetBrowserContext(),
@@ -3215,15 +3229,11 @@
 
     EXPECT_TRUE(HasDefaultSiteInstance(a));
     EXPECT_FALSE(HasDefaultSiteInstance(b));
-  } else {
-    // Documenting current behavior where the top level document doesn't end
-    // up in a default SiteInstance even though it is not isolated and does not
-    // require a dedicated process. c.com does get placed in a default
-    // SiteInstance because we currently allow subframes that don't require
-    // isolation to share a process. This behavior should go away once we
-    // turn on default SiteInstances by default.
+  } else if (AreStrictSiteInstancesEnabled()) {
+    // All sites have their own SiteInstance and sites that are not isolated
+    // are all placed in the same process.
     EXPECT_NE(a->GetProcess()->GetID(), b->GetProcess()->GetID());
-    EXPECT_NE(a->GetProcess()->GetID(), c->GetProcess()->GetID());
+    EXPECT_EQ(a->GetProcess()->GetID(), c->GetProcess()->GetID());
 
     EXPECT_NE(a->GetSiteInstance(), b->GetSiteInstance());
     EXPECT_NE(a->GetSiteInstance(), c->GetSiteInstance());
@@ -3232,7 +3242,9 @@
 
     EXPECT_FALSE(HasDefaultSiteInstance(a));
     EXPECT_FALSE(HasDefaultSiteInstance(b));
-    EXPECT_TRUE(HasDefaultSiteInstance(c));
+    EXPECT_FALSE(HasDefaultSiteInstance(c));
+  } else {
+    FAIL() << "Unexpected process model configuration.";
   }
 }
 
@@ -3466,12 +3478,15 @@
 
   // The two frames should be in the same process, since neither site is
   // isolated so far.
-  if (!AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  } else {
     EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
               child->current_frame_host()->GetSiteInstance());
-    EXPECT_EQ(root->current_frame_host()->GetProcess(),
-              child->current_frame_host()->GetProcess());
   }
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            child->current_frame_host()->GetProcess());
 
   // Start isolating foo.com.
   auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
@@ -3493,12 +3508,23 @@
       "bar.com", "/cross_site_iframe_factory.html?bar.com(foo.com)"));
   NavigateIframeToURL(web_contents(), "test_iframe", bar_with_foo_url);
   FrameTreeNode* grandchild = child->child_at(0);
-  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
-            child->current_frame_host()->GetSiteInstance());
-  EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
-            grandchild->current_frame_host()->GetSiteInstance());
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+    EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
+              grandchild->current_frame_host()->GetSiteInstance());
+  } else {
+    EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+    EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
+              grandchild->current_frame_host()->GetSiteInstance());
+  }
   EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
             grandchild->current_frame_host()->GetSiteInstance());
+  EXPECT_EQ(root->current_frame_host()->GetProcess(),
+            child->current_frame_host()->GetProcess());
+  EXPECT_EQ(child->current_frame_host()->GetProcess(),
+            grandchild->current_frame_host()->GetProcess());
 
   // Create an unrelated window, which will be in a new BrowsingInstance.
   // Ensure that foo.com becomes an isolated origin in that window.  A
@@ -3773,8 +3799,14 @@
   EXPECT_EQ(child->current_url(), bar_url);
 
   // The iframe should not be in an OOPIF yet.
-  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
-            child->current_frame_host()->GetSiteInstance());
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+
+  } else {
+    EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  }
   EXPECT_EQ(root->current_frame_host()->GetProcess(),
             child->current_frame_host()->GetProcess());
 
@@ -3959,8 +3991,13 @@
   root = web_contents()->GetFrameTree()->root();
   child = root->child_at(0);
   EXPECT_EQ(child->current_url(), bar_url);
-  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
-            child->current_frame_host()->GetSiteInstance());
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  } else {
+    EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  }
   EXPECT_EQ(root->current_frame_host()->GetProcess(),
             child->current_frame_host()->GetProcess());
 }
@@ -3982,7 +4019,12 @@
   FrameTreeNode* child = root->child_at(0);
   scoped_refptr<SiteInstance> first_instance =
       root->current_frame_host()->GetSiteInstance();
-  EXPECT_EQ(first_instance, child->current_frame_host()->GetSiteInstance());
+
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(first_instance, child->current_frame_host()->GetSiteInstance());
+  } else {
+    EXPECT_EQ(first_instance, child->current_frame_host()->GetSiteInstance());
+  }
   EXPECT_EQ(root->current_frame_host()->GetProcess(),
             child->current_frame_host()->GetProcess());
   auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index 5c4ff95..f6add29f 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -501,13 +501,13 @@
     EXPECT_EQ(initiator_process_id, observer.last_initiator_process_id());
   }
 
-  // The RenderFrameHost should not have changed unless site-per-process or
-  // proactive BrowsingInstance swap is enabled.
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
-    EXPECT_NE(initial_rfh, current_frame_host());
-  } else {
+  // The RenderFrameHost should have changed unless default SiteInstances
+  // are enabled and proactive BrowsingInstance swaps are disabled.
+  if (AreDefaultSiteInstancesEnabled() &&
+      !CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
     EXPECT_EQ(initial_rfh, current_frame_host());
+  } else {
+    EXPECT_NE(initial_rfh, current_frame_host());
   }
 }
 
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
index e168413..fd5f07f 100644
--- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -4593,7 +4593,7 @@
   FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                             ->GetFrameTree()
                             ->root();
-  SiteInstance* main_site_instance =
+  SiteInstanceImpl* main_site_instance =
       root->current_frame_host()->GetSiteInstance();
 
   // The main frame defaults to an empty name.
@@ -4656,14 +4656,15 @@
   EXPECT_TRUE(NavigateToURLFromRenderer(foo_subframe, bar_url));
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
-  // When run just with subframe navigation entries enabled and not in
-  // site-per-process-mode the subframe should be in the same SiteInstance as
-  // its parent.
-  if (!AreAllSitesIsolatedForTesting()) {
-    EXPECT_EQ(main_site_instance,
+  if (AreStrictSiteInstancesEnabled()) {
+    EXPECT_NE(main_site_instance,
               foo_subframe->current_frame_host()->GetSiteInstance());
   } else {
-    EXPECT_NE(main_site_instance,
+    // When strict SiteInstances are not being used, the subframe should be
+    // the same as its parent because both sites get routed to the default
+    // SiteInstance.
+    EXPECT_TRUE(main_site_instance->IsDefaultSiteInstance());
+    EXPECT_EQ(main_site_instance,
               foo_subframe->current_frame_host()->GetSiteInstance());
   }
 
@@ -5518,12 +5519,16 @@
   EXPECT_EQ(main_url_a, new_root->current_url());
   EXPECT_EQ(frame_url_b, new_root->child_at(0)->current_url());
 
-  // The subframe should only be in a different SiteInstance if OOPIFs are
-  // required for all sites.
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
     EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
               new_root->child_at(0)->current_frame_host()->GetSiteInstance());
   } else {
+    // When strict SiteInstances are not enabled, the subframe should be in the
+    // same SiteInstance as the parent because both sites get mapped to the
+    // default SiteInstance.
+    EXPECT_TRUE(new_root->current_frame_host()
+                    ->GetSiteInstance()
+                    ->IsDefaultSiteInstance());
     EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
               new_root->child_at(0)->current_frame_host()->GetSiteInstance());
   }
@@ -5960,9 +5965,9 @@
 // not modify the underlying last committed entry.)  Not crashing means that
 // the test is successful.
 IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, ReloadOriginalRequest) {
-  // TODO(lukasza): https://crbug.com/417518: Get tests working with
-  // --site-per-process.
-  if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites() ||
+  // TODO(lukasza): https://crbug.com/1159466: Get tests working for all
+  // process model modes.
+  if (AreStrictSiteInstancesEnabled() ||
       CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
     return;
   }
diff --git a/content/browser/renderer_host/navigator_unittest.cc b/content/browser/renderer_host/navigator_unittest.cc
index a1432ab..0ba3392 100644
--- a/content/browser/renderer_host/navigator_unittest.cc
+++ b/content/browser/renderer_host/navigator_unittest.cc
@@ -40,6 +40,19 @@
 
 namespace content {
 
+namespace {
+
+// Helper function that determines if a test should expect a cross-site
+// navigation to trigger a SiteInstance change based on the current process
+// model.
+bool ExpectSiteInstanceChange(SiteInstanceImpl* site_instance) {
+  return AreAllSitesIsolatedForTesting() ||
+         CanCrossSiteNavigationsProactivelySwapBrowsingInstances() ||
+         !site_instance->IsDefaultSiteInstance();
+}
+
+}  // namespace
+
 class NavigatorTest : public RenderViewHostImplTestHarness {
  public:
   using SiteInstanceDescriptor = RenderFrameHostManager::SiteInstanceDescriptor;
@@ -190,7 +203,10 @@
 
   contents()->NavigateAndCommit(kUrl1);
   EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
-  int32_t site_instance_id_1 = main_test_rfh()->GetSiteInstance()->GetId();
+  scoped_refptr<SiteInstanceImpl> site_instance_1 =
+      main_test_rfh()->GetSiteInstance();
+  bool expect_site_instance_change =
+      ExpectSiteInstanceChange(site_instance_1.get());
 
   // Start a renderer-initiated navigation.
   EXPECT_FALSE(main_test_rfh()->navigation_request());
@@ -206,8 +222,7 @@
   EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, request->state());
   EXPECT_EQ(kUrl2, request->common_params().url);
   EXPECT_FALSE(request->browser_initiated());
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -215,8 +230,7 @@
 
   // Have the current RenderFrameHost commit the navigation.
   navigation->ReadyToCommit();
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_EQ(navigation->GetFinalRenderFrameHost(),
               GetSpeculativeRenderFrameHost(node));
   }
@@ -228,12 +242,14 @@
   EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
 
-  // The SiteInstance did not change unless site-per-process is enabled.
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
-    EXPECT_NE(site_instance_id_1, main_test_rfh()->GetSiteInstance()->GetId());
+  if (expect_site_instance_change) {
+    EXPECT_NE(site_instance_1->GetId(),
+              main_test_rfh()->GetSiteInstance()->GetId());
+    EXPECT_EQ(site_instance_1->IsDefaultSiteInstance(),
+              main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
   } else {
-    EXPECT_EQ(site_instance_id_1, main_test_rfh()->GetSiteInstance()->GetId());
+    EXPECT_EQ(site_instance_1->GetId(),
+              main_test_rfh()->GetSiteInstance()->GetId());
   }
 }
 
@@ -315,9 +331,11 @@
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(root_node));
 
   // Subframe navigations should never create a speculative RenderFrameHost,
-  // unless site-per-process is enabled. In that case, as the subframe
-  // navigation is to a different site and is still ongoing, it should have one.
-  if (AreAllSitesIsolatedForTesting()) {
+  // unless site-per-process or ProcessSharingWithStrictSiteInstances is
+  // enabled. In that case, as the subframe navigation is to a different site
+  // and is still ongoing, it should have one.
+  bool expect_site_instance_change = AreStrictSiteInstancesEnabled();
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(subframe_node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(subframe_node));
@@ -359,7 +377,7 @@
 
   // As the main frame hasn't yet committed the subframe still exists. Thus, the
   // above situation regarding subframe navigations is valid here.
-  if (AreAllSitesIsolatedForTesting()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(subframe_node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(subframe_node));
@@ -598,6 +616,8 @@
   // Initialization.
   contents()->NavigateAndCommit(kUrl0);
   FrameTreeNode* node = main_test_rfh()->frame_tree_node();
+  bool expect_site_instance_change =
+      ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
 
   // Start a browser-initiated navigation to the 1st URL and invoke its
   // beforeUnload completion callback.
@@ -634,8 +654,7 @@
 
   // Confirm that the speculative RenderFrameHost was destroyed in the non
   // SitePerProcess case.
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -661,6 +680,8 @@
   // Initialization.
   contents()->NavigateAndCommit(kUrl0);
   FrameTreeNode* node = main_test_rfh()->frame_tree_node();
+  bool expect_site_instance_change =
+      ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
 
   // Start a renderer-initiated user-initiated navigation to the 1st URL.
   EXPECT_FALSE(main_test_rfh()->navigation_request());
@@ -674,8 +695,7 @@
   EXPECT_EQ(kUrl1, request1->common_params().url);
   EXPECT_FALSE(request1->browser_initiated());
   EXPECT_TRUE(request1->common_params().has_user_gesture);
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -695,8 +715,7 @@
   EXPECT_EQ(kUrl2, request2->common_params().url);
   EXPECT_FALSE(request2->browser_initiated());
   EXPECT_FALSE(request2->common_params().has_user_gesture);
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -762,6 +781,8 @@
   contents()->NavigateAndCommit(kUrl0);
   FrameTreeNode* node = main_test_rfh()->frame_tree_node();
   int32_t site_instance_id_0 = main_test_rfh()->GetSiteInstance()->GetId();
+  bool expect_site_instance_change =
+      ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
 
   // Start a renderer-initiated non-user-initiated navigation to the 1st URL.
   EXPECT_FALSE(main_test_rfh()->navigation_request());
@@ -776,8 +797,7 @@
   EXPECT_EQ(kUrl1, request1->common_params().url);
   EXPECT_FALSE(request1->browser_initiated());
   EXPECT_FALSE(request1->common_params().has_user_gesture);
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -797,8 +817,7 @@
   EXPECT_EQ(kUrl2, request2->common_params().url);
   EXPECT_FALSE(request2->browser_initiated());
   EXPECT_FALSE(request2->common_params().has_user_gesture);
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
   } else {
     EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -811,9 +830,7 @@
   navigation2->Commit();
   EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
 
-  // The SiteInstance did not change unless site-per-process is enabled.
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (expect_site_instance_change) {
     EXPECT_NE(site_instance_id_0, main_test_rfh()->GetSiteInstance()->GetId());
   } else {
     EXPECT_EQ(site_instance_id_0, main_test_rfh()->GetSiteInstance()->GetId());
@@ -1042,7 +1059,7 @@
       ChildProcessSecurityPolicy::IsolatedOriginSource::TEST,
       browser_context());
   contents()->NavigateAndCommit(kUrl1);
-  SiteInstance* current_instance = main_test_rfh()->GetSiteInstance();
+  SiteInstanceImpl* current_instance = main_test_rfh()->GetSiteInstance();
   ASSERT_TRUE(current_instance);
 
   // 1) Convert a descriptor pointing to the current instance.
@@ -1101,12 +1118,15 @@
     EXPECT_NE(current_instance, related_instance.get());
     EXPECT_NE(unrelated_instance.get(), related_instance.get());
 
-    if (AreAllSitesIsolatedForTesting()) {
-      EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrlSameSiteAs2),
-                related_instance->GetSiteURL());
+    auto* related_instance_impl =
+        static_cast<SiteInstanceImpl*>(related_instance.get());
+
+    if (AreDefaultSiteInstancesEnabled()) {
+      ASSERT_TRUE(related_instance_impl->IsDefaultSiteInstance());
     } else {
-      EXPECT_TRUE(static_cast<SiteInstanceImpl*>(related_instance.get())
-                      ->IsDefaultSiteInstance());
+      EXPECT_EQ(SiteInstanceImpl::ComputeSiteInfoForTesting(
+                    current_instance->GetIsolationContext(), kUrlSameSiteAs2),
+                related_instance_impl->GetSiteInfo());
     }
   }
 
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index 69aeef8..13bc06dd 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -791,14 +791,14 @@
   EXPECT_EQ(main_frame, child->GetBeforeUnloadInitiator());
   EXPECT_EQ(main_frame, main_frame->GetBeforeUnloadInitiator());
 
-  // When in --site-per-process mode, LoadURL() should trigger two beforeunload
-  // IPCs for subframe and the main frame: the subframe has a beforeunload
-  // handler, and while the main frame does not, we always send the IPC to
-  // navigating frames, regardless of whether or not they have a handler.
+  // When in a strict SiteInstances mode, LoadURL() should trigger two
+  // beforeunload IPCs for subframe and the main frame: the subframe has a
+  // beforeunload handler, and while the main frame does not, we always send the
+  // IPC to navigating frames, regardless of whether or not they have a handler.
   //
-  // Without --site-per-process, only one beforeunload IPC should be sent to
+  // Without strict SiteInstances, only one beforeunload IPC should be sent to
   // the main frame, which will handle both (same-process) frames.
-  EXPECT_EQ(AreAllSitesIsolatedForTesting() ? 2u : 1u,
+  EXPECT_EQ(AreStrictSiteInstancesEnabled() ? 2u : 1u,
             main_frame->beforeunload_pending_replies_.size());
 
   // Wait for the beforeunload dialog to be shown from the subframe.
@@ -811,12 +811,12 @@
   EXPECT_TRUE(main_frame->is_waiting_for_beforeunload_completion());
   EXPECT_FALSE(child->is_waiting_for_beforeunload_completion());
 
-  // In --site-per-process mode, the beforeunload completion callback should
-  // happen on the child RFH.  Without --site-per-process, it will come from the
-  // main frame RFH, which processes beforeunload for both main frame and child
-  // frame, since they are in the same process.
+  // In a strict SiteInstances mode, the beforeunload completion callback should
+  // happen on the child RFH.  Without strict SiteInstances, it will come from
+  // the main frame RFH, which processes beforeunload for both main frame and
+  // child frame, since they are in the same process and SiteInstance.
   RenderFrameHostImpl* frame_that_sent_beforeunload_ipc =
-      AreAllSitesIsolatedForTesting() ? child : main_frame;
+      AreStrictSiteInstancesEnabled() ? child : main_frame;
   EXPECT_TRUE(main_frame->beforeunload_pending_replies_.count(
       frame_that_sent_beforeunload_ipc));
 
@@ -4997,6 +4997,15 @@
   return parent->child_at(initial_child_count)->current_frame_host();
 }
 
+RenderFrameHostImpl* AddChildInitialEmptyDoc(RenderFrameHostImpl* parent) {
+  return AddChildWithScript(parent, R"(
+    const iframe = document.createElement("iframe");
+    iframe.src = "/nocontent";  // Returns 204 NO CONTENT, thus no doc commits.
+    document.body.appendChild(iframe);
+    true  // Do not wait for iframe.onload, which never fires.
+  )");
+}
+
 RenderFrameHostImpl* AddChildFromAboutBlank(RenderFrameHostImpl* parent) {
   return AddChildWithScript(parent, R"(
     new Promise((resolve) => {
@@ -5030,6 +5039,17 @@
   )");
 }
 
+RenderFrameHostImpl* AddChildFromJavascriptURL(RenderFrameHostImpl* parent) {
+  return AddChildWithScript(parent, R"(
+    new Promise((resolve) => {
+      const iframe = document.createElement("iframe");
+      iframe.src = "javascript:'foo'";
+      iframe.onload = _ => { resolve(true); };
+      document.body.appendChild(iframe);
+    })
+  )");
+}
+
 RenderFrameHostImpl* AddChildFromBlob(RenderFrameHostImpl* parent) {
   return AddChildWithScript(parent, R"(
     new Promise((resolve) => {
@@ -5112,6 +5132,40 @@
 
 IN_PROC_BROWSER_TEST_F(
     RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsAddressSpaceForInitialEmptyDocFromPublic) {
+  EXPECT_TRUE(NavigateToURL(
+      shell(), SecureTreatAsPublicAddressURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame = AddChildInitialEmptyDoc(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child's address space
+  // is kPublic once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsAddressSpaceForInitialEmptyDocFromLocal) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame = AddChildInitialEmptyDoc(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child's address space
+  // is kLocal once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
     IframeInheritsAddressSpaceForAboutSrcdocFromPublic) {
   EXPECT_TRUE(NavigateToURL(
       shell(), SecureTreatAsPublicAddressURL(*embedded_test_server())));
@@ -5184,6 +5238,42 @@
 
 IN_PROC_BROWSER_TEST_F(
     RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsAddressSpaceForJavascriptURLFromPublic) {
+  EXPECT_TRUE(NavigateToURL(
+      shell(), SecureTreatAsPublicAddressURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame =
+      AddChildFromJavascriptURL(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child's address space
+  // is kPublic once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsAddressSpaceForJavascriptURLFromLocal) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame =
+      AddChildFromJavascriptURL(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child's address space
+  // is kLocal once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
     IframeInheritsAddressSpaceForBlobURLFromPublic) {
   EXPECT_TRUE(NavigateToURL(
       shell(), SecureTreatAsPublicAddressURL(*embedded_test_server())));
@@ -5289,6 +5379,40 @@
 
 IN_PROC_BROWSER_TEST_F(
     RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsSecureContextForInitialEmptyDocFromSecure) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame = AddChildInitialEmptyDoc(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child is a secure context
+  // once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsSecureContextForInitialEmptyDocFromInsecure) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), InsecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame = AddChildInitialEmptyDoc(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child is not a secure
+  // context once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
     IframeInheritsSecureContextForAboutSrcdocFromSecure) {
   EXPECT_TRUE(
       NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
@@ -5355,6 +5479,42 @@
 
 IN_PROC_BROWSER_TEST_F(
     RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsSecureContextForJavascriptURLFromSecure) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame =
+      AddChildFromJavascriptURL(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child is a secure context
+  // once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
+    IframeInheritsSecureContextForJavascriptURLFromInsecure) {
+  EXPECT_TRUE(
+      NavigateToURL(shell(), InsecureDefaultURL(*embedded_test_server())));
+
+  RenderFrameHostImpl* child_frame =
+      AddChildFromJavascriptURL(root_frame_host());
+  ASSERT_NE(nullptr, child_frame);
+
+  const network::mojom::ClientSecurityStatePtr& security_state =
+      child_frame->last_committed_client_security_state();
+
+  // TODO(https://crbug.com/1126856): Expect that the child is not a secure
+  // context once inheritance is fixed.
+  EXPECT_TRUE(security_state.is_null());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTestWithInsecurePrivateNetworkRequestsBlocked,
     IframeInheritsSecureContextForBlobURLFromSecure) {
   EXPECT_TRUE(
       NavigateToURL(shell(), SecureDefaultURL(*embedded_test_server())));
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
index da9f876..6c151b9 100644
--- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -90,6 +90,13 @@
 
 namespace {
 
+// Helper function that return true in cases where the current process model
+// will return the same SiteInstance for a cross-process navigation.
+bool ExpectSameSiteInstance() {
+  return AreDefaultSiteInstancesEnabled() &&
+         !CanCrossSiteNavigationsProactivelySwapBrowsingInstances();
+}
+
 const char kOpenUrlViaClickTargetFunc[] =
     "(function(url) {\n"
     "  var lnk = document.createElement(\"a\");\n"
@@ -680,10 +687,10 @@
   // Should have the same SiteInstance unless we're in site-per-process mode.
   scoped_refptr<SiteInstance> blank_site_instance(
       new_shell->web_contents()->GetSiteInstance());
-  if (AreAllSitesIsolatedForTesting())
-    EXPECT_NE(orig_site_instance, blank_site_instance);
-  else
+  if (AreDefaultSiteInstancesEnabled())
     EXPECT_EQ(orig_site_instance, blank_site_instance);
+  else
+    EXPECT_NE(orig_site_instance, blank_site_instance);
 }
 
 // Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
@@ -715,14 +722,12 @@
   EXPECT_EQ("/title2.html",
             shell()->web_contents()->GetLastCommittedURL().path());
 
-  // Should have the same SiteInstance unless we're in site-per-process mode.
   scoped_refptr<SiteInstance> noref_site_instance(
       shell()->web_contents()->GetSiteInstance());
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
-    EXPECT_NE(orig_site_instance, noref_site_instance);
-  } else {
+  if (ExpectSameSiteInstance()) {
     EXPECT_EQ(orig_site_instance, noref_site_instance);
+  } else {
+    EXPECT_NE(orig_site_instance, noref_site_instance);
   }
 }
 
@@ -754,14 +759,12 @@
   EXPECT_EQ("/title2.html",
             shell()->web_contents()->GetLastCommittedURL().path());
 
-  // Should have the same SiteInstance unless we're in site-per-process mode.
   scoped_refptr<SiteInstance> noref_site_instance(
       shell()->web_contents()->GetSiteInstance());
-  if (AreAllSitesIsolatedForTesting() ||
-      CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
-    EXPECT_NE(orig_site_instance, noref_site_instance);
-  } else {
+  if (ExpectSameSiteInstance()) {
     EXPECT_EQ(orig_site_instance, noref_site_instance);
+  } else {
+    EXPECT_NE(orig_site_instance, noref_site_instance);
   }
 }
 
@@ -840,7 +843,7 @@
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, MAYBE_DisownOpener) {
   StartEmbeddedServer();
 
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed to get a non-default
     // SiteInstance for navigations to this origin.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -940,7 +943,7 @@
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                        PreserveTopFrameWindowNameOnCrossProcessNavigations) {
   StartEmbeddedServer();
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed it is placed in a different
     // process.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -1008,7 +1011,7 @@
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                        SupportCrossProcessPostMessage) {
   StartEmbeddedServer();
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed it is placed in a different
     // process.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -1149,7 +1152,7 @@
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                        SupportCrossProcessPostMessageWithMessagePort) {
   StartEmbeddedServer();
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed it is placed in a different
     // process.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -1239,7 +1242,7 @@
                        AllowTargetedNavigationsInOpenerAfterSwap) {
   StartEmbeddedServer();
 
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed to get a non-default
     // SiteInstance for navigations to this origin.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -1346,7 +1349,7 @@
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                        ProcessExitWithSwappedOutViews) {
   StartEmbeddedServer();
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed to get a non-default
     // SiteInstance for navigations to this origin.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -2349,7 +2352,7 @@
                        DontPreemptNavigationWithFrameTreeUpdate) {
   StartEmbeddedServer();
 
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed to get a non-default
     // SiteInstance for navigations to this origin.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -3080,7 +3083,7 @@
                        ReinitializeOpenerChainAfterCrashAndReload) {
   StartEmbeddedServer();
 
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed to get a non-default
     // SiteInstance for navigations to this origin.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -3149,7 +3152,7 @@
 // the other popup, and ensure that the opener is updated in all processes.
 IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, UpdateOpener) {
   StartEmbeddedServer();
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "foo.com" so we are guaranteed it is placed in a different
     // process.
     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
@@ -3921,9 +3924,9 @@
 
   // The FrameTree contains two successful instances of each site plus an
   // unsuccessfully-navigated third instance of B with a blank URL.  When not in
-  // site-per-process mode, the FrameTreeVisualizer depicts all nodes as
+  // strict SiteInstance mode, the FrameTreeVisualizer depicts all nodes as
   // referencing Site A because iframes are identified with their root site.
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreStrictSiteInstancesEnabled()) {
     EXPECT_EQ(
         " Site A ------------ proxies for B\n"
         "   +--Site B ------- proxies for A\n"
@@ -4379,8 +4382,7 @@
   // Since this is a browser-initiated, cross-site navigation, it will swap
   // BrowsingInstances, and create a new foo.com SiteInstance, distinct from
   // the initial one.
-  if (!AreAllSitesIsolatedForTesting() &&
-      !CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
+  if (ExpectSameSiteInstance()) {
     EXPECT_EQ(site_instance, shell()->web_contents()->GetSiteInstance());
   } else {
     EXPECT_NE(site_instance, shell()->web_contents()->GetSiteInstance());
@@ -4785,10 +4787,10 @@
                        ErrorPageNavigationReload_InSubframe_NetworkError) {
   StartEmbeddedServer();
 
-  // Isolating a.com helps more robustly exercise platforms without strict site
-  // isolation - we want to ensure that enforcing |initiator_origin| in
-  // BeginNavigation is compatible with process locks, even when only one of the
-  // frames requires isolation.
+  // Isolating a.com helps more robustly exercise platforms without strict
+  // site isolation - we want to ensure that enforcing |initiator_origin| in
+  // BeginNavigation is compatible with process locks, even when only one of
+  // the frames requires isolation.
   IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
                            {"b.com"});
 
@@ -4953,11 +4955,11 @@
         child1->current_frame_host()->GetSiteInstance();
 
     GURL c_site_url = child1_site_instance->GetSiteURL();
-    if (AreAllSitesIsolatedForTesting()) {
+    if (AreDefaultSiteInstancesEnabled()) {
+      EXPECT_TRUE(child1_site_instance->IsDefaultSiteInstance());
+    } else {
       EXPECT_EQ("c.com", c_site_url.host());
       EXPECT_EQ(test_url.host(), c_site_url.host());
-    } else {
-      EXPECT_TRUE(child1_site_instance->IsDefaultSiteInstance());
     }
     EXPECT_NE(a_site_url, c_site_url);
     EXPECT_NE(b_site_url, c_site_url);
@@ -5749,13 +5751,15 @@
       static_cast<SiteInstanceImpl*>(
           web_contents->GetMainFrame()->GetSiteInstance());
 
-  // Check that A and B are in different BrowsingInstances (both are in default
-  // SiteInstances of different BrowsingInstances) but have the same renderer
-  // process.
+  // Check that A and B are in different BrowsingInstances but have the same
+  // renderer process. When default SiteInstances are enabled, A and B are
+  // both default SiteInstances of different BrowsingInstances.
   EXPECT_FALSE(a_site_instance->IsRelatedSiteInstance(b_site_instance.get()));
-  EXPECT_TRUE(a_site_instance->IsDefaultSiteInstance());
-  EXPECT_TRUE(b_site_instance->IsDefaultSiteInstance());
   EXPECT_EQ(a_site_instance->GetProcess(), b_site_instance->GetProcess());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            a_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            b_site_instance->IsDefaultSiteInstance());
 }
 
 // Different from renderer-initiated cross-site navigations, browser-initiated
@@ -5784,12 +5788,15 @@
       static_cast<SiteInstanceImpl*>(
           web_contents->GetMainFrame()->GetSiteInstance());
 
-  // Check that A and B are in different BrowsingInstances (both are in default
-  // SiteInstances of different BrowsingInstances) and renderer processes.
+  // Check that A and B are in different BrowsingInstances and renderer
+  // processes. When default SiteInstances are enabled, A and B are
+  // both default SiteInstances of different BrowsingInstances.
   EXPECT_FALSE(a_site_instance->IsRelatedSiteInstance(b_site_instance.get()));
-  EXPECT_TRUE(a_site_instance->IsDefaultSiteInstance());
-  EXPECT_TRUE(b_site_instance->IsDefaultSiteInstance());
   EXPECT_NE(a_site_instance->GetProcess(), b_site_instance->GetProcess());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            a_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            b_site_instance->IsDefaultSiteInstance());
 }
 
 // A test ContentBrowserClient implementation that enforce process-per-site mode
@@ -5844,13 +5851,14 @@
       static_cast<SiteInstanceImpl*>(
           web_contents->GetMainFrame()->GetSiteInstance());
 
-  // Check that A and B are in different BrowsingInstances (both are in default
-  // SiteInstances of different BrowsingInstances) but have the same renderer
-  // process.
+  // Check that A and B are in different BrowsingInstances but have the same
+  // renderer process.
   EXPECT_FALSE(a_site_instance->IsRelatedSiteInstance(b_site_instance.get()));
-  EXPECT_TRUE(a_site_instance->IsDefaultSiteInstance());
-  EXPECT_TRUE(b_site_instance->IsDefaultSiteInstance());
   EXPECT_EQ(b_site_instance->GetProcess(), original_process);
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            a_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            b_site_instance->IsDefaultSiteInstance());
 
   // Make sure we will use process-per-site for C.
   // Note this is enforcing process-per-site for all sites, which is why we turn
@@ -5864,10 +5872,11 @@
       static_cast<SiteInstanceImpl*>(
           web_contents->GetMainFrame()->GetSiteInstance());
 
-  // Check that B and C are in different BrowsingInstances (both are in default
-  // SiteInstances of different BrowsingInstances) and renderer processes.
+  // Check that B and C are in different BrowsingInstances and renderer
+  // processes.
   EXPECT_FALSE(b_site_instance->IsRelatedSiteInstance(c_site_instance.get()));
-  EXPECT_TRUE(c_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            c_site_instance->IsDefaultSiteInstance());
   EXPECT_NE(c_site_instance->GetProcess(), original_process);
   // C is using the process for C's site.
   EXPECT_EQ(c_site_instance->GetProcess(),
@@ -5885,7 +5894,8 @@
           web_contents->GetMainFrame()->GetSiteInstance());
   EXPECT_FALSE(b2_site_instance->IsRelatedSiteInstance(c_site_instance.get()));
   EXPECT_FALSE(b2_site_instance->IsRelatedSiteInstance(b_site_instance.get()));
-  EXPECT_TRUE(b2_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            b2_site_instance->IsDefaultSiteInstance());
   EXPECT_NE(b2_site_instance->GetProcess(), original_process);
   // B will reuse C's process here, even though C is process-per-site, because
   // neither of them require a dedicated process.
@@ -5941,12 +5951,13 @@
       static_cast<SiteInstanceImpl*>(
           web_contents->GetMainFrame()->GetSiteInstance());
 
-  // Check that A and B are in different BrowsingInstances (both are in default
-  // SiteInstances of different BrowsingInstances) but B should use the sole
-  // process assigned to site B.
+  // Check that A and B are in different BrowsingInstances but B should use the
+  // sole process assigned to site B.
   EXPECT_FALSE(a_site_instance->IsRelatedSiteInstance(b_site_instance.get()));
-  EXPECT_TRUE(a_site_instance->IsDefaultSiteInstance());
-  EXPECT_TRUE(b_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            a_site_instance->IsDefaultSiteInstance());
+  EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
+            b_site_instance->IsDefaultSiteInstance());
   EXPECT_NE(b_site_instance->GetProcess(), original_process);
   EXPECT_EQ(b_site_instance->GetProcess(), process_for_b);
   EXPECT_EQ(b_site_instance->GetProcess(),
@@ -7697,6 +7708,11 @@
   }
 
   {
+    FrameTreeNode* root = web_contents->GetFrameTree()->root();
+    RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host();
+    bool subframe_was_in_same_site_instance =
+        root->current_frame_host()->GetSiteInstance() ==
+        child_rfh->GetSiteInstance();
     // 4) Set up a script that will call postMessage on a cross-site iframe
     // after we commit the next navigation.
     // TODO(https://crbug.com/1110497): GetAsyncScriptExecutorCallback() must be
@@ -7722,7 +7738,8 @@
     // have already unloaded).
     ExpectBucketCount(kActionAfterPagehideHistogramName,
                       ActionAfterPagehide::kSentPostMessage, 2);
-    if (AreAllSitesIsolatedForTesting() && !IsBackForwardCacheEnabled()) {
+
+    if (!subframe_was_in_same_site_instance && !IsBackForwardCacheEnabled()) {
       ExpectBucketCount(kActionAfterPagehideHistogramName,
                         ActionAfterPagehide::kReceivedPostMessage, 1);
     } else {
@@ -8543,12 +8560,8 @@
   scoped_refptr<SiteInstanceImpl> new_instance =
       web_contents->GetMainFrame()->GetSiteInstance();
   EXPECT_EQ(url1, web_contents->GetLastCommittedURL());
-  if (AreAllSitesIsolatedForTesting() || AreDefaultSiteInstancesEnabled()) {
-    EXPECT_NE(instance1, new_instance);
-    EXPECT_EQ(GURL(), new_instance->GetSiteURL());
-  } else {
-    EXPECT_EQ(instance1, new_instance);
-  }
+  EXPECT_NE(instance1, new_instance);
+  EXPECT_EQ(GURL(), new_instance->GetSiteURL());
   EXPECT_TRUE(new_instance->HasProcess());
 
   // Because url1 does not set a site URL, it should not lock the new process
diff --git a/content/browser/renderer_host/render_frame_host_manager_unittest.cc b/content/browser/renderer_host/render_frame_host_manager_unittest.cc
index 89b0916..bbbae29 100644
--- a/content/browser/renderer_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_unittest.cc
@@ -314,9 +314,9 @@
     RenderViewHostImplTestHarness::SetUp();
     WebUIControllerFactory::RegisterFactory(&factory_);
 
-    if (AreDefaultSiteInstancesEnabled()) {
-      // Isolate |isolated_cross_site_url()| so we can't get a default
-      // SiteInstance for it.
+    if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
+      // Isolate |isolated_cross_site_url()|so it cannot share a process
+      // with another site.
       ChildProcessSecurityPolicyImpl::GetInstance()->AddIsolatedOrigins(
           {url::Origin::Create(isolated_cross_site_url())},
           ChildProcessSecurityPolicy::IsolatedOriginSource::TEST,
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 063fb15b..4ca1acd9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2615,7 +2615,7 @@
   }
 
   float scale = GetScaleFactorForView(GetView());
-  gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(bitmap, scale);
   view->StartDragging(filtered_data, drag_operations_mask, image,
                       bitmap_offset_in_dip, *event_info, this);
 }
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 065444d1..046084c5 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -112,7 +112,7 @@
                                              int* target_routing_id) {
   GURL foo("http://foo.com/simple_page.html");
 
-  if (AreDefaultSiteInstancesEnabled()) {
+  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
     // Isolate "bar.com" so we are guaranteed to get a different process
     // for navigations to this origin.
     IsolateOriginsForTesting(server, shell->web_contents(), {"bar.com"});
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index ec0849f9..c8fc1dd 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -431,8 +431,9 @@
   // Make sure feature list command-line options are set in a way that forces
   // default SiteInstance creation on all platforms.
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      features::kProcessSharingWithDefaultSiteInstances);
+  feature_list.InitWithFeatures(
+      /* enable */ {features::kProcessSharingWithDefaultSiteInstances},
+      /* disable */ {features::kProcessSharingWithStrictSiteInstances});
   EXPECT_TRUE(base::FeatureList::IsEnabled(
       features::kProcessSharingWithDefaultSiteInstances));
   EXPECT_FALSE(base::FeatureList::IsEnabled(
@@ -1706,12 +1707,12 @@
       context(), UrlInfo::CreateForTesting(kGuestUrl),
       CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
   EXPECT_FALSE(instance1->IsGuest());
-  if (AreAllSitesIsolatedForTesting()) {
+  if (AreDefaultSiteInstancesEnabled()) {
+    EXPECT_TRUE(instance1->IsDefaultSiteInstance());
+  } else {
     EXPECT_NE(kGuestUrl, instance1->GetSiteURL());
     EXPECT_EQ(GURL(std::string(kGuestScheme) + "://abc123/"),
               instance1->GetSiteURL());
-  } else {
-    EXPECT_TRUE(instance1->IsDefaultSiteInstance());
   }
 
   // Verify that a SiteInstance created with CreateForGuest() is considered
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 26118b8..9743e6c 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -2039,6 +2039,9 @@
     // depending on |test_type|.
     root_gesture_event_observer.Wait();
 
+    // Wait for all remaining input events to be processed by root_rwhv
+    RunUntilInputProcessed(root_rwhv->GetRenderWidgetHost());
+
     // Shut down.
     touch_emulator->Disable();
   }
@@ -2054,9 +2057,8 @@
   RunTest(ScrollBubbling);
 }
 
-// TODO(crbug.com/1156243): Disabled as flaky because of crrev.com/c/2562796
 IN_PROC_BROWSER_TEST_F(SitePerProcessEmulatedTouchBrowserTest,
-                       DISABLED_EmulatedTouchPinchGoesToMainFrame) {
+                       EmulatedTouchPinchGoesToMainFrame) {
   RunTest(PinchGoesToMainFrame);
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index d5309b3..8056f3b 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -832,9 +832,6 @@
       audio_stream_monitor_(this),
       media_web_contents_observer_(
           std::make_unique<MediaWebContentsObserver>(this)),
-#if !defined(OS_ANDROID)
-      page_scale_factor_is_one_(true),
-#endif  // !defined(OS_ANDROID)
       is_overlay_content_(false),
       showing_context_menu_(false),
       text_autosizer_page_info_({0, 0, 1.f}) {
@@ -5789,22 +5786,21 @@
 #if !defined(OS_ANDROID)
   // While page scale factor is used on mobile, this PageScaleFactorIsOne logic
   // is only needed on desktop.
+  bool was_one = page_scale_factor_ == 1.f;
   bool is_one = page_scale_factor == 1.f;
-  if (is_one != page_scale_factor_is_one_) {
-    page_scale_factor_is_one_ = is_one;
-
+  if (is_one != was_one) {
     HostZoomMapImpl* host_zoom_map =
         static_cast<HostZoomMapImpl*>(HostZoomMap::GetForWebContents(this));
 
     if (host_zoom_map) {
       host_zoom_map->SetPageScaleFactorIsOneForView(
           source->GetProcess()->GetID(),
-          source->GetRenderViewHost()->GetRoutingID(),
-          page_scale_factor_is_one_);
+          source->GetRenderViewHost()->GetRoutingID(), is_one);
     }
   }
 #endif  // !defined(OS_ANDROID)
 
+  page_scale_factor_ = page_scale_factor;
   observers_.ForEachObserver([&](WebContentsObserver* observer) {
     observer->OnPageScaleFactorChanged(page_scale_factor);
   });
@@ -8610,12 +8606,10 @@
   OPTIONAL_TRACE_EVENT1("content",
                         "WebContentsImpl::UpdateWebContentsVisibility",
                         "visibility", visibility);
-  // Occlusion is disabled when |features::kWebContentsOcclusion| is disabled
-  // (for power and speed impact assessment) or when
+  // Occlusion is disabled when
   // |switches::kDisableBackgroundingOccludedWindowsForTesting| is specified on
   // the command line (to avoid flakiness in browser tests).
   const bool occlusion_is_disabled =
-      !base::FeatureList::IsEnabled(features::kWebContentsOcclusion) ||
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableBackgroundingOccludedWindowsForTesting);
   if (occlusion_is_disabled && visibility == Visibility::OCCLUDED)
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index a56cb36..983fd6d4 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1231,6 +1231,8 @@
     return javascript_dialog_navigation_deferrer_.get();
   }
 
+  float page_scale_factor() { return page_scale_factor_; }
+
   // Returns the focused frame's input handler.
   blink::mojom::FrameWidgetInputHandler* GetFocusedFrameWidgetInputHandler();
 
@@ -1995,9 +1997,7 @@
 
   std::unique_ptr<RenderWidgetHostInputEventRouter> rwh_input_event_router_;
 
-#if !defined(OS_ANDROID)
-  bool page_scale_factor_is_one_;
-#endif  // !defined(OS_ANDROID)
+  float page_scale_factor_ = 1;
 
   // TextInputManager tracks the IME-related state for all the
   // RenderWidgetHostViews on this WebContents. Only exists on the outermost
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index 5ce9825..1d3e78a 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1653,7 +1653,6 @@
   // occluded (because we treat it as hidden), unless when occlusion is
   // disabled, in which case we treat it the same as being visible.
   const bool occlusion_is_disabled =
-      !base::FeatureList::IsEnabled(features::kWebContentsOcclusion) ||
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableBackgroundingOccludedWindowsForTesting);
   web_contents->UpdateWebContentsVisibility(Visibility::OCCLUDED);
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index ab1afab..f9b7b17 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -113,9 +113,9 @@
     WebUIControllerFactory::RegisterFactory(
         ContentWebUIControllerFactory::GetInstance());
 
-    if (AreDefaultSiteInstancesEnabled()) {
-      // Isolate |isolated_cross_site_url()| so we can't get a default
-      // SiteInstance for it.
+    if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
+      // Isolate |isolated_cross_site_url()| so it cannot share a process
+      // with another site.
       ChildProcessSecurityPolicyImpl::GetInstance()->AddIsolatedOrigins(
           {url::Origin::Create(isolated_cross_site_url())},
           ChildProcessSecurityPolicy::IsolatedOriginSource::TEST,
@@ -1684,9 +1684,6 @@
 }
 
 TEST_F(WebContentsImplTest, UpdateWebContentsVisibility) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion);
-
   TestRenderWidgetHostView* view = static_cast<TestRenderWidgetHostView*>(
       main_test_rfh()->GetRenderViewHost()->GetWidget()->GetView());
   TestWebContentsObserver observer(contents());
@@ -1793,8 +1790,6 @@
 }
 
 TEST_F(WebContentsImplTest, OccludeWithCapturer) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion);
   HideOrOccludeWithCapturerTest(contents(), Visibility::OCCLUDED);
 }
 
diff --git a/content/browser/web_contents/web_contents_view_aura_unittest.cc b/content/browser/web_contents/web_contents_view_aura_unittest.cc
index d9df069..66a21888 100644
--- a/content/browser/web_contents/web_contents_view_aura_unittest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_unittest.cc
@@ -222,9 +222,6 @@
 }
 
 TEST_F(WebContentsViewAuraTest, OccludeView) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion);
-
   EXPECT_EQ(web_contents()->GetVisibility(), Visibility::VISIBLE);
   occluding_window_->Show();
   EXPECT_EQ(web_contents()->GetVisibility(), Visibility::OCCLUDED);
@@ -624,4 +621,4 @@
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/web_package/web_bundle_browsertest.cc b/content/browser/web_package/web_bundle_browsertest.cc
index 75e0e3c3..b9282e96 100644
--- a/content/browser/web_package/web_bundle_browsertest.cc
+++ b/content/browser/web_package/web_bundle_browsertest.cc
@@ -1370,8 +1370,8 @@
             GetLoadResultForNavigationTest(GetFirstChild(web_contents)));
 
   FrameTreeNode* iframe_node = GetFirstChild(web_contents);
-  bool is_same_process = (iframe_node->parent()->GetProcess() ==
-                          iframe_node->current_frame_host()->GetProcess());
+  bool no_proxy_to_parent =
+      iframe_node->render_manager()->GetProxyToParent() == nullptr;
 
   RunScriptAndObserveNavigation(
       "Navigate the iframe to /1-page/", web_contents,
@@ -1387,7 +1387,7 @@
   // from web bundle. To support this case we need to change
   // NavigationControllerImpl::NavigateFromFrameProxy() to correctly handle
   // the WebBundleHandleTracker.
-  EXPECT_EQ(is_same_process
+  EXPECT_EQ(no_proxy_to_parent
                 ? "/1-page/ from wbn, /1-page/script from wbn"
                 : "/1-page/ from server, /1-page/script from server",
             GetLoadResultForNavigationTest(GetFirstChild(web_contents)));
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index cfe5829..29f0331 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -21,6 +21,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info.h"
 #include "base/test/bind.h"
 #include "base/test/gtest_util.h"
@@ -3515,11 +3516,12 @@
 
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override {
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override {
     *collected_pin_ = true;
     *min_pin_length_ = options.min_pin_length;
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(provide_pin_cb), kTestPIN));
+        FROM_HERE,
+        base::BindOnce(std::move(provide_pin_cb), base::UTF8ToUTF16(kTestPIN)));
   }
 
   void StartBioEnrollment(base::OnceClosure next_callback) override {
@@ -3641,16 +3643,17 @@
   DISALLOW_COPY_AND_ASSIGN(UVAuthenticatorImplTest);
 };
 
-using PINMode =
-    device::FidoRequestHandlerBase::Observer::CollectPINOptions::Mode;
+using PINReason = device::pin::PINEntryReason;
+using PINError = device::pin::PINEntryError;
 
 // PINExpectation represent expected |mode|, |attempts|, |min_pin_length| and
 // the PIN to answer with.
 struct PINExpectation {
-  PINMode mode;
+  PINReason reason;
   std::string pin;
   int attempts;
   uint32_t min_pin_length = device::kMinPinLength;
+  PINError error = PINError::kNoError;
 };
 
 class PINTestAuthenticatorRequestDelegate
@@ -3669,21 +3672,23 @@
 
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override {
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override {
     DCHECK(supports_pin_);
     DCHECK(!expected_.empty());
-    if (expected_.front().mode == CollectPINOptions::Mode::kChallenge) {
+    if (expected_.front().reason == PINReason::kChallenge) {
       DCHECK(options.attempts == expected_.front().attempts)
           << "got: " << options.attempts
           << " expected: " << expected_.front().attempts;
     }
     DCHECK_EQ(expected_.front().min_pin_length, options.min_pin_length);
-    DCHECK_EQ(expected_.front().mode, options.mode);
+    DCHECK_EQ(expected_.front().reason, options.reason);
+    DCHECK_EQ(expected_.front().error, options.error);
     std::string pin = std::move(expected_.front().pin);
     expected_.pop_front();
 
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(provide_pin_cb), std::move(pin)));
+        FROM_HERE, base::BindOnce(std::move(provide_pin_cb),
+                                  base::UTF8ToUTF16(std::move(pin))));
   }
 
   void FinishCollectToken() override {}
@@ -3862,12 +3867,12 @@
 
               case kSetPIN:
                 // A single PIN prompt to set a PIN is expected.
-                test_client_.expected = {{PINMode::kSet, kTestPIN}};
+                test_client_.expected = {{PINReason::kSet, kTestPIN}};
                 break;
 
               case kUsePIN:
                 // A single PIN prompt to get the PIN is expected.
-                test_client_.expected = {{PINMode::kChallenge, kTestPIN, 8}};
+                test_client_.expected = {{PINReason::kChallenge, kTestPIN, 8}};
                 break;
 
               default:
@@ -3912,9 +3917,11 @@
   virtual_device_factory_->mutable_state()->pin_retries =
       device::kMaxPinRetries;
 
-  test_client_.expected = {{PINMode::kChallenge, "wrong", 8},
-                           {PINMode::kChallenge, "wrong", 7},
-                           {PINMode::kChallenge, "wrong", 6}};
+  test_client_.expected = {{PINReason::kChallenge, "wrong", 8},
+                           {PINReason::kChallenge, "wrong", 7,
+                            device::kMinPinLength, PINError::kWrongPIN},
+                           {PINReason::kChallenge, "wrong", 6,
+                            device::kMinPinLength, PINError::kWrongPIN}};
   EXPECT_EQ(AuthenticatorMakeCredential(make_credential_options()).status,
             AuthenticatorStatus::NOT_ALLOWED_ERROR);
   EXPECT_EQ(5, virtual_device_factory_->mutable_state()->pin_retries);
@@ -3928,7 +3935,7 @@
   virtual_device_factory_->mutable_state()->pin = kTestPIN;
   virtual_device_factory_->mutable_state()->pin_retries = 1;
 
-  test_client_.expected = {{PINMode::kChallenge, "wrong", 1}};
+  test_client_.expected = {{PINReason::kChallenge, "wrong", 1}};
   EXPECT_EQ(AuthenticatorMakeCredential().status,
             AuthenticatorStatus::NOT_ALLOWED_ERROR);
   EXPECT_EQ(0, virtual_device_factory_->mutable_state()->pin_retries);
@@ -3943,8 +3950,9 @@
       device::kMaxPinRetries;
 
   // Test that we can successfully get a PIN token after a failure.
-  test_client_.expected = {{PINMode::kChallenge, "wrong", 8},
-                           {PINMode::kChallenge, kTestPIN, 7}};
+  test_client_.expected = {{PINReason::kChallenge, "wrong", 8},
+                           {PINReason::kChallenge, kTestPIN, 7,
+                            device::kMinPinLength, PINError::kWrongPIN}};
   EXPECT_EQ(AuthenticatorMakeCredential().status, AuthenticatorStatus::SUCCESS);
   EXPECT_EQ(static_cast<int>(device::kMaxPinRetries),
             virtual_device_factory_->mutable_state()->pin_retries);
@@ -3961,7 +3969,7 @@
   virtual_device_factory_->mutable_state()->pin_retries =
       device::kMaxPinRetries;
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
   EXPECT_EQ(AuthenticatorMakeCredential().status, AuthenticatorStatus::SUCCESS);
   EXPECT_EQ(taps, 1);
 }
@@ -3992,7 +4000,7 @@
       ->ReplaceDefaultDiscoveryFactoryForTesting(std::move(discovery));
 
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
   EXPECT_EQ(AuthenticatorMakeCredential().status, AuthenticatorStatus::SUCCESS);
   EXPECT_EQ(taps, 2);
 }
@@ -4011,7 +4019,7 @@
   virtual_device_factory_->SetCtap2Config(config);
   virtual_device_factory_->mutable_state()->pin = kTestPIN;
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
 
   MakeCredentialResult result =
       AuthenticatorMakeCredential(make_credential_options(
@@ -4064,7 +4072,7 @@
   config.ctap2_versions = {device::Ctap2Version::kCtap2_1};
   virtual_device_factory_->SetCtap2Config(config);
   virtual_device_factory_->mutable_state()->min_pin_length = 6;
-  test_client_.expected = {{PINMode::kSet, "123456", 0, 6}};
+  test_client_.expected = {{PINReason::kSet, "123456", 0, 6}};
 
   MakeCredentialResult result =
       AuthenticatorMakeCredential(make_credential_options());
@@ -4084,7 +4092,7 @@
   virtual_device_factory_->mutable_state()->min_pin_length = 6;
   virtual_device_factory_->mutable_state()->pin = "123456";
   test_client_.expected = {
-      {PINMode::kChallenge, "123456", device::kMaxPinRetries, 6}};
+      {PINReason::kChallenge, "123456", device::kMaxPinRetries, 6}};
 
   MakeCredentialResult result =
       AuthenticatorMakeCredential(make_credential_options());
@@ -4107,9 +4115,9 @@
   virtual_device_factory_->mutable_state()->pin_retries =
       device::kMaxPinRetries;
   virtual_device_factory_->mutable_state()->min_pin_length = 6;
-  test_client_.expected = {{PINMode::kChallenge, kTestPIN,
+  test_client_.expected = {{PINReason::kChallenge, kTestPIN,
                             device::kMaxPinRetries, device::kMinPinLength},
-                           {PINMode::kChange, "567890", 0, 6}};
+                           {PINReason::kChange, "567890", 0, 6}};
 
   MakeCredentialResult result =
       AuthenticatorMakeCredential(make_credential_options());
@@ -4175,7 +4183,7 @@
 
               case kUsePIN:
                 // A single prompt to get the PIN is expected.
-                test_client_.expected = {{PINMode::kChallenge, kTestPIN, 8}};
+                test_client_.expected = {{PINReason::kChallenge, kTestPIN, 8}};
                 break;
 
               default:
@@ -4222,9 +4230,11 @@
   ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
       options->allow_credentials[0].id(), kTestRelyingPartyId));
 
-  test_client_.expected = {{PINMode::kChallenge, "wrong", 8},
-                           {PINMode::kChallenge, "wrong", 7},
-                           {PINMode::kChallenge, "wrong", 6}};
+  test_client_.expected = {{PINReason::kChallenge, "wrong", 8},
+                           {PINReason::kChallenge, "wrong", 7,
+                            device::kMinPinLength, PINError::kWrongPIN},
+                           {PINReason::kChallenge, "wrong", 6,
+                            device::kMinPinLength, PINError::kWrongPIN}};
   EXPECT_EQ(AuthenticatorGetAssertion(std::move(options)).status,
             AuthenticatorStatus::NOT_ALLOWED_ERROR);
   EXPECT_EQ(5, virtual_device_factory_->mutable_state()->pin_retries);
@@ -4242,7 +4252,7 @@
   ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
       options->allow_credentials[0].id(), kTestRelyingPartyId));
 
-  test_client_.expected = {{PINMode::kChallenge, "wrong", 1}};
+  test_client_.expected = {{PINReason::kChallenge, "wrong", 1}};
   EXPECT_EQ(AuthenticatorGetAssertion(std::move(options)).status,
             AuthenticatorStatus::NOT_ALLOWED_ERROR);
   EXPECT_EQ(0, virtual_device_factory_->mutable_state()->pin_retries);
@@ -4263,7 +4273,7 @@
   ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
       options->allow_credentials[0].id(), kTestRelyingPartyId));
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
   EXPECT_EQ(AuthenticatorGetAssertion(std::move(options)).status,
             AuthenticatorStatus::SUCCESS);
   EXPECT_EQ(taps, 1);
@@ -4298,7 +4308,7 @@
       ->ReplaceDefaultDiscoveryFactoryForTesting(std::move(discovery));
 
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
   EXPECT_EQ(AuthenticatorGetAssertion(std::move(options)).status,
             AuthenticatorStatus::SUCCESS);
   EXPECT_EQ(taps, 2);
@@ -4318,7 +4328,7 @@
   ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
       options->allow_credentials[0].id(), kTestRelyingPartyId));
   test_client_.expected = {
-      {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+      {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
 
   GetAssertionResult result = AuthenticatorGetAssertion(std::move(options));
   EXPECT_EQ(result.status, AuthenticatorStatus::SUCCESS);
@@ -4389,7 +4399,7 @@
           device::kMaxPinRetries;
       virtual_device_factory_->SetCtap2Config(config);
       test_client_.expected = {
-          {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+          {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
       // Since converting to U2F isn't possible, this will trigger a PIN prompt
       // and succeed because the device does actually support the algorithm.
       expected_to_succeed = true;
@@ -4449,7 +4459,7 @@
       // test infrastructure will CHECK if |expected| is set and not used.)
       options->prf_enable = true;
       test_client_.expected = {
-          {PINMode::kChallenge, kTestPIN, device::kMaxPinRetries}};
+          {PINReason::kChallenge, kTestPIN, device::kMaxPinRetries}};
     } else {
       // If PRF is requested, but the authenticator doesn't support it, then we
       // should still use U2F.
@@ -5002,9 +5012,10 @@
 
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override {
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(provide_pin_cb), kTestPIN));
+        FROM_HERE,
+        base::BindOnce(std::move(provide_pin_cb), base::UTF8ToUTF16(kTestPIN)));
   }
 
   void FinishCollectToken() override {}
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc
index 52cb61e9..eac94e56 100644
--- a/content/browser/worker_host/dedicated_worker_host.cc
+++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -379,8 +379,7 @@
   if (!ancestor_render_frame_host) {
     // The ancestor frame may have already been closed. In that case, the worker
     // will soon be terminated too, so abort the connection.
-    receiver.ResetWithReason(network::mojom::WebSocket::kInsufficientResources,
-                             "The parent frame has already been gone.");
+    receiver.ResetWithReason(0, "The parent frame has already been gone.");
     return;
   }
   mojo::MakeSelfOwnedReceiver(
diff --git a/content/public/browser/authenticator_request_client_delegate.cc b/content/public/browser/authenticator_request_client_delegate.cc
index 3193b5e..4c36021 100644
--- a/content/public/browser/authenticator_request_client_delegate.cc
+++ b/content/public/browser/authenticator_request_client_delegate.cc
@@ -134,7 +134,7 @@
 
 void AuthenticatorRequestClientDelegate::CollectPIN(
     CollectPINOptions options,
-    base::OnceCallback<void(std::string)> provide_pin_cb) {
+    base::OnceCallback<void(base::string16)> provide_pin_cb) {
   NOTREACHED();
 }
 
@@ -149,6 +149,4 @@
 void AuthenticatorRequestClientDelegate::OnRetryUserVerification(int attempts) {
 }
 
-void AuthenticatorRequestClientDelegate::OnInternalUserVerificationLocked() {}
-
 }  // namespace content
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h
index 30f9b29..67822aa 100644
--- a/content/public/browser/authenticator_request_client_delegate.h
+++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -240,12 +240,11 @@
   bool SupportsPIN() const override;
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override;
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override;
   void StartBioEnrollment(base::OnceClosure next_callback) override;
   void OnSampleCollected(int bio_samples_remaining) override;
   void FinishCollectToken() override;
   void OnRetryUserVerification(int attempts) override;
-  void OnInternalUserVerificationLocked() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestClientDelegate);
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index f5f2e6c..47572dce 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -794,17 +794,6 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-// Controls whether the visibility of a WebContents can be OCCLUDED. When
-// disabled, an occluded WebContents behaves exactly like a VISIBLE WebContents.
-const base::Feature kWebContentsOcclusion {
-  "WebContentsOcclusion",
-#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN)
-      base::FEATURE_ENABLED_BY_DEFAULT
-#else
-      base::FEATURE_DISABLED_BY_DEFAULT
-#endif
-};
-
 // Controls whether the WebAuthentication API is enabled:
 // https://w3c.github.io/webauthn
 const base::Feature kWebAuth{"WebAuthentication",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index b609fb0..629c425 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -189,7 +189,6 @@
 CONTENT_EXPORT extern const base::Feature kWebBluetoothNewPermissionsBackend;
 CONTENT_EXPORT extern const base::Feature kWebBundles;
 CONTENT_EXPORT extern const base::Feature kWebBundlesFromNetwork;
-CONTENT_EXPORT extern const base::Feature kWebContentsOcclusion;
 CONTENT_EXPORT extern const base::Feature kWebGLImageChromium;
 CONTENT_EXPORT extern const base::Feature kWebID;
 CONTENT_EXPORT extern const base::Feature kWebOtpBackendAuto;
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index fdac7af..eb959bf2 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -942,7 +942,8 @@
       mojo_rule->host_pattern = rule.host_pattern;
       mojo_rule->replacement = rule.replacement;
       mojo_rule->host_resolver_flags = rule.host_resolver_flags;
-      mojo_rule->canonical_name = rule.canonical_name;
+      mojo_rule->canonical_name =
+          !rule.dns_aliases.empty() ? rule.dns_aliases.front() : std::string();
       mojo_rules.push_back(std::move(mojo_rule));
     }
   }
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index 2812abf4..f68f6e2 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -205,6 +205,18 @@
              features::kProcessSharingWithDefaultSiteInstances);
 }
 
+bool AreStrictSiteInstancesEnabled() {
+  return AreAllSitesIsolatedForTesting() ||
+         base::FeatureList::IsEnabled(
+             features::kProcessSharingWithStrictSiteInstances);
+}
+
+bool IsIsolatedOriginRequiredToGuaranteeDedicatedProcess() {
+  return AreDefaultSiteInstancesEnabled() ||
+         base::FeatureList::IsEnabled(
+             features::kProcessSharingWithStrictSiteInstances);
+}
+
 void IsolateAllSitesForTesting(base::CommandLine* command_line) {
   command_line->AppendSwitch(switches::kSitePerProcess);
 }
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h
index b55ad04c..3cd02f9a 100644
--- a/content/public/test/test_utils.h
+++ b/content/public/test/test_utils.h
@@ -95,6 +95,18 @@
 // to mark expectations specific to default SiteInstances.
 bool AreDefaultSiteInstancesEnabled();
 
+// Returns true if the process model only allows a SiteInstance to contain
+// a single site.
+bool AreStrictSiteInstancesEnabled();
+
+// Returns true if a test needs to register an origin for isolation to ensure
+// that navigations, for that origin, are placed in a dedicated process. Some
+// process model modes allow sites to share a process if they are not isolated.
+// This helper indicates when such a mode is in use and indicates the test must
+// register an isolated origin to ensure the origin gets placed in its own
+// process.
+bool IsIsolatedOriginRequiredToGuaranteeDedicatedProcess();
+
 // Appends --site-per-process to the command line, enabling tests to exercise
 // site isolation and cross-process iframes. This must be called early in
 // the test; the flag will be read on the first real navigation.
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index efb500c..3572ec5 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -272,7 +272,18 @@
 }
 
 bool TestWebContents::CrossProcessNavigationPending() {
-  return GetRenderManager()->speculative_render_frame_host_ != nullptr;
+  // If we don't have a speculative RenderFrameHost then it means we did not
+  // change SiteInstances so we must be in the same process.
+  if (GetRenderManager()->speculative_render_frame_host_ == nullptr)
+    return false;
+
+  auto* current_instance =
+      GetRenderManager()->current_frame_host()->GetSiteInstance();
+  auto* speculative_instance =
+      GetRenderManager()->speculative_frame_host()->GetSiteInstance();
+  if (current_instance == speculative_instance)
+    return false;
+  return current_instance->GetProcess() != speculative_instance->GetProcess();
 }
 
 bool TestWebContents::CreateRenderViewForRenderManager(
diff --git a/device/fido/auth_token_requester.cc b/device/fido/auth_token_requester.cc
index 46463dd3..6b41b54f 100644
--- a/device/fido/auth_token_requester.cc
+++ b/device/fido/auth_token_requester.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "components/device_event_log/device_event_log.h"
 #include "device/fido/authenticator_supported_options.h"
 #include "device/fido/fido_authenticator.h"
@@ -37,7 +38,8 @@
                                        Options options)
     : delegate_(delegate),
       authenticator_(authenticator),
-      options_(std::move(options)) {
+      options_(std::move(options)),
+      internal_uv_locked_(options_.internal_uv_locked) {
   DCHECK(delegate_);
   DCHECK(authenticator_);
   DCHECK(authenticator_->Options());
@@ -190,7 +192,7 @@
     // Fall back to PIN if able.
     if (authenticator_->Options()->client_pin_availability ==
         ClientPinAvailability::kSupportedAndPinSet) {
-      delegate_->InternalUVLockedForAuthToken();
+      internal_uv_locked_ = true;
       ObtainTokenFromPIN();
       return;
     }
@@ -230,30 +232,49 @@
         base::nullopt);
     return;
   }
-  if (internal_uv_locked_) {
-    delegate_->InternalUVLockedForAuthToken();
+  pin_retries_ = response->retries;
+  pin::PINEntryError error;
+  if (pin_invalid_) {
+    pin_invalid_ = false;
+    error = pin::PINEntryError::kWrongPIN;
+  } else if (internal_uv_locked_) {
+    error = pin::PINEntryError::kInternalUvLocked;
+  } else {
+    error = pin::PINEntryError::kNoError;
   }
-  delegate_->CollectExistingPIN(
-      response->retries, authenticator_->CurrentMinPINLength(),
+  delegate_->CollectPIN(
+      pin::PINEntryReason::kChallenge, error,
+      authenticator_->CurrentMinPINLength(), pin_retries_,
       base::BindOnce(&AuthTokenRequester::HavePIN, weak_factory_.GetWeakPtr()));
 }
 
-void AuthTokenRequester::HavePIN(std::string pin) {
-  DCHECK(pin::IsValid(pin));
-  current_pin_ = pin;
-  authenticator_->GetPINToken(std::move(pin),
+void AuthTokenRequester::HavePIN(base::string16 pin16) {
+  pin::PINEntryError error = pin::ValidatePIN(
+      pin16, authenticator_->CurrentMinPINLength(), current_pin_);
+  if (error != pin::PINEntryError::kNoError) {
+    delegate_->CollectPIN(pin::PINEntryReason::kChallenge, error,
+                          authenticator_->CurrentMinPINLength(), pin_retries_,
+                          base::BindOnce(&AuthTokenRequester::HavePIN,
+                                         weak_factory_.GetWeakPtr()));
+    return;
+  }
+
+  std::string pin = base::UTF16ToUTF8(pin16);
+  authenticator_->GetPINToken(pin,
                               {std::begin(options_.token_permissions),
                                std::end(options_.token_permissions)},
                               options_.rp_id,
                               base::BindOnce(&AuthTokenRequester::OnGetPINToken,
-                                             weak_factory_.GetWeakPtr()));
+                                             weak_factory_.GetWeakPtr(), pin));
   return;
 }
 
 void AuthTokenRequester::OnGetPINToken(
+    std::string pin,
     CtapDeviceResponseCode status,
     base::Optional<pin::TokenResponse> response) {
   if (status == CtapDeviceResponseCode::kCtap2ErrPinInvalid) {
+    pin_invalid_ = true;
     ObtainTokenFromPIN();
     return;
   }
@@ -263,10 +284,13 @@
     switch (status) {
       case CtapDeviceResponseCode::kCtap2ErrPinPolicyViolation:
         // The user needs to set a new PIN before they can use the device.
-        delegate_->CollectNewPIN(authenticator_->NewMinPINLength(),
-                                 /*force_pin_change=*/true,
-                                 base::BindOnce(&AuthTokenRequester::HaveNewPIN,
-                                                weak_factory_.GetWeakPtr()));
+        current_pin_ = pin;
+        delegate_->CollectPIN(pin::PINEntryReason::kChange,
+                              pin::PINEntryError::kNoError,
+                              authenticator_->NewMinPINLength(),
+                              /*attempts=*/0,
+                              base::BindOnce(&AuthTokenRequester::HaveNewPIN,
+                                             weak_factory_.GetWeakPtr()));
         return;
       case CtapDeviceResponseCode::kCtap2ErrPinAuthBlocked:
         ret = Result::kPostTouchAuthenticatorPINSoftLock;
@@ -289,14 +313,27 @@
 
 void AuthTokenRequester::ObtainTokenFromNewPIN() {
   NotifyAuthenticatorSelected();
-  delegate_->CollectNewPIN(authenticator_->NewMinPINLength(),
-                           /*force_pin_change=*/false,
-                           base::BindOnce(&AuthTokenRequester::HaveNewPIN,
-                                          weak_factory_.GetWeakPtr()));
+  delegate_->CollectPIN(pin::PINEntryReason::kSet, pin::PINEntryError::kNoError,
+                        authenticator_->NewMinPINLength(),
+                        /*attempts=*/0,
+                        base::BindOnce(&AuthTokenRequester::HaveNewPIN,
+                                       weak_factory_.GetWeakPtr()));
 }
 
-void AuthTokenRequester::HaveNewPIN(const std::string pin) {
-  DCHECK(pin::IsValid(pin));
+void AuthTokenRequester::HaveNewPIN(base::string16 pin16) {
+  pin::PINEntryError error =
+      pin::ValidatePIN(pin16, authenticator_->NewMinPINLength(), current_pin_);
+  if (error != pin::PINEntryError::kNoError) {
+    delegate_->CollectPIN(
+        current_pin_ ? pin::PINEntryReason::kChange : pin::PINEntryReason::kSet,
+        error, authenticator_->NewMinPINLength(),
+        /*attempts=*/0,
+        base::BindOnce(&AuthTokenRequester::HaveNewPIN,
+                       weak_factory_.GetWeakPtr()));
+    return;
+  }
+
+  std::string pin = base::UTF16ToUTF8(pin16);
   if (current_pin_) {
     authenticator_->ChangePIN(*current_pin_, pin,
                               base::BindOnce(&AuthTokenRequester::OnSetPIN,
@@ -325,7 +362,7 @@
                                std::end(options_.token_permissions)},
                               options_.rp_id,
                               base::BindOnce(&AuthTokenRequester::OnGetPINToken,
-                                             weak_factory_.GetWeakPtr()));
+                                             weak_factory_.GetWeakPtr(), pin));
 }
 
 void AuthTokenRequester::NotifyAuthenticatorSelected() {
diff --git a/device/fido/auth_token_requester.h b/device/fido/auth_token_requester.h
index fcc18b6..a5882e2 100644
--- a/device/fido/auth_token_requester.h
+++ b/device/fido/auth_token_requester.h
@@ -54,14 +54,17 @@
     // skip_pin_touch indicates whether not to request a touch before attempting
     // to obtain a token using a PIN.
     bool skip_pin_touch = false;
+
+    // internal_uv_locked indicates that internal user verification was already
+    // locked for the authenticator when building this AuthTokenRequester.
+    bool internal_uv_locked = false;
   };
 
   class COMPONENT_EXPORT(DEVICE_FIDO) Delegate {
    public:
     // ProvidePINCallback is used to provide the AuthTokenRequester with a PIN
-    // entered by the user. Callers must use |pin::IsValid()| to validate |pin|
-    // before invoking this callback.
-    using ProvidePINCallback = base::OnceCallback<void(std::string pin)>;
+    // entered by the user.
+    using ProvidePINCallback = base::OnceCallback<void(base::string16 pin)>;
 
     virtual ~Delegate();
 
@@ -77,36 +80,20 @@
     virtual void AuthenticatorSelectedForPINUVAuthToken(
         FidoAuthenticator* authenticator) = 0;
 
-    // CollectNewPIN is invoked to prompt the user to enter a new PIN for an
+    // CollectNewPIN is invoked to prompt the user to enter a PIN for an
     // authenticator. |min_pin_length| is the minimum length for a valid PIN.
-    // |force_pin_change| is true iff the user must change the PIN on their
-    // security key before using it.
+    // |attempts| is the number of attempts before the authenticator is locked.
+    // This number may be zero if the number is unlimited, e.g. when setting a
+    // new PIN.
     //
     // The callee must provide the PIN by invoking |provide_pin_cb|. The
     // callback is weakly bound and safe to invoke even after the
     // AuthTokenRequester was freed.
-    virtual void CollectNewPIN(uint32_t min_pin_length,
-                               bool force_pin_change,
-                               ProvidePINCallback provide_pin_cb) = 0;
-
-    // CollectExistingPIN is invoked to prompt the user to provide the existing
-    // PIN to an authenticator. |attempts| is the number of remaining attempts
-    // before the authenticator is locked. |min_pin_length| is the minimum
-    // length for a valid PIN.
-    //
-    // The callee must provide the PIN by invoking |provide_pin_cb|. The
-    // callback is weakly bound and safe to invoke even after the
-    // AuthTokenRequester was freed. If CollectExistingPIN() is called again
-    // after callback invocation, the provided PIN was incorrect.
-    virtual void CollectExistingPIN(int attempts,
-                                    uint32_t min_pin_length,
-                                    ProvidePINCallback provide_pin_cb) = 0;
-
-    // InternalUVLockedForAuthToken() notifies the delegate that the
-    // authenticator's internal modality was locked due to too many invalid
-    // authentication attempts. It is followed by a call to CollectExistingPIN()
-    // to prompt for a PIN as a fallback authentication mechanism.
-    virtual void InternalUVLockedForAuthToken() = 0;
+    virtual void CollectPIN(pin::PINEntryReason reason,
+                            pin::PINEntryError error,
+                            uint32_t min_pin_length,
+                            int attempts,
+                            ProvidePINCallback provide_pin_cb) = 0;
 
     // PromptForInternalUVRetry is invoked to prompt the user to retry internal
     // user verification (usually on a fingerprint sensor). |attempts| is the
@@ -151,12 +138,13 @@
   void ObtainTokenFromPIN();
   void OnGetPINRetries(CtapDeviceResponseCode status,
                        base::Optional<pin::RetriesResponse> response);
-  void HavePIN(std::string pin);
-  void OnGetPINToken(CtapDeviceResponseCode status,
+  void HavePIN(base::string16 pin);
+  void OnGetPINToken(std::string pin,
+                     CtapDeviceResponseCode status,
                      base::Optional<pin::TokenResponse> response);
 
   void ObtainTokenFromNewPIN();
-  void HaveNewPIN(std::string pin);
+  void HaveNewPIN(base::string16 pin);
   void OnSetPIN(std::string pin,
                 CtapDeviceResponseCode status,
                 base::Optional<pin::EmptyResponse> response);
@@ -173,6 +161,8 @@
   bool is_internal_uv_retry_ = false;
   base::Optional<std::string> current_pin_;
   bool internal_uv_locked_ = false;
+  bool pin_invalid_ = false;
+  int pin_retries_ = 0;
 
   base::WeakPtrFactory<AuthTokenRequester> weak_factory_{this};
 };
diff --git a/device/fido/auth_token_requester_unittest.cc b/device/fido/auth_token_requester_unittest.cc
index 299b85f..d80e47a 100644
--- a/device/fido/auth_token_requester_unittest.cc
+++ b/device/fido/auth_token_requester_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "device/fido/auth_token_requester.h"
 
+#include <list>
 #include <string>
 
-#include "base/stl_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -15,6 +15,9 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/optional.h"
 #include "base/run_loop.h"
+#include "base/stl_util.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/test/task_environment.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_device_authenticator.h"
@@ -32,22 +35,35 @@
     device::AuthenticatorSupportedOptions::UserVerificationAvailability;
 
 constexpr char kTestPIN[] = "1234";
+constexpr char kNewPIN[] = "5678";
+
+struct TestExpectation {
+  pin::PINEntryReason reason;
+  pin::PINEntryError error = pin::PINEntryError::kNoError;
+  uint32_t min_pin_length = kMinPinLength;
+  int attempts = 8;
+  base::string16 pin = base::UTF8ToUTF16(kTestPIN);
+};
+
+struct TestCase {
+  ClientPinAvailability client_pin;
+  UserVerificationAvailability user_verification;
+  bool success;
+  std::list<TestExpectation> expectations;
+};
 
 class TestAuthTokenRequesterDelegate : public AuthTokenRequester::Delegate {
  public:
-  explicit TestAuthTokenRequesterDelegate(std::string pin)
-      : pin_(std::move(pin)) {}
+  explicit TestAuthTokenRequesterDelegate(
+      std::list<TestExpectation> expectations)
+      : expectations_(std::move(expectations)) {}
 
   void WaitForResult() { wait_for_result_loop_.Run(); }
   base::Optional<AuthTokenRequester::Result>& result() { return result_; }
   base::Optional<pin::TokenResponse>& response() { return response_; }
-  bool pin_was_set() { return pin_was_set_; }
-  uint32_t min_pin_length() { return min_pin_length_; }
-  bool pin_was_collected() { return pin_was_collected_; }
   bool internal_uv_was_retried() { return internal_uv_num_retries_ > 0u; }
   size_t internal_uv_num_retries() { return internal_uv_num_retries_; }
-  bool forced_pin_change() { return forced_pin_change_; }
-  bool internal_uv_was_locked() { return internal_uv_was_locked_; }
+  std::list<TestExpectation> expectations() { return expectations_; }
 
  private:
   // AuthTokenRequester::Delegate:
@@ -55,33 +71,27 @@
       FidoAuthenticator* authenticator) override {
     authenticator_selected_ = true;
   }
-  void CollectNewPIN(uint32_t min_pin_length,
-                     bool force_pin_change,
-                     ProvidePINCallback provide_pin_cb) override {
+  void CollectPIN(pin::PINEntryReason reason,
+                  pin::PINEntryError error,
+                  uint32_t min_pin_length,
+                  int attempts,
+                  ProvidePINCallback provide_pin_cb) override {
     DCHECK(authenticator_selected_);
-    DCHECK(!pin_.empty());
-    pin_was_set_ = true;
-    min_pin_length_ = min_pin_length;
-    forced_pin_change_ = force_pin_change;
-    std::move(provide_pin_cb).Run(pin_);
-  }
-  void CollectExistingPIN(int attempts,
-                          uint32_t min_pin_length,
-                          ProvidePINCallback provide_pin_cb) override {
-    DCHECK(authenticator_selected_);
-    DCHECK(!pin_.empty());
-    pin_was_collected_ = true;
-    min_pin_length_ = min_pin_length;
-    std::move(provide_pin_cb).Run(pin_);
+
+    DCHECK_NE(expectations_.size(), 0u);
+    DCHECK_EQ(reason, expectations_.front().reason);
+    DCHECK_EQ(error, expectations_.front().error);
+    DCHECK_EQ(min_pin_length, expectations_.front().min_pin_length);
+    DCHECK_EQ(attempts, expectations_.front().attempts);
+
+    base::string16 pin = expectations_.front().pin;
+    expectations_.pop_front();
+    std::move(provide_pin_cb).Run(pin);
   }
   void PromptForInternalUVRetry(int attempts) override {
     DCHECK(authenticator_selected_);
     internal_uv_num_retries_++;
   }
-  void InternalUVLockedForAuthToken() override {
-    DCHECK(authenticator_selected_);
-    internal_uv_was_locked_ = true;
-  }
   void HavePINUVAuthTokenResultForAuthenticator(
       FidoAuthenticator* authenticator,
       AuthTokenRequester::Result result,
@@ -100,28 +110,17 @@
     wait_for_result_loop_.Quit();
   }
 
-  std::string pin_;
+  std::list<TestExpectation> expectations_;
 
   base::Optional<AuthTokenRequester::Result> result_;
   base::Optional<pin::TokenResponse> response_;
 
   bool authenticator_selected_ = false;
-  bool pin_was_collected_ = false;
-  bool pin_was_set_ = false;
-  bool forced_pin_change_ = false;
   size_t internal_uv_num_retries_ = 0u;
-  uint32_t min_pin_length_ = 0;
-  bool internal_uv_was_locked_ = false;
 
   base::RunLoop wait_for_result_loop_;
 };
 
-struct TestCase {
-  ClientPinAvailability client_pin;
-  UserVerificationAvailability user_verification;
-  bool success;
-};
-
 class AuthTokenRequesterTest : public ::testing::Test {
  protected:
   void SetUp() override {}
@@ -163,7 +162,8 @@
     authenticator->InitializeAuthenticator(init_loop.QuitClosure());
     init_loop.Run();
 
-    delegate_ = std::make_unique<TestAuthTokenRequesterDelegate>(kTestPIN);
+    delegate_ = std::make_unique<TestAuthTokenRequesterDelegate>(
+        std::move(test_case.expectations));
     AuthTokenRequester::Options options;
     options.token_permissions = {pin::Permissions::kMakeCredential};
     options.rp_id = "foobar.com";
@@ -173,6 +173,8 @@
     delegate_->WaitForResult();
   }
 
+  void TearDown() override { EXPECT_EQ(delegate_->expectations().size(), 0u); }
+
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
@@ -181,7 +183,7 @@
 };
 
 TEST_F(AuthTokenRequesterTest, AuthenticatorWithoutUVTokenSupport) {
-  constexpr TestCase kTestCases[]{
+  const TestCase kTestCases[]{
       {
           ClientPinAvailability::kNotSupported,
           UserVerificationAvailability::kNotSupported,
@@ -201,31 +203,37 @@
           ClientPinAvailability::kSupportedButPinNotSet,
           UserVerificationAvailability::kNotSupported,
           true,
+          {{.reason = pin::PINEntryReason::kSet, .attempts = 0}},
       },
       {
           ClientPinAvailability::kSupportedButPinNotSet,
           UserVerificationAvailability::kSupportedButNotConfigured,
           true,
+          {{.reason = pin::PINEntryReason::kSet, .attempts = 0}},
       },
       {
           ClientPinAvailability::kSupportedButPinNotSet,
           UserVerificationAvailability::kSupportedAndConfigured,
           true,
+          {{.reason = pin::PINEntryReason::kSet, .attempts = 0}},
       },
       {
           ClientPinAvailability::kSupportedAndPinSet,
           UserVerificationAvailability::kNotSupported,
           true,
+          {{pin::PINEntryReason::kChallenge}},
       },
       {
           ClientPinAvailability::kSupportedAndPinSet,
           UserVerificationAvailability::kSupportedButNotConfigured,
           true,
+          {{pin::PINEntryReason::kChallenge}},
       },
       {
           ClientPinAvailability::kSupportedAndPinSet,
           UserVerificationAvailability::kSupportedAndConfigured,
           true,
+          {{pin::PINEntryReason::kChallenge}},
       },
   };
 
@@ -241,26 +249,17 @@
       EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess);
       EXPECT_THAT(delegate_->response()->token_for_testing(),
                   ElementsAreArray(state_->pin_token));
-      EXPECT_EQ(delegate_->pin_was_set(),
-                t.client_pin == ClientPinAvailability::kSupportedButPinNotSet);
-      EXPECT_EQ(delegate_->min_pin_length(), kMinPinLength);
-      EXPECT_EQ(delegate_->pin_was_collected(),
-                t.client_pin == ClientPinAvailability::kSupportedAndPinSet);
     } else {
       EXPECT_EQ(*delegate_->result(),
                 AuthTokenRequester::Result::kPreTouchUnsatisfiableRequest);
       EXPECT_FALSE(delegate_->response());
-      EXPECT_FALSE(delegate_->pin_was_set());
-      EXPECT_FALSE(delegate_->pin_was_collected());
     }
     EXPECT_FALSE(delegate_->internal_uv_was_retried());
-    EXPECT_FALSE(delegate_->internal_uv_was_locked());
-    EXPECT_FALSE(delegate_->forced_pin_change());
   }
 }
 
 TEST_F(AuthTokenRequesterTest, AuthenticatorWithUVTokenSupport) {
-  constexpr TestCase kTestCases[]{
+  const TestCase kTestCases[]{
       {
           ClientPinAvailability::kNotSupported,
           UserVerificationAvailability::kNotSupported,
@@ -280,11 +279,13 @@
           ClientPinAvailability::kSupportedButPinNotSet,
           UserVerificationAvailability::kNotSupported,
           true,
+          {{.reason = pin::PINEntryReason::kSet, .attempts = 0}},
       },
       {
           ClientPinAvailability::kSupportedButPinNotSet,
           UserVerificationAvailability::kSupportedButNotConfigured,
           true,
+          {{.reason = pin::PINEntryReason::kSet, .attempts = 0}},
       },
       {
           ClientPinAvailability::kSupportedButPinNotSet,
@@ -295,11 +296,13 @@
           ClientPinAvailability::kSupportedAndPinSet,
           UserVerificationAvailability::kNotSupported,
           true,
+          {{pin::PINEntryReason::kChallenge}},
       },
       {
           ClientPinAvailability::kSupportedAndPinSet,
           UserVerificationAvailability::kSupportedButNotConfigured,
           true,
+          {{pin::PINEntryReason::kChallenge}},
       },
       {
           ClientPinAvailability::kSupportedAndPinSet,
@@ -326,31 +329,12 @@
                 static_cast<uint8_t>(pin::Permissions::kMakeCredential));
       EXPECT_THAT(delegate_->response()->token_for_testing(),
                   ElementsAreArray(state_->pin_token));
-      EXPECT_EQ(delegate_->pin_was_set(),
-                t.client_pin == ClientPinAvailability::kSupportedButPinNotSet &&
-                    t.user_verification !=
-                        UserVerificationAvailability::kSupportedAndConfigured);
-      EXPECT_EQ(delegate_->min_pin_length(),
-                t.user_verification !=
-                        UserVerificationAvailability::kSupportedAndConfigured
-                    ? kMinPinLength
-                    : 0);
-      EXPECT_EQ(delegate_->pin_was_collected(),
-                t.client_pin == ClientPinAvailability::kSupportedAndPinSet &&
-                    t.user_verification !=
-                        UserVerificationAvailability::kSupportedAndConfigured);
       EXPECT_FALSE(delegate_->internal_uv_was_retried());
-      EXPECT_FALSE(delegate_->internal_uv_was_locked());
-      EXPECT_FALSE(delegate_->forced_pin_change());
     } else {
       EXPECT_EQ(*delegate_->result(),
                 AuthTokenRequester::Result::kPreTouchUnsatisfiableRequest);
       EXPECT_FALSE(delegate_->response());
-      EXPECT_FALSE(delegate_->pin_was_set());
-      EXPECT_FALSE(delegate_->pin_was_collected());
       EXPECT_FALSE(delegate_->internal_uv_was_retried());
-      EXPECT_FALSE(delegate_->internal_uv_was_locked());
-      EXPECT_FALSE(delegate_->forced_pin_change());
     }
   }
 }
@@ -364,20 +348,15 @@
   state->soft_locked = true;
 
   RunTestCase(std::move(config), state,
-              TestCase{
-                  ClientPinAvailability::kSupportedAndPinSet,
-                  UserVerificationAvailability::kNotSupported,
-                  false,
-              });
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kNotSupported,
+                       false,
+                       {{pin::PINEntryReason::kChallenge}}});
 
   EXPECT_EQ(*delegate_->result(),
             AuthTokenRequester::Result::kPostTouchAuthenticatorPINSoftLock);
   EXPECT_FALSE(delegate_->response());
-  EXPECT_FALSE(delegate_->pin_was_set());
-  EXPECT_TRUE(delegate_->pin_was_collected());
   EXPECT_FALSE(delegate_->internal_uv_was_retried());
-  EXPECT_FALSE(delegate_->internal_uv_was_locked());
-  EXPECT_FALSE(delegate_->forced_pin_change());
 }
 
 TEST_F(AuthTokenRequesterTest, PINHardLock) {
@@ -398,11 +377,40 @@
   EXPECT_EQ(*delegate_->result(),
             AuthTokenRequester::Result::kPostTouchAuthenticatorPINHardLock);
   EXPECT_FALSE(delegate_->response());
-  EXPECT_FALSE(delegate_->pin_was_set());
-  EXPECT_FALSE(delegate_->pin_was_collected());
   EXPECT_FALSE(delegate_->internal_uv_was_retried());
-  EXPECT_FALSE(delegate_->internal_uv_was_locked());
-  EXPECT_FALSE(delegate_->forced_pin_change());
+}
+
+TEST_F(AuthTokenRequesterTest, PINInvalid) {
+  VirtualCtap2Device::Config config;
+  config.pin_uv_auth_token_support = true;
+  config.ctap2_versions = {std::begin(kCtap2Versions2_1),
+                           std::end(kCtap2Versions2_1)};
+  auto state = base::MakeRefCounted<VirtualFidoDevice::State>();
+  RunTestCase(
+      std::move(config), state,
+      TestCase{ClientPinAvailability::kSupportedAndPinSet,
+               UserVerificationAvailability::kNotSupported,
+               true,
+               {{.reason = pin::PINEntryReason::kChallenge,
+                 .pin = base::string16({0xd800, 0xd800, 0xd800, 0xd800})},
+                {pin::PINEntryReason::kChallenge,
+                 pin::PINEntryError::kInvalidCharacters}}});
+}
+
+TEST_F(AuthTokenRequesterTest, PINTooShort) {
+  VirtualCtap2Device::Config config;
+  config.pin_uv_auth_token_support = true;
+  config.ctap2_versions = {std::begin(kCtap2Versions2_1),
+                           std::end(kCtap2Versions2_1)};
+  auto state = base::MakeRefCounted<VirtualFidoDevice::State>();
+  RunTestCase(std::move(config), state,
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kNotSupported,
+                       true,
+                       {{.reason = pin::PINEntryReason::kChallenge,
+                         .pin = base::UTF8ToUTF16("まどか")},
+                        {pin::PINEntryReason::kChallenge,
+                         pin::PINEntryError::kTooShort}}});
 }
 
 TEST_F(AuthTokenRequesterTest, UVLockedPINFallback) {
@@ -415,19 +423,15 @@
   state->uv_retries = 3;
 
   RunTestCase(std::move(config), state,
-              TestCase{
-                  ClientPinAvailability::kSupportedAndPinSet,
-                  UserVerificationAvailability::kSupportedAndConfigured,
-                  true,
-              });
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kSupportedAndConfigured,
+                       true,
+                       {{pin::PINEntryReason::kChallenge,
+                         pin::PINEntryError::kInternalUvLocked}}});
 
   EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess);
   EXPECT_TRUE(delegate_->response());
-  EXPECT_FALSE(delegate_->pin_was_set());
-  EXPECT_TRUE(delegate_->pin_was_collected());
   EXPECT_EQ(delegate_->internal_uv_num_retries(), 2u);
-  EXPECT_TRUE(delegate_->internal_uv_was_locked());
-  EXPECT_FALSE(delegate_->forced_pin_change());
 }
 
 TEST_F(AuthTokenRequesterTest, UVAlreadyLockedPINFallback) {
@@ -440,19 +444,15 @@
   state->uv_retries = 0;
 
   RunTestCase(std::move(config), state,
-              TestCase{
-                  ClientPinAvailability::kSupportedAndPinSet,
-                  UserVerificationAvailability::kSupportedAndConfigured,
-                  true,
-              });
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kSupportedAndConfigured,
+                       true,
+                       {{pin::PINEntryReason::kChallenge,
+                         pin::PINEntryError::kInternalUvLocked}}});
 
   EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess);
   EXPECT_TRUE(delegate_->response());
-  EXPECT_FALSE(delegate_->pin_was_set());
-  EXPECT_TRUE(delegate_->pin_was_collected());
   EXPECT_EQ(delegate_->internal_uv_num_retries(), 0u);
-  EXPECT_TRUE(delegate_->internal_uv_was_locked());
-  EXPECT_FALSE(delegate_->forced_pin_change());
 }
 
 TEST_F(AuthTokenRequesterTest, ForcePINChange) {
@@ -465,18 +465,47 @@
   state->force_pin_change = true;
 
   RunTestCase(std::move(config), state,
-              TestCase{
-                  ClientPinAvailability::kSupportedAndPinSet,
-                  UserVerificationAvailability::kNotSupported,
-                  true,
-              });
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kNotSupported,
+                       true,
+                       {{pin::PINEntryReason::kChallenge},
+                        {
+                            .reason = pin::PINEntryReason::kChange,
+                            .attempts = 0,
+                            .pin = base::UTF8ToUTF16(kNewPIN),
+                        }}});
 
   EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess);
   EXPECT_TRUE(delegate_->response());
-  EXPECT_TRUE(delegate_->pin_was_set());
-  EXPECT_TRUE(delegate_->pin_was_collected());
-  EXPECT_FALSE(delegate_->internal_uv_was_locked());
-  EXPECT_TRUE(delegate_->forced_pin_change());
+}
+
+TEST_F(AuthTokenRequesterTest, ForcePINChangeSameAsCurrent) {
+  VirtualCtap2Device::Config config;
+  config.pin_uv_auth_token_support = true;
+  config.ctap2_versions = {std::begin(kCtap2Versions2_1),
+                           std::end(kCtap2Versions2_1)};
+  config.min_pin_length_support = true;
+  auto state = base::MakeRefCounted<VirtualFidoDevice::State>();
+  state->force_pin_change = true;
+
+  RunTestCase(std::move(config), state,
+              TestCase{ClientPinAvailability::kSupportedAndPinSet,
+                       UserVerificationAvailability::kNotSupported,
+                       true,
+                       {{pin::PINEntryReason::kChallenge},
+                        {
+                            .reason = pin::PINEntryReason::kChange,
+                            .attempts = 0,
+                        },
+                        {
+                            .reason = pin::PINEntryReason::kChange,
+                            .error = pin::PINEntryError::kSameAsCurrentPIN,
+                            .attempts = 0,
+                            .pin = base::UTF8ToUTF16(kNewPIN),
+                        }}});
+
+  EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess);
+  EXPECT_TRUE(delegate_->response());
 }
 
 }  // namespace
diff --git a/device/fido/ble_adapter_manager_unittest.cc b/device/fido/ble_adapter_manager_unittest.cc
index 87b3b2f..76631926 100644
--- a/device/fido/ble_adapter_manager_unittest.cc
+++ b/device/fido/ble_adapter_manager_unittest.cc
@@ -48,7 +48,8 @@
   MOCK_METHOD1(FidoAuthenticatorRemoved, void(base::StringPiece device_id));
   MOCK_CONST_METHOD0(SupportsPIN, bool());
   MOCK_METHOD2(CollectPIN,
-               void(CollectPINOptions, base::OnceCallback<void(std::string)>));
+               void(CollectPINOptions,
+                    base::OnceCallback<void(base::string16)>));
   MOCK_METHOD0(OnForcePINChange, void());
   MOCK_METHOD1(StartBioEnrollment, void(base::OnceClosure));
   MOCK_METHOD1(OnSampleCollected, void(int));
diff --git a/device/fido/fido_request_handler_base.h b/device/fido/fido_request_handler_base.h
index 62b84a5e..b14edf8 100644
--- a/device/fido/fido_request_handler_base.h
+++ b/device/fido/fido_request_handler_base.h
@@ -25,6 +25,7 @@
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_discovery_base.h"
 #include "device/fido/fido_transport_protocol.h"
+#include "device/fido/pin.h"
 
 namespace device {
 
@@ -97,19 +98,11 @@
   class COMPONENT_EXPORT(DEVICE_FIDO) Observer {
    public:
     struct COMPONENT_EXPORT(DEVICE_FIDO) CollectPINOptions {
-      enum class Mode {
-        // Indicates a new PIN is being set. |attempts| should be ignored.
-        kSet,
-
-        // The existing PIN must be changed before using this authenticator.
-        kChange,
-
-        // The existing PIN is being collected to prove user verification.
-        kChallenge
-      };
-
       // Why this PIN is being collected.
-      Mode mode;
+      pin::PINEntryReason reason;
+
+      // The error for which we are prompting for a PIN.
+      pin::PINEntryError error = pin::PINEntryError::kNoError;
 
       // The minimum PIN length the authenticator will accept for the PIN.
       uint32_t min_pin_length = device::kMinPinLength;
@@ -153,7 +146,7 @@
     // hard lock.
     virtual void CollectPIN(
         CollectPINOptions options,
-        base::OnceCallback<void(std::string)> provide_pin_cb) = 0;
+        base::OnceCallback<void(base::string16)> provide_pin_cb) = 0;
 
     virtual void FinishCollectToken() = 0;
 
@@ -174,11 +167,6 @@
     // internal user verification.
     virtual void OnRetryUserVerification(int attempts) = 0;
 
-    // Called when an authenticator reports internal user verification has been
-    // locked (e.g. by repeated failed attempts to recognise the user's
-    // fingerprints).
-    virtual void OnInternalUserVerificationLocked() = 0;
-
     // SetMightCreateResidentCredential indicates whether the activation of an
     // authenticator may cause a resident credential to be created. A resident
     // credential may be discovered by someone with physical access to the
diff --git a/device/fido/fido_request_handler_unittest.cc b/device/fido/fido_request_handler_unittest.cc
index 2c783f59..e54967f 100644
--- a/device/fido/fido_request_handler_unittest.cc
+++ b/device/fido/fido_request_handler_unittest.cc
@@ -114,7 +114,7 @@
 
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override {
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override {
     NOTREACHED();
   }
 
@@ -122,8 +122,6 @@
 
   void OnRetryUserVerification(int attempts) override {}
 
-  void OnInternalUserVerificationLocked() override {}
-
   void StartBioEnrollment(base::OnceClosure next_callback) override {}
 
   void OnSampleCollected(int remaining_samples) override {}
diff --git a/device/fido/get_assertion_handler_unittest.cc b/device/fido/get_assertion_handler_unittest.cc
index 3b4c8a21..1274866 100644
--- a/device/fido/get_assertion_handler_unittest.cc
+++ b/device/fido/get_assertion_handler_unittest.cc
@@ -790,14 +790,13 @@
   bool SupportsPIN() const override { return false; }
   void CollectPIN(
       CollectPINOptions options,
-      base::OnceCallback<void(std::string)> provide_pin_cb) override {
+      base::OnceCallback<void(base::string16)> provide_pin_cb) override {
     NOTREACHED();
   }
   void StartBioEnrollment(base::OnceClosure next_callback) override {}
   void OnSampleCollected(int bio_samples_remaining) override {}
   void FinishCollectToken() override { NOTREACHED(); }
   void OnRetryUserVerification(int attempts) override {}
-  void OnInternalUserVerificationLocked() override {}
   void SetMightCreateResidentCredential(bool v) override {}
 
   bool controls_dispatch_ = false;
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc
index 9bcf6c7..975d3e88 100644
--- a/device/fido/get_assertion_request_handler.cc
+++ b/device/fido/get_assertion_request_handler.cc
@@ -352,7 +352,8 @@
     case PINUVDisposition::kGetToken:
       ObtainPINUVAuthToken(
           authenticator, GetPinTokenPermissionsFor(*authenticator, request),
-          active_authenticators().size() == 1 && allow_skipping_pin_touch_);
+          active_authenticators().size() == 1 && allow_skipping_pin_touch_,
+          /*internal_uv_locked=*/false);
       return;
     case PINUVDisposition::kUnsatisfiable:
       FIDO_LOG(DEBUG) << authenticator->GetDisplayName()
@@ -437,24 +438,14 @@
   CancelActiveAuthenticators(authenticator->GetId());
 }
 
-void GetAssertionRequestHandler::CollectNewPIN(
-    uint32_t min_pin_length,
-    bool force_pin_change,
-    ProvidePINCallback provide_pin_cb) {
+void GetAssertionRequestHandler::CollectPIN(pin::PINEntryReason reason,
+                                            pin::PINEntryError error,
+                                            uint32_t min_pin_length,
+                                            int attempts,
+                                            ProvidePINCallback provide_pin_cb) {
   DCHECK_EQ(state_, State::kWaitingForToken);
-  observer()->CollectPIN(
-      {.mode = force_pin_change ? Observer::CollectPINOptions::Mode::kChange
-                                : Observer::CollectPINOptions::Mode::kSet,
-       .min_pin_length = min_pin_length},
-      std::move(provide_pin_cb));
-}
-
-void GetAssertionRequestHandler::CollectExistingPIN(
-    int attempts,
-    uint32_t min_pin_length,
-    ProvidePINCallback provide_pin_cb) {
-  DCHECK_EQ(state_, State::kWaitingForToken);
-  observer()->CollectPIN({.mode = Observer::CollectPINOptions::Mode::kChallenge,
+  observer()->CollectPIN({.reason = reason,
+                          .error = error,
                           .min_pin_length = min_pin_length,
                           .attempts = attempts},
                          std::move(provide_pin_cb));
@@ -466,12 +457,6 @@
   observer()->OnRetryUserVerification(attempts);
 }
 
-void GetAssertionRequestHandler::InternalUVLockedForAuthToken() {
-  DCHECK(state_ == State::kWaitingForTouch ||
-         state_ == State::kWaitingForToken);
-  observer()->OnInternalUserVerificationLocked();
-}
-
 void GetAssertionRequestHandler::HavePINUVAuthTokenResultForAuthenticator(
     FidoAuthenticator* authenticator,
     AuthTokenRequester::Result result,
@@ -522,11 +507,13 @@
 void GetAssertionRequestHandler::ObtainPINUVAuthToken(
     FidoAuthenticator* authenticator,
     std::set<pin::Permissions> permissions,
-    bool skip_pin_touch) {
+    bool skip_pin_touch,
+    bool internal_uv_locked) {
   AuthTokenRequester::Options options;
   options.token_permissions = std::move(permissions);
   options.rp_id = request_.rp_id;
   options.skip_pin_touch = skip_pin_touch;
+  options.internal_uv_locked = internal_uv_locked;
 
   auth_token_requester_map_.insert(
       {authenticator, std::make_unique<AuthTokenRequester>(
@@ -593,14 +580,14 @@
     if (response_time < kMinExpectedAuthenticatorResponseTime) {
       FIDO_LOG(DEBUG) << "Authenticator is probably locked, response_time="
                       << response_time;
-      ObtainPINUVAuthToken(authenticator,
-                           GetPinTokenPermissionsFor(*authenticator, request),
-                           /*skip_pin_touch=*/false);
+      ObtainPINUVAuthToken(
+          authenticator, GetPinTokenPermissionsFor(*authenticator, request),
+          /*skip_pin_touch=*/false, /*internal_uv_locked=*/true);
       return;
     }
     ObtainPINUVAuthToken(authenticator,
                          GetPinTokenPermissionsFor(*authenticator, request),
-                         /*skip_pin_touch=*/true);
+                         /*skip_pin_touch=*/true, /*internal_uv_locked=*/true);
     return;
   }
 
diff --git a/device/fido/get_assertion_request_handler.h b/device/fido/get_assertion_request_handler.h
index cab048e..d55abb9 100644
--- a/device/fido/get_assertion_request_handler.h
+++ b/device/fido/get_assertion_request_handler.h
@@ -92,14 +92,12 @@
   // AuthTokenRequester::Delegate:
   void AuthenticatorSelectedForPINUVAuthToken(
       FidoAuthenticator* authenticator) override;
-  void CollectNewPIN(uint32_t min_pin_length,
-                     bool force_pin_change,
-                     ProvidePINCallback provide_pin_cb) override;
-  void CollectExistingPIN(int attempts,
-                          uint32_t min_pin_length,
-                          ProvidePINCallback provide_pin_cb) override;
+  void CollectPIN(pin::PINEntryReason reason,
+                  pin::PINEntryError error,
+                  uint32_t min_pin_length,
+                  int attempts,
+                  ProvidePINCallback provide_pin_cb) override;
   void PromptForInternalUVRetry(int attempts) override;
-  void InternalUVLockedForAuthToken() override;
   void HavePINUVAuthTokenResultForAuthenticator(
       FidoAuthenticator* authenticator,
       AuthTokenRequester::Result result,
@@ -107,7 +105,8 @@
 
   void ObtainPINUVAuthToken(FidoAuthenticator* authenticator,
                             std::set<pin::Permissions> permissions,
-                            bool skip_pin_touch);
+                            bool skip_pin_touch,
+                            bool internal_uv_locked);
   void HandleResponse(
       FidoAuthenticator* authenticator,
       CtapGetAssertionRequest request,
diff --git a/device/fido/make_credential_request_handler.cc b/device/fido/make_credential_request_handler.cc
index 313fa11..9ca2966 100644
--- a/device/fido/make_credential_request_handler.cc
+++ b/device/fido/make_credential_request_handler.cc
@@ -432,7 +432,8 @@
     case PINUVDisposition::kNoTokenInternalUVPINFallback:
       break;
     case PINUVDisposition::kGetToken:
-      ObtainPINUVAuthToken(authenticator, skip_pin_touch);
+      ObtainPINUVAuthToken(authenticator, skip_pin_touch,
+                           /*internal_uv_locked=*/false);
       return;
     case PINUVDisposition::kUnsatisfiable:
       // |IsCandidateAuthenticatorPostTouch| should have handled this case.
@@ -484,24 +485,15 @@
   CancelActiveAuthenticators(authenticator->GetId());
 }
 
-void MakeCredentialRequestHandler::CollectNewPIN(
+void MakeCredentialRequestHandler::CollectPIN(
+    pin::PINEntryReason reason,
+    pin::PINEntryError error,
     uint32_t min_pin_length,
-    bool force_pin_change,
-    ProvidePINCallback provide_pin_cb) {
-  DCHECK_EQ(state_, State::kWaitingForToken);
-  observer()->CollectPIN(
-      {.mode = force_pin_change ? Observer::CollectPINOptions::Mode::kChange
-                                : Observer::CollectPINOptions::Mode::kSet,
-       .min_pin_length = min_pin_length},
-      std::move(provide_pin_cb));
-}
-
-void MakeCredentialRequestHandler::CollectExistingPIN(
     int attempts,
-    uint32_t min_pin_length,
     ProvidePINCallback provide_pin_cb) {
   DCHECK_EQ(state_, State::kWaitingForToken);
-  observer()->CollectPIN({.mode = Observer::CollectPINOptions::Mode::kChallenge,
+  observer()->CollectPIN({.reason = reason,
+                          .error = error,
                           .min_pin_length = min_pin_length,
                           .attempts = attempts},
                          std::move(provide_pin_cb));
@@ -513,12 +505,6 @@
   observer()->OnRetryUserVerification(attempts);
 }
 
-void MakeCredentialRequestHandler::InternalUVLockedForAuthToken() {
-  DCHECK(state_ == State::kWaitingForTouch ||
-         state_ == State::kWaitingForToken);
-  observer()->OnInternalUserVerificationLocked();
-}
-
 void MakeCredentialRequestHandler::HavePINUVAuthTokenResultForAuthenticator(
     FidoAuthenticator* authenticator,
     AuthTokenRequester::Result result,
@@ -588,12 +574,14 @@
 
 void MakeCredentialRequestHandler::ObtainPINUVAuthToken(
     FidoAuthenticator* authenticator,
-    bool skip_pin_touch) {
+    bool skip_pin_touch,
+    bool internal_uv_locked) {
   AuthTokenRequester::Options options;
   options.token_permissions =
       GetMakeCredentialRequestPermissions(authenticator);
   options.rp_id = request_.rp.id;
   options.skip_pin_touch = skip_pin_touch;
+  options.internal_uv_locked = internal_uv_locked;
 
   auth_token_requester_map_.insert(
       {authenticator, std::make_unique<AuthTokenRequester>(
@@ -652,14 +640,15 @@
     // Authenticators without uvToken support will return this error immediately
     // without user interaction when internal UV is locked.
     const base::TimeDelta response_time = request_timer.Elapsed();
-    observer()->OnInternalUserVerificationLocked();
     if (response_time < kMinExpectedAuthenticatorResponseTime) {
       FIDO_LOG(DEBUG) << "Authenticator is probably locked, response_time="
                       << response_time;
-      ObtainPINUVAuthToken(authenticator, /*skip_pin_touch=*/false);
+      ObtainPINUVAuthToken(authenticator, /*skip_pin_touch=*/false,
+                           /*internal_uv_locked=*/true);
       return;
     }
-    ObtainPINUVAuthToken(authenticator, /*skip_pin_touch=*/true);
+    ObtainPINUVAuthToken(authenticator, /*skip_pin_touch=*/true,
+                         /*internal_uv_locked=*/true);
     return;
   }
 
diff --git a/device/fido/make_credential_request_handler.h b/device/fido/make_credential_request_handler.h
index e8b5a4b4..8821754 100644
--- a/device/fido/make_credential_request_handler.h
+++ b/device/fido/make_credential_request_handler.h
@@ -150,14 +150,12 @@
   // AuthTokenRequester::Delegate:
   void AuthenticatorSelectedForPINUVAuthToken(
       FidoAuthenticator* authenticator) override;
-  void CollectNewPIN(uint32_t min_pin_length,
-                     bool force_pin_change,
-                     ProvidePINCallback provide_pin_cb) override;
-  void CollectExistingPIN(int attempts,
-                          uint32_t min_pin_length,
-                          ProvidePINCallback provide_pin_cb) override;
+  void CollectPIN(pin::PINEntryReason reason,
+                  pin::PINEntryError error,
+                  uint32_t min_pin_length,
+                  int attempts,
+                  ProvidePINCallback provide_pin_cb) override;
   void PromptForInternalUVRetry(int attempts) override;
-  void InternalUVLockedForAuthToken() override;
   void HavePINUVAuthTokenResultForAuthenticator(
       FidoAuthenticator* authenticator,
       AuthTokenRequester::Result result,
@@ -171,7 +169,8 @@
   void OnEnrollmentError(CtapDeviceResponseCode status) override;
 
   void ObtainPINUVAuthToken(FidoAuthenticator* authenticator,
-                            bool skip_pin_touch);
+                            bool skip_pin_touch,
+                            bool internal_uv_locked);
 
   void HandleResponse(
       FidoAuthenticator* authenticator,
diff --git a/device/fido/pin.cc b/device/fido/pin.cc
index 89a7ff7..b1fbcc0 100644
--- a/device/fido/pin.cc
+++ b/device/fido/pin.cc
@@ -10,6 +10,7 @@
 
 #include "base/i18n/char_iterator.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "components/cbor/reader.h"
 #include "components/cbor/values.h"
 #include "components/cbor/writer.h"
@@ -42,10 +43,32 @@
   return it.Advance() && it.Advance() && it.Advance() && it.Advance();
 }
 
-bool IsValid(const std::string& pin) {
-  return pin.size() >= kMinBytes && pin.size() <= kMaxBytes &&
-         pin.back() != 0 && base::IsStringUTF8(pin) &&
-         HasAtLeastFourCodepoints(pin);
+PINEntryError ValidatePIN(const std::string& pin,
+                          uint32_t min_pin_length,
+                          base::Optional<std::string> current_pin) {
+  if (pin.size() < min_pin_length) {
+    return PINEntryError::kTooShort;
+  }
+  if (pin.size() > kMaxBytes || pin.back() == 0 || !base::IsStringUTF8(pin)) {
+    return PINEntryError::kInvalidCharacters;
+  }
+  if (!HasAtLeastFourCodepoints(pin)) {
+    return PINEntryError::kTooShort;
+  }
+  if (pin == current_pin) {
+    return pin::PINEntryError::kSameAsCurrentPIN;
+  }
+  return PINEntryError::kNoError;
+}
+
+PINEntryError ValidatePIN(const base::string16& pin16,
+                          uint32_t min_pin_length,
+                          base::Optional<std::string> current_pin) {
+  std::string pin;
+  if (!base::UTF16ToUTF8(pin16.c_str(), pin16.size(), &pin)) {
+    return pin::PINEntryError::kInvalidCharacters;
+  }
+  return ValidatePIN(std::move(pin), min_pin_length, std::move(current_pin));
 }
 
 // EncodePINCommand returns a CTAP2 PIN command for the operation |subcommand|.
@@ -191,7 +214,7 @@
                        const std::string& pin,
                        const KeyAgreementResponse& peer_key)
     : protocol_(protocol), peer_key_(peer_key) {
-  DCHECK(IsValid(pin));
+  DCHECK_EQ(ValidatePIN(pin), PINEntryError::kNoError);
   memset(pin_, 0, sizeof(pin_));
   memcpy(pin_, pin.data(), pin.size());
 }
@@ -219,7 +242,7 @@
          digest);
   memcpy(old_pin_hash_, digest, sizeof(old_pin_hash_));
 
-  DCHECK(IsValid(new_pin));
+  DCHECK_EQ(ValidatePIN(new_pin), PINEntryError::kNoError);
   memset(new_pin_, 0, sizeof(new_pin_));
   memcpy(new_pin_, new_pin.data(), new_pin.size());
 }
diff --git a/device/fido/pin.h b/device/fido/pin.h
index bda30b1..402bb6f 100644
--- a/device/fido/pin.h
+++ b/device/fido/pin.h
@@ -24,6 +24,39 @@
 namespace device {
 namespace pin {
 
+// The reason we are prompting for a new PIN.
+enum class PINEntryReason {
+  // Indicates a new PIN is being set.
+  kSet,
+
+  // The existing PIN must be changed before using this authenticator.
+  kChange,
+
+  // The existing PIN is being collected to prove user verification.
+  kChallenge
+};
+
+// The errors that may prompt asking for a PIN.
+enum class PINEntryError {
+  // No error has occurred.
+  kNoError,
+
+  // Internal UV is locked, so we are falling back to PIN.
+  kInternalUvLocked,
+
+  // The PIN the user entered does not match the authenticator PIN.
+  kWrongPIN,
+
+  // The new PIN the user entered is too short.
+  kTooShort,
+
+  // The new PIN the user entered contains invalid characters.
+  kInvalidCharacters,
+
+  // The new PIN the user entered is the same as the currently set PIN.
+  kSameAsCurrentPIN,
+};
+
 // Permission list flags. See
 // https://drafts.fidoalliance.org/fido-2/stable-links-to-latest/fido-client-to-authenticator-protocol.html#permissions
 enum class Permissions : uint8_t {
@@ -41,9 +74,20 @@
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-// IsValid returns true if |pin|, which must be UTF-8, is a syntactically valid
-// PIN.
-COMPONENT_EXPORT(DEVICE_FIDO) bool IsValid(const std::string& pin);
+// Validates |pin|, returning |kNoError| if valid or an appropriate error code
+// otherwise.
+COMPONENT_EXPORT(DEVICE_FIDO)
+PINEntryError ValidatePIN(
+    const std::string& pin,
+    uint32_t min_pin_length = kMinPinLength,
+    base::Optional<std::string> current_pin = base::nullopt);
+
+// Like |ValidatePIN| above but takes a wide string.
+COMPONENT_EXPORT(DEVICE_FIDO)
+PINEntryError ValidatePIN(
+    const base::string16& pin16,
+    uint32_t min_pin_length = kMinPinLength,
+    base::Optional<std::string> current_pin = base::nullopt);
 
 // kMinBytes is the minimum number of *bytes* of PIN data that a CTAP2 device
 // will accept. Since the PIN is UTF-8 encoded, this could be a single code
diff --git a/device/fido/set_pin_request_handler.cc b/device/fido/set_pin_request_handler.cc
index e4ada0c..310c8a8 100644
--- a/device/fido/set_pin_request_handler.cc
+++ b/device/fido/set_pin_request_handler.cc
@@ -35,7 +35,7 @@
                                       const std::string& new_pin) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(State::kWaitingForPIN, state_);
-  DCHECK(pin::IsValid(new_pin));
+  DCHECK_EQ(pin::ValidatePIN(new_pin), pin::PINEntryError::kNoError);
 
   if (authenticator_ == nullptr) {
     // Authenticator was detached.
diff --git a/device/vr/openxr/test/fake_openxr_impl_api.cc b/device/vr/openxr/test/fake_openxr_impl_api.cc
index 7c60dc0..63b3ba6 100644
--- a/device/vr/openxr/test/fake_openxr_impl_api.cc
+++ b/device/vr/openxr/test/fake_openxr_impl_api.cc
@@ -665,6 +665,31 @@
   return XR_SUCCESS;
 }
 
+XrResult xrGetViewConfigurationProperties(
+    XrInstance instance,
+    XrSystemId system_id,
+    XrViewConfigurationType view_configuration_type,
+    XrViewConfigurationProperties* configuration_properties) {
+  DVLOG(2) << __FUNCTION__;
+  RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
+  RETURN_IF_XR_FAILED(g_test_helper.ValidateSystemId(system_id));
+  RETURN_IF(
+      view_configuration_type != XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
+      XR_ERROR_VALIDATION_FAILURE, "viewConfigurationType must be stereo");
+  RETURN_IF(
+      configuration_properties->type == XR_TYPE_VIEW_CONFIGURATION_PROPERTIES,
+      XR_ERROR_VALIDATION_FAILURE,
+      "XrViewConfigurationProperties.type must be "
+      "XR_TYPE_VIEW_CONFIGURATION_PROPERTIES");
+  RETURN_IF(configuration_properties->next == nullptr,
+            XR_ERROR_VALIDATION_FAILURE,
+            "XrViewConfigurationProperties.next must be nullptr");
+  configuration_properties->viewConfigurationType =
+      XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
+  configuration_properties->fovMutable = XR_TRUE;
+  return XR_SUCCESS;
+}
+
 XrResult xrGetSystem(XrInstance instance,
                      const XrSystemGetInfo* get_info,
                      XrSystemId* system_id) {
@@ -982,6 +1007,9 @@
   } else if (strcmp(name, "xrGetReferenceSpaceBoundsRect") == 0) {
     *function =
         reinterpret_cast<PFN_xrVoidFunction>(xrGetReferenceSpaceBoundsRect);
+  } else if (strcmp(name, "xrGetViewConfigurationProperties") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrGetViewConfigurationProperties);
   } else if (strcmp(name, "xrGetSystem") == 0) {
     *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetSystem);
   } else if (strcmp(name, "xrLocateSpace") == 0) {
diff --git a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc
index 58524a6..2f771a5 100644
--- a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc
+++ b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc
@@ -105,7 +105,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (error)
-    Respond(Error(*error));
+    Respond(Error(std::move(*error)));
   else
     Respond(NoArguments());
 }
@@ -184,14 +184,22 @@
   auto* rules_monitor_service =
       declarative_net_request::RulesMonitorService::Get(browser_context());
   DCHECK(rules_monitor_service);
-  std::string update_error;
-  if (!rules_monitor_service->UpdateSessionRules(
-          extension_id(), std::move(rule_ids_to_remove),
-          std::move(rules_to_add), &update_error)) {
-    return RespondNow(Error(std::move(update_error)));
-  }
+  rules_monitor_service->UpdateSessionRules(
+      *extension(), std::move(rule_ids_to_remove), std::move(rules_to_add),
+      base::BindOnce(&DeclarativeNetRequestUpdateSessionRulesFunction::
+                         OnSessionRulesUpdated,
+                     this));
+  return did_respond() ? AlreadyResponded() : RespondLater();
+}
 
-  return RespondNow(NoArguments());
+void DeclarativeNetRequestUpdateSessionRulesFunction::OnSessionRulesUpdated(
+    base::Optional<std::string> error) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (error)
+    Respond(Error(std::move(*error)));
+  else
+    Respond(NoArguments());
 }
 
 DeclarativeNetRequestGetSessionRulesFunction::
diff --git a/extensions/browser/api/declarative_net_request/declarative_net_request_api.h b/extensions/browser/api/declarative_net_request/declarative_net_request_api.h
index 1d5a691..ca3531e 100644
--- a/extensions/browser/api/declarative_net_request/declarative_net_request_api.h
+++ b/extensions/browser/api/declarative_net_request/declarative_net_request_api.h
@@ -62,6 +62,9 @@
 
   // ExtensionFunction override:
   ExtensionFunction::ResponseAction Run() override;
+
+ private:
+  void OnSessionRulesUpdated(base::Optional<std::string> error);
 };
 
 class DeclarativeNetRequestGetSessionRulesFunction : public ExtensionFunction {
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
index 8e5e45ddf..9f51c2f 100644
--- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
+++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -260,55 +260,20 @@
   return result;
 }
 
-bool RulesMonitorService::UpdateSessionRules(
-    const ExtensionId& extension_id,
+void RulesMonitorService::UpdateSessionRules(
+    const Extension& extension,
     std::vector<int> rule_ids_to_remove,
     std::vector<api::declarative_net_request::Rule> rules_to_add,
-    std::string* error) {
-  DCHECK(error);
-
+    base::OnceCallback<void(base::Optional<std::string> error)> callback) {
   // Sanity check that this is only called for an enabled extension.
-  DCHECK(extension_registry_->enabled_extensions().Contains(extension_id));
+  DCHECK(extension_registry_->enabled_extensions().Contains(extension.id()));
 
-  std::vector<api::declarative_net_request::Rule> new_rules =
-      GetSessionRules(extension_id);
-
-  std::set<int> ids_to_remove(rule_ids_to_remove.begin(),
-                              rule_ids_to_remove.end());
-  base::EraseIf(new_rules, [&ids_to_remove](const dnr_api::Rule& rule) {
-    return base::Contains(ids_to_remove, rule.id);
-  });
-
-  new_rules.insert(new_rules.end(),
-                   std::make_move_iterator(rules_to_add.begin()),
-                   std::make_move_iterator(rules_to_add.end()));
-
-  // TODO(crbug.com/1043200): Implement a shared rules and regex rules limit for
-  // dynamic and session-scoped rules.
-  if (new_rules.size() > kSessionRulesetLimit) {
-    *error = "Number of session scoped rules exceeded";
-    return false;
-  }
-
-  std::unique_ptr<base::ListValue> new_rules_value = base::ListValue::From(
-      json_schema_compiler::util::CreateValueFromArray(new_rules));
-  DCHECK(new_rules_value);
-
-  std::unique_ptr<RulesetMatcher> matcher =
-      CreateSessionScopedMatcher(extension_id, std::move(new_rules), error);
-  if (!matcher)
-    return false;  // |error| should be already populated.
-
-  session_rules_[extension_id] = std::move(*new_rules_value);
-
-  // Update the RulesetMatcher if the extension is not currently loading its
-  // initial rulesets in response to extension load. If it is, then the
-  // session-scoped ruleset will be loaded subsequently in
-  // OnInitialRulesetsLoadedFromDisk.
-  if (!base::Contains(tasks_pending_on_load_, extension_id))
-    UpdateRulesetMatcher(extension_id, std::move(matcher));
-
-  return true;
+  ExecuteOrQueueAPICall(
+      extension,
+      base::BindOnce(&RulesMonitorService::UpdateSessionRulesInternal,
+                     weak_factory_.GetWeakPtr(), extension.id(),
+                     std::move(rule_ids_to_remove), std::move(rules_to_add),
+                     std::move(callback)));
 }
 
 RulesMonitorService::RulesMonitorService(
@@ -503,7 +468,7 @@
     DynamicRuleUpdateUICallback callback) {
   if (!extension_registry_->enabled_extensions().Contains(extension_id)) {
     // There is no enabled extension to respond to. While this is probably a
-    // no-op, still dispatch the callback to ensure any related book-keeping is
+    // no-op, still dispatch the callback to ensure any related bookkeeping is
     // done.
     std::move(callback).Run(base::nullopt /* error */);
     return;
@@ -524,6 +489,56 @@
       std::move(update_rules_callback));
 }
 
+void RulesMonitorService::UpdateSessionRulesInternal(
+    const ExtensionId& extension_id,
+    std::vector<int> rule_ids_to_remove,
+    std::vector<api::declarative_net_request::Rule> rules_to_add,
+    base::OnceCallback<void(base::Optional<std::string> error)> callback) {
+  if (!extension_registry_->enabled_extensions().Contains(extension_id)) {
+    // There is no enabled extension to respond to. While this is probably a
+    // no-op, still dispatch the callback to ensure any related bookkeeping is
+    // done.
+    std::move(callback).Run(base::nullopt /* error */);
+    return;
+  }
+
+  std::vector<api::declarative_net_request::Rule> new_rules =
+      GetSessionRules(extension_id);
+
+  std::set<int> ids_to_remove(rule_ids_to_remove.begin(),
+                              rule_ids_to_remove.end());
+  base::EraseIf(new_rules, [&ids_to_remove](const dnr_api::Rule& rule) {
+    return base::Contains(ids_to_remove, rule.id);
+  });
+
+  new_rules.insert(new_rules.end(),
+                   std::make_move_iterator(rules_to_add.begin()),
+                   std::make_move_iterator(rules_to_add.end()));
+
+  // TODO(crbug.com/1043200): Implement a shared rules and regex rules limit for
+  // dynamic and session-scoped rules.
+  if (new_rules.size() > kSessionRulesetLimit) {
+    std::move(callback).Run("Number of session scoped rules exceeded");
+    return;
+  }
+
+  std::unique_ptr<base::ListValue> new_rules_value = base::ListValue::From(
+      json_schema_compiler::util::CreateValueFromArray(new_rules));
+  DCHECK(new_rules_value);
+
+  std::string error;
+  std::unique_ptr<RulesetMatcher> matcher =
+      CreateSessionScopedMatcher(extension_id, std::move(new_rules), &error);
+  if (!matcher) {
+    std::move(callback).Run(std::move(error));
+    return;
+  }
+
+  session_rules_[extension_id] = std::move(*new_rules_value);
+  UpdateRulesetMatcher(extension_id, std::move(matcher));
+  std::move(callback).Run(base::nullopt /* error */);
+}
+
 void RulesMonitorService::UpdateEnabledStaticRulesetsInternal(
     const ExtensionId& extension_id,
     std::set<RulesetID> ids_to_disable,
@@ -533,7 +548,7 @@
       extension_id, ExtensionRegistry::ENABLED);
   if (!extension) {
     // There is no enabled extension to respond to. While this is probably a
-    // no-op, still dispatch the callback to ensure any related book-keeping is
+    // no-op, still dispatch the callback to ensure any related bookkeeping is
     // done.
     std::move(callback).Run(base::nullopt /* error */);
     return;
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.h b/extensions/browser/api/declarative_net_request/rules_monitor_service.h
index 05b5b3f..430a0b9 100644
--- a/extensions/browser/api/declarative_net_request/rules_monitor_service.h
+++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.h
@@ -105,13 +105,13 @@
   std::vector<api::declarative_net_request::Rule> GetSessionRules(
       const ExtensionId& extension_id) const;
 
-  // Updates the session scoped rules for the given |extension_id|. On failure,
-  // returns false and populates |error|.
-  bool UpdateSessionRules(
-      const ExtensionId& extension_id,
+  // Updates the session scoped rules for the given |extension_id|. Invokes
+  // |callback| with an optional error.
+  void UpdateSessionRules(
+      const Extension& extension,
       std::vector<int> rule_ids_to_remove,
       std::vector<api::declarative_net_request::Rule> rules_to_add,
-      std::string* error);
+      base::OnceCallback<void(base::Optional<std::string> error)> callback);
 
   RulesetManager* ruleset_manager() { return &ruleset_manager_; }
 
@@ -167,6 +167,13 @@
       std::set<RulesetID> ids_to_enable,
       UpdateEnabledRulesetsUICallback callback);
 
+  // Internal helper for UpdateSessionRules.
+  void UpdateSessionRulesInternal(
+      const ExtensionId& extension_id,
+      std::vector<int> rule_ids_to_remove,
+      std::vector<api::declarative_net_request::Rule> rules_to_add,
+      base::OnceCallback<void(base::Optional<std::string> error)> callback);
+
   // Invoked when we have loaded the rulesets in |load_data| on
   // |file_task_runner_| in response to OnExtensionLoaded.
   void OnInitialRulesetsLoadedFromDisk(LoadRequestData load_data);
diff --git a/google_apis/test/OWNERS b/google_apis/test/OWNERS
new file mode 100644
index 0000000..a020bfae
--- /dev/null
+++ b/google_apis/test/OWNERS
@@ -0,0 +1 @@
+per-file embedded_setup_chromeos.html=file://ash/login/LOGIN_LOCK_OWNERS
diff --git a/ios/chrome/browser/sync/session_sync_service_factory.mm b/ios/chrome/browser/sync/session_sync_service_factory.mm
index 0a11d81ab..701a07c7d 100644
--- a/ios/chrome/browser/sync/session_sync_service_factory.mm
+++ b/ios/chrome/browser/sync/session_sync_service_factory.mm
@@ -15,6 +15,8 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/model/model_type_store_service.h"
+#include "components/sync_device_info/device_info_sync_service.h"
+#include "components/sync_device_info/device_info_tracker.h"
 #include "components/sync_sessions/local_session_event_router.h"
 #include "components/sync_sessions/session_sync_prefs.h"
 #include "components/sync_sessions/session_sync_service_impl.h"
@@ -24,6 +26,7 @@
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
+#include "ios/chrome/browser/sync/device_info_sync_service_factory.h"
 #include "ios/chrome/browser/sync/glue/sync_start_util.h"
 #include "ios/chrome/browser/sync/model_type_store_service_factory.h"
 #import "ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.h"
@@ -95,6 +98,12 @@
     return ShouldSyncURLImpl(url);
   }
 
+  bool IsRecentLocalCacheGuid(const std::string& cache_guid) const override {
+    return DeviceInfoSyncServiceFactory::GetForBrowserState(browser_state_)
+        ->GetDeviceInfoTracker()
+        ->IsRecentLocalCacheGuid(cache_guid);
+  }
+
   sync_sessions::SyncedWindowDelegatesGetter* GetSyncedWindowDelegatesGetter()
       override {
     return window_delegates_getter_.get();
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index fb2b0288..4407c4a 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -67,8 +67,10 @@
     "//ios/chrome/browser/ui/bookmarks/cells",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/elements",
+    "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/list_model",
+    "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/material_components",
     "//ios/chrome/browser/ui/menu",
     "//ios/chrome/browser/ui/sharing",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
index 16f1eb4..23669b1 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -51,7 +51,9 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/elements/home_waiting_view.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
+#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/material_components/utils.h"
 #import "ios/chrome/browser/ui/menu/action_factory.h"
 #import "ios/chrome/browser/ui/menu/menu_histograms.h"
@@ -713,6 +715,22 @@
 - (void)openAllURLs:(std::vector<GURL>)urls
         inIncognito:(BOOL)inIncognito
              newTab:(BOOL)newTab {
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && inIncognito) {
+    IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent
+        agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser)
+                           ->GetSceneState()];
+    if (reauthAgent.authenticationRequired) {
+      __weak BookmarkHomeViewController* weakSelf = self;
+      [reauthAgent
+          authenticateIncognitoContentWithCompletionBlock:^(BOOL success) {
+            if (success) {
+              [weakSelf openAllURLs:urls inIncognito:inIncognito newTab:newTab];
+            }
+          }];
+      return;
+    }
+  }
+
   [self cacheIndexPathRow];
   [self.homeDelegate bookmarkHomeViewControllerWantsDismissal:self
                                              navigationToUrls:urls
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 04085173..005e6e8 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -95,6 +95,7 @@
 #import "ios/chrome/browser/ui/image_util/image_copier.h"
 #import "ios/chrome/browser/ui/image_util/image_saver.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.h"
 #import "ios/chrome/browser/ui/infobars/infobar_container_coordinator.h"
 #import "ios/chrome/browser/ui/infobars/infobar_feature.h"
@@ -3411,6 +3412,27 @@
           params.append_to = kCurrentTab;
           UrlLoadingBrowserAgent::FromBrowser(self.browser)->Load(params);
         };
+
+        if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) {
+          IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent
+              agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser)
+                                 ->GetSceneState()];
+          // Wrap the action inside of an auth check block.
+          ProceduralBlock wrappedAction = action;
+          action = ^{
+            if (reauthAgent.authenticationRequired) {
+              [reauthAgent authenticateIncognitoContentWithCompletionBlock:^(
+                               BOOL success) {
+                if (success) {
+                  wrappedAction();
+                }
+              }];
+            } else {
+              wrappedAction();
+            }
+          };
+        }
+
         [_contextMenuCoordinator addItemWithTitle:title
                                            action:action
                                             style:UIAlertActionStyleDefault];
@@ -4852,6 +4874,11 @@
   if (!self.active)
     return YES;
 
+  BOOL isShowingIncognitoBlocker = (self.blockingView.superview != nil);
+  if (isShowingIncognitoBlocker) {
+    return YES;
+  }
+
   return NO;
 }
 
diff --git a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h
index 4ac04db6..d9f9a47 100644
--- a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h
+++ b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h
@@ -88,8 +88,23 @@
 - (void)recordNoticeCardShown:(BOOL)shown;
 
 // Records the |durationInSeconds| it took to Discover feed to Fetch articles.
+// |success| is YES if operation was successful.
 - (void)recordFeedArticlesFetchDurationInSeconds:
-    (NSTimeInterval)durationInSeconds;
+            (NSTimeInterval)durationInSeconds
+                                         success:(BOOL)success;
+
+// Records the |durationInSeconds| it took to Discover feed to Fetch more
+// articles (e.g. New "infinite feed" articles). |success| is YES if operation
+// was successful.
+- (void)recordFeedMoreArticlesFetchDurationInSeconds:
+            (NSTimeInterval)durationInSeconds
+                                             success:(BOOL)success;
+
+// Records the |durationInSeconds| it took to Discover feed to upload actions.
+// |success| is YES if operation was successful.
+- (void)recordFeedUploadActionsDurationInSeconds:
+            (NSTimeInterval)durationInSeconds
+                                         success:(BOOL)success;
 
 @end
 
diff --git a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm
index 1c1e653..4c769b3a 100644
--- a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm
@@ -112,8 +112,39 @@
 const char kDiscoverFeedNoticeCardFulfilled[] =
     "ContentSuggestions.Feed.NoticeCardFulfilled2";
 
-// Histogram name to measure the time it tood the Feed to fetch articles.
-const char kDiscoverFeedArticlesFetchNetworkDuration[] =
+// Histogram name to measure the time it took the Feed to fetch articles
+// successfully.
+const char kDiscoverFeedArticlesFetchNetworkDurationSuccess[] =
+    "ContentSuggestions.Feed.Network.Duration.ArticlesFetchSuccess";
+
+// Histogram name to measure the time it took the Feed to fetch articles
+// unsuccessfully.
+const char kDiscoverFeedArticlesFetchNetworkDurationFailure[] =
+    "ContentSuggestions.Feed.Network.Duration.ArticlesFetchFailure";
+
+// Histogram name to measure the time it took the Feed to fetch more articles
+// successfully.
+const char kDiscoverFeedMoreArticlesFetchNetworkDurationSuccess[] =
+    "ContentSuggestions.Feed.Network.Duration.MoreArticlesFetchSuccess";
+
+// Histogram name to measure the time it took the Feed to fetch more articles
+// unsuccessfully.
+const char kDiscoverFeedMoreArticlesFetchNetworkDurationFailure[] =
+    "ContentSuggestions.Feed.Network.Duration.MoreArticlesFetchFailure";
+
+// Histogram name to measure the time it took the Feed to upload actions
+// successfully.
+const char kDiscoverFeedUploadActionsNetworkDurationSuccess[] =
+    "ContentSuggestions.Feed.Network.Duration.ActionUploadSuccess";
+
+// Histogram name to measure the time it took the Feed to upload actions
+// unsuccessfully.
+const char kDiscoverFeedUploadActionsNetworkDurationFailure[] =
+    "ContentSuggestions.Feed.Network.Duration.ActionUploadFailure";
+
+// Histogram name to measure the time it took the Feed to perform a network
+// operation.
+const char kDiscoverFeedNetworkDuration[] =
     "ContentSuggestions.Feed.Network.Duration";
 
 // Minimum scrolling amount to record a FeedEngagementType::kFeedEngaged due to
@@ -294,9 +325,44 @@
 }
 
 - (void)recordFeedArticlesFetchDurationInSeconds:
-    (NSTimeInterval)durationInSeconds {
-  UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedArticlesFetchNetworkDuration,
-                             base::TimeDelta::FromSeconds(durationInSeconds));
+            (NSTimeInterval)durationInSeconds
+                                         success:(BOOL)success {
+  if (success) {
+    UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedArticlesFetchNetworkDurationSuccess,
+                               base::TimeDelta::FromSeconds(durationInSeconds));
+  } else {
+    UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedArticlesFetchNetworkDurationFailure,
+                               base::TimeDelta::FromSeconds(durationInSeconds));
+  }
+  [self recordNetworkRequestDurationInSeconds:durationInSeconds];
+}
+
+- (void)recordFeedMoreArticlesFetchDurationInSeconds:
+            (NSTimeInterval)durationInSeconds
+                                             success:(BOOL)success {
+  if (success) {
+    UMA_HISTOGRAM_MEDIUM_TIMES(
+        kDiscoverFeedMoreArticlesFetchNetworkDurationSuccess,
+        base::TimeDelta::FromSeconds(durationInSeconds));
+  } else {
+    UMA_HISTOGRAM_MEDIUM_TIMES(
+        kDiscoverFeedMoreArticlesFetchNetworkDurationFailure,
+        base::TimeDelta::FromSeconds(durationInSeconds));
+  }
+  [self recordNetworkRequestDurationInSeconds:durationInSeconds];
+}
+
+- (void)recordFeedUploadActionsDurationInSeconds:
+            (NSTimeInterval)durationInSeconds
+                                         success:(BOOL)success {
+  if (success) {
+    UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedUploadActionsNetworkDurationSuccess,
+                               base::TimeDelta::FromSeconds(durationInSeconds));
+  } else {
+    UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedUploadActionsNetworkDurationFailure,
+                               base::TimeDelta::FromSeconds(durationInSeconds));
+  }
+  [self recordNetworkRequestDurationInSeconds:durationInSeconds];
 }
 
 #pragma mark - Private
@@ -362,4 +428,12 @@
   self.scrolledReported = NO;
 }
 
+// Records the |durationInSeconds| it took to Discover feed to perform any
+// network operation.
+- (void)recordNetworkRequestDurationInSeconds:
+    (NSTimeInterval)durationInSeconds {
+  UMA_HISTOGRAM_MEDIUM_TIMES(kDiscoverFeedNetworkDuration,
+                             base::TimeDelta::FromSeconds(durationInSeconds));
+}
+
 @end
diff --git a/ios/chrome/browser/ui/incognito_reauth/OWNERS b/ios/chrome/browser/ui/incognito_reauth/OWNERS
new file mode 100644
index 0000000..96e7948a
--- /dev/null
+++ b/ios/chrome/browser/ui/incognito_reauth/OWNERS
@@ -0,0 +1 @@
+stkhapugin@chromium.org
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
index a0d516f3..5f714396 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
@@ -36,6 +36,14 @@
 
 - (instancetype)init NS_UNAVAILABLE;
 
+// Requests authentication and marks the scene as authenticated until the next
+// scene foregrounding.
+// The authentication will require user interaction. Upon completion, will
+// notify observers and call the completion block (passing authentication
+// result).
+- (void)authenticateIncognitoContentWithCompletionBlock:
+    (void (^)(BOOL success))completion;
+
 // Registers the prefs required for this agent.
 + (void)registerLocalState:(PrefRegistrySimple*)registry;
 
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
index 67aeec1..787209d9 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
@@ -69,6 +69,11 @@
 }
 
 - (void)authenticateIncognitoContent {
+  [self authenticateIncognitoContentWithCompletionBlock:nil];
+}
+
+- (void)authenticateIncognitoContentWithCompletionBlock:
+    (void (^)(BOOL success))completion {
   DCHECK(self.reauthModule);
 
   if (!self.isAuthenticationRequired) {
@@ -88,6 +93,9 @@
                                       ReauthenticationResult::kSuccess);
                                  weakSelf.authenticatedSinceLastForeground =
                                      success;
+                                 if (completion) {
+                                   completion(success);
+                                 }
                                }];
 }
 
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index 79b5ea3..4e372c1 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -1144,6 +1144,20 @@
 }
 
 - (void)openURLInNewTab:(OpenNewTabCommand*)command {
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication) &&
+      command.inIncognito) {
+    IncognitoReauthSceneAgent* reauthAgent =
+        [IncognitoReauthSceneAgent agentFromScene:self.sceneState];
+    if (reauthAgent.authenticationRequired) {
+      __weak SceneController* weakSelf = self;
+      [reauthAgent
+          authenticateIncognitoContentWithCompletionBlock:^(BOOL success) {
+            [weakSelf openURLInNewTab:command];
+          }];
+      return;
+    }
+  }
+
   UrlLoadParams params =
       UrlLoadParams::InNewTab(command.URL, command.virtualURL);
   params.SetInBackground(command.inBackground);
@@ -1717,13 +1731,33 @@
                                dismissOmnibox:(BOOL)dismissOmnibox
                                    completion:(ProceduralBlock)completion {
   UrlLoadParams copyOfUrlLoadParams = urlLoadParams;
-  [self
-      dismissModalDialogsWithCompletion:^{
-        [self openSelectedTabInMode:targetMode
+
+  __weak SceneController* weakSelf = self;
+  void (^dismissModalsCompletion)() = ^{
+    [weakSelf openSelectedTabInMode:targetMode
                   withUrlLoadParams:copyOfUrlLoadParams
                          completion:completion];
-      }
-                         dismissOmnibox:dismissOmnibox];
+  };
+
+  // Wrap the post-dismiss-modals action with the incognito auth check.
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication) &&
+      targetMode == ApplicationModeForTabOpening::INCOGNITO) {
+    IncognitoReauthSceneAgent* reauthAgent =
+        [IncognitoReauthSceneAgent agentFromScene:self.sceneState];
+    if (reauthAgent.authenticationRequired) {
+      dismissModalsCompletion = ^{
+        [reauthAgent
+            authenticateIncognitoContentWithCompletionBlock:^(BOOL success) {
+              if (success) {
+                dismissModalsCompletion();
+              }
+            }];
+      };
+    }
+  }
+
+  [self dismissModalDialogsWithCompletion:dismissModalsCompletion
+                           dismissOmnibox:dismissOmnibox];
 }
 
 - (void)dismissModalsAndOpenMultipleTabsInMode:
diff --git a/ios/chrome/browser/ui/menu/BUILD.gn b/ios/chrome/browser/ui/menu/BUILD.gn
index e149907d..66b7ebfa 100644
--- a/ios/chrome/browser/ui/menu/BUILD.gn
+++ b/ios/chrome/browser/ui/menu/BUILD.gn
@@ -26,7 +26,10 @@
     "resources:share",
     "//base",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
+    "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/url_loading",
     "//ios/chrome/browser/window_activities",
diff --git a/ios/chrome/browser/ui/menu/action_factory.mm b/ios/chrome/browser/ui/menu/action_factory.mm
index 4724919c..d9dcedf 100644
--- a/ios/chrome/browser/ui/menu/action_factory.mm
+++ b/ios/chrome/browser/ui/menu/action_factory.mm
@@ -7,6 +7,9 @@
 #import "base/metrics/histogram_functions.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
+#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/util/pasteboard_util.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
@@ -130,6 +133,23 @@
 }
 
 - (UIAction*)actionToOpenInNewIncognitoTabWithBlock:(ProceduralBlock)block {
+  // Wrap the block with the incognito auth check, if necessary.
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) {
+    IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent
+        agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser)
+                           ->GetSceneState()];
+    if (reauthAgent.authenticationRequired) {
+      block = ^{
+        [reauthAgent
+            authenticateIncognitoContentWithCompletionBlock:^(BOOL success) {
+              if (success && block != nullptr) {
+                block();
+              }
+            }];
+      };
+    }
+  }
+
   return [self actionWithTitle:l10n_util::GetNSString(
                                    IDS_IOS_OPEN_IN_INCOGNITO_ACTION_TITLE)
                          image:[UIImage imageNamed:@"open_in_incognito"]
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn
index 5617969..934ecc9 100644
--- a/ios/chrome/browser/ui/reading_list/BUILD.gn
+++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -41,11 +41,14 @@
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/reading_list",
     "//ios/chrome/browser/tabs",
+    "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/activity_services",
     "//ios/chrome/browser/ui/alert_coordinator",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/favicon",
+    "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
+    "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/menu",
     "//ios/chrome/browser/ui/reading_list/context_menu",
     "//ios/chrome/browser/ui/reading_list/resources:distillation_fail_new",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
index deeb038f..9ac9e2a 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -22,6 +22,8 @@
 #import "ios/chrome/browser/ui/activity_services/activity_params.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
+#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/menu/action_factory.h"
 #import "ios/chrome/browser/ui/menu/menu_histograms.h"
 #import "ios/chrome/browser/ui/reading_list/context_menu/reading_list_context_menu_coordinator.h"
@@ -40,6 +42,7 @@
 #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller.h"
 #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_constants.h"
 #import "ios/chrome/browser/ui/table_view/table_view_presentation_controller.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/util/multi_window_support.h"
 #import "ios/chrome/browser/ui/util/pasteboard_util.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
@@ -385,6 +388,30 @@
       withOfflineURL:(const GURL&)offlineURL
             inNewTab:(BOOL)newTab
            incognito:(BOOL)incognito {
+  // Only open a new incognito tab when incognito is authenticated. Prompt for
+  // auth otherwise.
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && incognito) {
+    IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent
+        agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser)
+                           ->GetSceneState()];
+    __weak ReadingListCoordinator* weakSelf = self;
+    if (reauthAgent.authenticationRequired) {
+      // Copy C++ args to call later from the block.
+      GURL copyEntryURL = GURL(entryURL);
+      GURL copyOfflineURL = GURL(offlineURL);
+      [reauthAgent
+          authenticateIncognitoContentWithCompletionBlock:^(BOOL success) {
+            if (success) {
+              [weakSelf loadEntryURL:copyEntryURL
+                      withOfflineURL:copyOfflineURL
+                            inNewTab:newTab
+                           incognito:incognito];
+            }
+          }];
+      return;
+    }
+  }
+
   DCHECK(entryURL.is_valid());
   base::RecordAction(base::UserMetricsAction("MobileReadingListOpen"));
   web::WebState* activeWebState =
diff --git a/ios/chrome/browser/ui/scanner/scanner_view.mm b/ios/chrome/browser/ui/scanner/scanner_view.mm
index 84bb2afe..238485b 100644
--- a/ios/chrome/browser/ui/scanner/scanner_view.mm
+++ b/ios/chrome/browser/ui/scanner/scanner_view.mm
@@ -37,6 +37,8 @@
 }  // namespace
 
 @interface ScannerView () {
+  // A scrollview containing the viewport's caption.
+  UIScrollView* _captionContainer;
   // A button to toggle the torch.
   UIBarButtonItem* _torchButton;
   // A view containing the preview layer for camera input.
@@ -181,6 +183,12 @@
   return @"";
 }
 
+- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
+  [super traitCollectionDidChange:previousTraitCollection];
+  _captionContainer.hidden =
+      UIUserInterfaceSizeClassCompact == self.traitCollection.verticalSizeClass;
+}
+
 #pragma mark - private methods
 
 // Creates an image with template rendering mode for use in icons.
@@ -263,35 +271,39 @@
   [viewportCaption.layer setMasksToBounds:NO];
   [viewportCaption.layer setShouldRasterize:YES];
 
-  UIScrollView* scrollView = [[UIScrollView alloc] init];
-  scrollView.showsVerticalScrollIndicator = NO;
-  [self addSubview:scrollView];
-  [scrollView addSubview:viewportCaption];
+  _captionContainer = [[UIScrollView alloc] init];
+  _captionContainer.showsVerticalScrollIndicator = NO;
+  [self addSubview:_captionContainer];
+  [_captionContainer addSubview:viewportCaption];
 
   // Constraints for viewportCaption.
-  scrollView.translatesAutoresizingMaskIntoConstraints = NO;
+  _captionContainer.translatesAutoresizingMaskIntoConstraints = NO;
   viewportCaption.translatesAutoresizingMaskIntoConstraints = NO;
 
   [NSLayoutConstraint activateConstraints:@[
-    [scrollView.topAnchor
+    [_captionContainer.topAnchor
         constraintEqualToAnchor:self.centerYAnchor
-                       constant:[self viewportSize].height / 2 +
+                       constant:self.viewportSize.height / 2 +
                                 kViewportCaptionVerticalPadding],
-    [scrollView.bottomAnchor constraintEqualToAnchor:toolbar.topAnchor],
-    [scrollView.leadingAnchor
-        constraintEqualToAnchor:self.leadingAnchor
-                       constant:kViewportCaptionHorizontalPadding],
-    [viewportCaption.leadingAnchor
-        constraintEqualToAnchor:self.leadingAnchor
-                       constant:kViewportCaptionHorizontalPadding],
-    [scrollView.trailingAnchor
-        constraintEqualToAnchor:self.trailingAnchor
-                       constant:-kViewportCaptionHorizontalPadding],
-    [viewportCaption.trailingAnchor
-        constraintEqualToAnchor:self.trailingAnchor
-                       constant:-kViewportCaptionHorizontalPadding],
+    [_captionContainer.bottomAnchor constraintEqualToAnchor:toolbar.topAnchor],
+    [_captionContainer.centerXAnchor
+        constraintEqualToAnchor:_previewOverlay.centerXAnchor],
+    [_captionContainer.contentLayoutGuide.widthAnchor
+        constraintEqualToAnchor:_captionContainer.widthAnchor],
+    [_captionContainer.widthAnchor
+        constraintLessThanOrEqualToAnchor:self.widthAnchor
+                                 constant:-2 *
+                                          kViewportCaptionHorizontalPadding],
+    [_captionContainer.widthAnchor
+        constraintLessThanOrEqualToAnchor:self.heightAnchor
+                                 constant:-2 *
+                                          kViewportCaptionHorizontalPadding],
   ]];
-  AddSameConstraints(scrollView, viewportCaption);
+  AddSameConstraints(_captionContainer, viewportCaption);
+
+  // There is no space for at least 1 line of text in compact height.
+  _captionContainer.hidden =
+      UIUserInterfaceSizeClassCompact == self.traitCollection.verticalSizeClass;
 }
 
 // Adds a preview view to |self| and configures its layout constraints.
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
index 5ce7ed5..29cbff5 100644
--- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -115,6 +115,10 @@
 #pragma mark - UIViewController
 
 - (void)viewDidLoad {
+  if (!base::FeatureList::IsEnabled(kSettingsRefresh)) {
+    self.styler.tableViewBackgroundColor =
+        UIColor.cr_systemGroupedBackgroundColor;
+  }
   UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc]
       initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                            target:nil
diff --git a/ios/chrome/browser/url_loading/BUILD.gn b/ios/chrome/browser/url_loading/BUILD.gn
index 26e738bb..9616c6f9 100644
--- a/ios/chrome/browser/url_loading/BUILD.gn
+++ b/ios/chrome/browser/url_loading/BUILD.gn
@@ -37,7 +37,10 @@
     "//ios/chrome/browser/prerender",
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/snapshots",
+    "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
+    "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/ntp:util",
     "//ios/chrome/browser/web",
     "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm
index 7d2af5f..401bdd87 100644
--- a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm
+++ b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm
@@ -14,7 +14,10 @@
 #import "ios/chrome/browser/prerender/prerender_service.h"
 #import "ios/chrome/browser/prerender/prerender_service_factory.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
+#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/ntp/ntp_util.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/url_loading/scene_url_loading_service.h"
 #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h"
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
@@ -285,6 +288,15 @@
   DCHECK(scene_service_);
   DCHECK(delegate_);
   DCHECK(browser_);
+
+  if (base::FeatureList::IsEnabled(kIncognitoAuthentication) &&
+      params.in_incognito) {
+    IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent
+        agentFromScene:SceneStateBrowserAgent::FromBrowser(browser_)
+                           ->GetSceneState()];
+    DCHECK(!reauthAgent.authenticationRequired);
+  }
+
   ChromeBrowserState* browser_state = browser_->GetBrowserState();
   ChromeBrowserState* active_browser_state =
       scene_service_->GetCurrentBrowser()->GetBrowserState();
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
index 56371f5..c8c89b3 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-007525822c0412a6bd0c1d65fbe58d3ba96fce12
\ No newline at end of file
+0114c336adb33325d148efd99aa0f643d53531b8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
index e897ab42..6d1f2b30 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-d2ff5c31c703178b4d77c016eb8955f172b4e977
\ No newline at end of file
+b1af96ab9f3895e1cda65b3bcbdec1b87a3de58b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
index 61ca384..2a0f867 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-5de3632f4616a649ee5d54f5045ce4fa67cf243e
\ No newline at end of file
+fdd19e13ce3b88db633c961ab1a2b464dad85e2b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
index 6595a8a..626e124 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-d38a9cd1e9045dc0a0118c76d312c10cadedd611
\ No newline at end of file
+0b06118a4acac41403c31f82eb1527a045b48d74
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
index 850d35b..3fdb2c52b 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-b2baad9993ddb7d625b42bbfdbfe9c611f853c3b
\ No newline at end of file
+f3c8ac6d8ce75243de294820aca33b7b22df885a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
index 29291508..9e1f8b8 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-62455b7671269cbcd94966da3547f93e102c0362
\ No newline at end of file
+e724729deb0d00af077a966470cfe985b4229256
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
index f8ec414..f21addff 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-b49d3ea1f889d93e4091f0fed83d596372b957a9
\ No newline at end of file
+41271b830dc00f96f8d72b3b0b34614306dbc066
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
index ef5fbf3..eac6ce47 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-d9365568cb99a51f25a79edd1a091f8ac32a1b95
\ No newline at end of file
+1e80febdcc5345a5ab8c0b6833d652ddbc581a57
\ No newline at end of file
diff --git a/ios/web/public/test/fakes/BUILD.gn b/ios/web/public/test/fakes/BUILD.gn
index 630721c..049e64d6 100644
--- a/ios/web/public/test/fakes/BUILD.gn
+++ b/ios/web/public/test/fakes/BUILD.gn
@@ -73,12 +73,7 @@
     "test_browser_state.h",
     "test_java_script_dialog_presenter.h",
     "test_java_script_dialog_presenter.mm",
-    "test_navigation_manager.h",
-    "test_web_client.h",
-    "test_web_state.h",
     "test_web_state_delegate.h",
     "test_web_state_delegate.mm",
-    "test_web_state_observer.h",
-    "test_web_state_observer_util.h",
   ]
 }
diff --git a/ios/web/public/test/fakes/test_navigation_manager.h b/ios/web/public/test/fakes/test_navigation_manager.h
deleted file mode 100644
index 82d684c..0000000
--- a/ios/web/public/test/fakes/test_navigation_manager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_NAVIGATION_MANAGER_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_NAVIGATION_MANAGER_H_
-
-#import "ios/web/public/test/fakes/fake_navigation_manager.h"
-
-// TODO(crbug.com/688063): Remove this file after updating all clients to import
-// fake_navigation_manager.h and use FakeNavigationManager class.
-
-namespace web {
-using TestNavigationManager = FakeNavigationManager;
-}
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_NAVIGATION_MANAGER_H_
diff --git a/ios/web/public/test/fakes/test_web_client.h b/ios/web/public/test/fakes/test_web_client.h
deleted file mode 100644
index 7b940e1..0000000
--- a/ios/web/public/test/fakes/test_web_client.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_CLIENT_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_CLIENT_H_
-
-#import "ios/web/public/test/fakes/fake_web_client.h"
-
-// TODO(crbug.com/688063): Remove this file after updating all clients to import
-// fake_web_client.h and use FakeWebClient class.
-
-namespace web {
-using TestWebClient = FakeWebClient;
-}
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_CLIENT_H_
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h
deleted file mode 100644
index b04995c..0000000
--- a/ios/web/public/test/fakes/test_web_state.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_H_
-
-#import "ios/web/public/test/fakes/fake_web_state.h"
-
-// TODO(crbug.com/688063): Remove this file after updating all clients to import
-// fake_web_state.h and use FakeWebState class.
-
-namespace web {
-using TestWebState = FakeWebState;
-}
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_H_
diff --git a/ios/web/public/test/fakes/test_web_state_observer.h b/ios/web/public/test/fakes/test_web_state_observer.h
deleted file mode 100644
index 709a31c2..0000000
--- a/ios/web/public/test/fakes/test_web_state_observer.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
-
-#include "ios/web/public/test/fakes/fake_web_state_observer.h"
-
-// TODO(crbug.com/688063): Remove this file after updating all clients to import
-// fake_web_state_observer.h and use FakeWebStateObserver class.
-
-namespace web {
-using TestWebStateObserver = FakeWebStateObserver;
-}
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
diff --git a/ios/web/public/test/fakes/test_web_state_observer_util.h b/ios/web/public/test/fakes/test_web_state_observer_util.h
deleted file mode 100644
index bf91a3c..0000000
--- a/ios/web/public/test/fakes/test_web_state_observer_util.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_UTIL_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_UTIL_H_
-
-#import "ios/web/public/test/fakes/fake_web_state_observer_util.h"
-
-// TODO(crbug.com/688063): Remove this file after updating all clients to import
-// fake_web_state_observer_util.h.
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_UTIL_H_
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
index 03ab168a..f571d83 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
@@ -415,8 +415,9 @@
   // change event (but not the opposite), so we must make sure both events
   // are processed in the correct order.
   if (buffer->IsLast()){
-    if (!resolution_change_cb_ && !flush_cb_)
-      ProcessEventQueue();
+    // Check that we don't have a resolution change event pending. If we do
+    // then this LAST buffer was related to it.
+    ProcessEventQueue();
 
     if (resolution_change_cb_) {
       std::move(resolution_change_cb_).Run();
@@ -429,6 +430,19 @@
   EnqueueOutputBuffers();
 }
 
+bool V4L2StatefulVideoDecoderBackend::SendStopCommand() {
+  struct v4l2_decoder_cmd cmd;
+  memset(&cmd, 0, sizeof(cmd));
+  cmd.cmd = V4L2_DEC_CMD_STOP;
+  if (device_->Ioctl(VIDIOC_DECODER_CMD, &cmd) != 0) {
+    LOG(ERROR) << "Failed to issue STOP command";
+    client_->OnBackendError();
+    return false;
+  }
+
+  return true;
+}
+
 bool V4L2StatefulVideoDecoderBackend::InitiateFlush(
     VideoDecoder::DecodeCB flush_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -452,16 +466,17 @@
   if (!has_pending_requests_)
     return CompleteFlush();
 
-  // Send the STOP command to the V4L2 device. The device will let us know
-  // that the flush is completed by sending us a CAPTURE buffer with the LAST
-  // flag set.
-  struct v4l2_decoder_cmd cmd;
-  memset(&cmd, 0, sizeof(cmd));
-  cmd.cmd = V4L2_DEC_CMD_STOP;
-  if (device_->Ioctl(VIDIOC_DECODER_CMD, &cmd) != 0) {
-    LOG(ERROR) << "Failed to issue STOP command";
-    client_->OnBackendError();
-    return false;
+  if (output_queue_->IsStreaming()) {
+    // If the CAPTURE queue is streaming, send the STOP command to the V4L2
+    // device. The device will let us know that the flush is completed by
+    // sending us a CAPTURE buffer with the LAST flag set.
+    return SendStopCommand();
+  } else {
+    // If the CAPTURE queue is not streaming, this means we received the flush
+    // request before the initial resolution has been established. The flush
+    // request will be processed in OnChangeResolutionDone(), when the CAPTURE
+    // queue starts streaming.
+    DVLOGF(2) << "Flush request to be processed after CAPTURE queue starts";
   }
 
   return true;
@@ -594,6 +609,16 @@
   // Enqueue all available output buffers now that they are allocated.
   EnqueueOutputBuffers();
 
+  // If we had a flush request pending before the initial resolution change,
+  // process it now.
+  if (flush_cb_) {
+    DVLOGF(2) << "Processing pending flush request...";
+
+    client_->InitiateFlush();
+    if (!SendStopCommand())
+      return;
+  }
+
   // Also try to progress on our work.
   DoDecodeWork();
 }
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
index a6cd687..b91230c 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
+++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
@@ -107,6 +107,7 @@
   // becomes available.
   scoped_refptr<VideoFrame> GetPoolVideoFrame();
 
+  bool SendStopCommand();
   bool InitiateFlush(VideoDecoder::DecodeCB flush_cb);
   bool CompleteFlush();
 
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index 0943bb8..a7f73e88 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -386,6 +386,18 @@
   uint8_t* pixels = static_cast<uint8_t*>(rgb_pixels) +
                     row_bytes * chunk_start * rows_per_chunk;
 
+  if (format == PIXEL_FORMAT_ARGB) {
+    DCHECK_LE(width, static_cast<int>(row_bytes));
+    const uint8_t* data = plane_meta[VideoFrame::kARGBPlane].data;
+    for (size_t i = 0; i < rows; i++) {
+      memcpy(pixels, data, width * 4);
+      pixels += row_bytes;
+      data += plane_meta[VideoFrame::kARGBPlane].stride;
+    }
+    done->Run();
+    return;
+  }
+
   // TODO(crbug.com/828599): This should default to BT.709 color space.
   SkYUVColorSpace color_space = kRec601_SkYUVColorSpace;
   video_frame->ColorSpace().ToSkYUVColorSpace(&color_space);
@@ -917,6 +929,7 @@
   if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
       !(media::IsYuvPlanar(video_frame->format()) ||
         video_frame->format() == media::PIXEL_FORMAT_Y16 ||
+        video_frame->format() == media::PIXEL_FORMAT_ARGB ||
         video_frame->HasTextures())) {
     cc::PaintFlags black_with_alpha_flags;
     black_with_alpha_flags.setAlpha(flags.getAlpha());
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index 5a36c9d..ea7c29d2 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -37,6 +37,8 @@
       "address_sorter.h",
       "context_host_resolver.cc",
       "context_host_resolver.h",
+      "dns_alias_utility.cc",
+      "dns_alias_utility.h",
       "dns_config.cc",
       "dns_config_service.cc",
       "dns_config_service.h",
@@ -390,6 +392,7 @@
   sources = [
     "address_info_unittest.cc",
     "context_host_resolver_unittest.cc",
+    "dns_alias_utility_unittest.cc",
     "dns_config_service_unittest.cc",
     "dns_hosts_unittest.cc",
     "dns_query_unittest.cc",
diff --git a/net/dns/context_host_resolver.cc b/net/dns/context_host_resolver.cc
index 5645b8f..f34bcc4 100644
--- a/net/dns/context_host_resolver.cc
+++ b/net/dns/context_host_resolver.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "base/check_op.h"
 #include "base/no_destructor.h"
@@ -150,6 +151,17 @@
     return inner_request_->GetHostnameResults();
   }
 
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override {
+    if (!inner_request_) {
+      static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+          nullopt_result;
+      return *nullopt_result;
+    }
+
+    return inner_request_->GetDnsAliasResults();
+  }
+
   net::ResolveErrorInfo GetResolveErrorInfo() const override {
     if (!inner_request_) {
       return resolve_error_info_;
diff --git a/net/dns/dns_alias_utility.cc b/net/dns/dns_alias_utility.cc
new file mode 100644
index 0000000..8c96c5f
--- /dev/null
+++ b/net/dns/dns_alias_utility.cc
@@ -0,0 +1,74 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/dns_alias_utility.h"
+
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "base/check.h"
+#include "net/base/url_util.h"
+#include "net/dns/public/dns_protocol.h"
+#include "url/url_canon.h"
+#include "url/url_canon_stdstring.h"
+
+namespace net {
+
+namespace {
+
+bool IsValidAliasWithCanonicalOutput(const std::string& alias,
+                                     std::string* out_canonicalized_alias) {
+  DCHECK(out_canonicalized_alias);
+
+  // Disallow empty hostnames, hostnames longer than
+  // `dns_protocol::kMaxCharNameLength` characters (with one extra character
+  // allowed for fully-qualified hostnames, i.e. hostnames ending with '.'),
+  // and "localhost".
+  if (alias.empty() || alias.size() > dns_protocol::kMaxCharNameLength + 1 ||
+      (alias.size() == dns_protocol::kMaxCharNameLength + 1 &&
+       alias.back() != '.') ||
+      HostStringIsLocalhost(alias)) {
+    return false;
+  }
+
+  url::StdStringCanonOutput output(out_canonicalized_alias);
+  url::CanonHostInfo host_info;
+  const char* alias_spec = alias.c_str();
+  url::Component host(0, alias.size());
+
+  url::CanonicalizeHostVerbose(alias_spec, host, &output, &host_info);
+  output.Complete();
+
+  return host_info.family == url::CanonHostInfo::Family::NEUTRAL;
+}
+
+}  // namespace
+
+namespace dns_alias_utility {
+
+std::vector<std::string> SanitizeDnsAliases(
+    const std::vector<std::string>& aliases) {
+  std::vector<std::string> sanitized_aliases;
+  std::unordered_set<std::string> aliases_seen;
+
+  for (const auto& alias : aliases) {
+    std::string canonicalized_alias;
+
+    if (IsValidAliasWithCanonicalOutput(alias, &canonicalized_alias)) {
+      // Skip adding any duplicate aliases.
+      if (aliases_seen.find(canonicalized_alias) != aliases_seen.end())
+        continue;
+
+      aliases_seen.insert(canonicalized_alias);
+      sanitized_aliases.push_back(std::move(canonicalized_alias));
+    }
+  }
+
+  return sanitized_aliases;
+}
+
+}  // namespace dns_alias_utility
+
+}  // namespace net
diff --git a/net/dns/dns_alias_utility.h b/net/dns/dns_alias_utility.h
new file mode 100644
index 0000000..236a69a
--- /dev/null
+++ b/net/dns/dns_alias_utility.h
@@ -0,0 +1,31 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DNS_DNS_ALIAS_UTILITY_H_
+#define NET_DNS_DNS_ALIAS_UTILITY_H_
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace dns_alias_utility {
+
+// Returns a sanitized list of canonicalized aliases (i.e. aliases that are
+// written as hostnames for canonical URLs). The list is stripped of
+// "localhost", IP addresses, duplicates, the empty string, strings longer
+// than `dns_protocol::kMaxCharNameLength` characters (with one extra
+// character allowed for fully-qualified hostnames, i.e. hostnames ending
+// with '.'), and any strings that fail to URL-canonicalize as hosts. The
+// remaining aliases are replaced with their canonicalized forms.
+NET_EXPORT_PRIVATE std::vector<std::string> SanitizeDnsAliases(
+    const std::vector<std::string>& aliases);
+
+}  // namespace dns_alias_utility
+
+}  // namespace net
+
+#endif  // NET_DNS_DNS_ALIAS_UTILITY_H_
diff --git a/net/dns/dns_alias_utility_unittest.cc b/net/dns/dns_alias_utility_unittest.cc
new file mode 100644
index 0000000..41f0f4d
--- /dev/null
+++ b/net/dns/dns_alias_utility_unittest.cc
@@ -0,0 +1,83 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/dns_alias_utility.h"
+
+#include <string>
+#include <vector>
+
+#include "net/dns/public/dns_protocol.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+TEST(DnsAliasUtilityTest, SanitizeDnsAliases) {
+  const struct {
+    const char* dns_alias;
+    const char* sanitized_dns_alias;
+  } kTestCases[] = {{"localhost", nullptr},
+                    {"1.2.3.4", nullptr},
+                    {"a.com", "a.com"},
+                    {"", nullptr},
+                    {"test", "test"},
+                    {"0", nullptr},
+                    {"[::1]", nullptr},
+                    {"::1", nullptr},
+                    {"-www.e.com", "-www.e.com"},
+                    {"alias.com", "alias.com"},
+                    {"s .de", "s%20.de"},
+                    {"www-1", "www-1"},
+                    {"2a", "2a"},
+                    {"a-", "a-"},
+                    {"b..net", "b..net"},
+                    {"a.com", nullptr},
+                    {"b_o.org", "b_o.org"},
+                    {"alias.com", nullptr},
+                    {"1..3.2", "1..3.2"},
+                    {"a,b,c", "a%2Cb%2Cc"},
+                    {"f/g", nullptr},
+                    {"www?", nullptr},
+                    {"[3a2:401f::1]", nullptr},
+                    {"0.0.1.2", nullptr},
+                    {"a.b.com", "a.b.com"},
+                    {"c.org", "c.org"},
+                    {"123.tld", "123.tld"},
+                    {"d-e.net", "d-e.net"},
+                    {"f__g", "f__g"},
+                    {"h", "h"}};
+
+  std::vector<std::string> aliases;
+  std::vector<std::string> expected_sanitized_aliases;
+
+  for (const auto& test : kTestCases) {
+    aliases.push_back(test.dns_alias);
+    if (test.sanitized_dns_alias)
+      expected_sanitized_aliases.push_back(test.sanitized_dns_alias);
+  }
+
+  std::vector<std::string> sanitized_aliases =
+      dns_alias_utility::SanitizeDnsAliases(aliases);
+  EXPECT_EQ(expected_sanitized_aliases, sanitized_aliases);
+
+  std::string long_unqualified_alias(dns_protocol::kMaxCharNameLength + 1, 'x');
+  std::string long_qualified_alias(dns_protocol::kMaxCharNameLength, 'x');
+  long_qualified_alias += ".";
+  std::vector<std::string> List_with_long_aliases(
+      {long_unqualified_alias, long_qualified_alias});
+
+  std::vector<std::string> sanitized_list_with_long_aliases =
+      dns_alias_utility::SanitizeDnsAliases(List_with_long_aliases);
+  EXPECT_THAT(sanitized_list_with_long_aliases,
+              testing::ElementsAre(long_qualified_alias));
+
+  std::vector<std::string> empty_aliases;
+  std::vector<std::string> sanitized_empty_aliases =
+      dns_alias_utility::SanitizeDnsAliases(empty_aliases);
+  EXPECT_TRUE(sanitized_empty_aliases.empty());
+}
+
+}  // namespace
+}  // namespace net
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc
index dec61ed..cc9ecc8c 100644
--- a/net/dns/host_resolver.cc
+++ b/net/dns/host_resolver.cc
@@ -4,7 +4,9 @@
 
 #include "net/dns/host_resolver.h"
 
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/check.h"
@@ -57,6 +59,13 @@
     return *nullopt_result;
   }
 
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override {
+    static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+        nullopt_result;
+    return *nullopt_result;
+  }
+
   ResolveErrorInfo GetResolveErrorInfo() const override {
     return ResolveErrorInfo(error_);
   }
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h
index 422bcacd..2173edbc 100644
--- a/net/dns/host_resolver.h
+++ b/net/dns/host_resolver.h
@@ -98,6 +98,17 @@
     virtual const base::Optional<std::vector<HostPortPair>>&
     GetHostnameResults() const = 0;
 
+    // Any DNS record aliases, such as CNAME aliases, found as a result of an
+    // address query. The alias chain order is preserved in reverse, from
+    // canonical name (i.e. address record name) through to query name. Should
+    // only be called after Start() signals completion, either by invoking the
+    // callback or by returning a result other than `ERR_IO_PENDING`. Returns a
+    // list of aliases that has been sanitized and canonicalized (as URL
+    // hostnames), and thus may differ from the results stored directly in the
+    // AddressList.
+    virtual const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+        const = 0;
+
     // Result of an experimental query. Meaning depends on the specific query
     // type, but each boolean value generally refers to a valid or invalid
     // record of the experimental type.
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index 3353998..760be32 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -22,9 +22,11 @@
 #include <cmath>
 #include <limits>
 #include <memory>
+#include <string>
 #include <tuple>
 #include <unordered_set>
 #include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/callback.h"
@@ -71,6 +73,7 @@
 #include "net/base/trace_constants.h"
 #include "net/base/url_util.h"
 #include "net/dns/address_sorter.h"
+#include "net/dns/dns_alias_utility.h"
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_reloader.h"
 #include "net/dns/dns_response.h"
@@ -571,6 +574,12 @@
     return results_ ? results_.value().hostnames() : *nullopt_result;
   }
 
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override {
+    DCHECK(complete_);
+    return sanitized_dns_alias_results_;
+  }
+
   const base::Optional<std::vector<bool>>& GetExperimentalResultsForTesting()
       const override {
     DCHECK(complete_);
@@ -679,6 +688,19 @@
 
   bool complete() const { return complete_; }
 
+  void SanitizeDnsAliasResults() {
+    // If there are no address results, if there are no aliases, or if there
+    // are already sanitized alias results, there is nothing to do.
+    if (!results_ || !results_.value().addresses() ||
+        results_.value().addresses()->dns_aliases().empty() ||
+        sanitized_dns_alias_results_) {
+      return;
+    }
+
+    sanitized_dns_alias_results_ = dns_alias_utility::SanitizeDnsAliases(
+        results_.value().addresses()->dns_aliases());
+  }
+
  private:
   // Logging and metrics for when a request has just been started.
   void LogStartRequest() {
@@ -745,6 +767,7 @@
   bool complete_;
   base::Optional<HostCache::Entry> results_;
   base::Optional<HostCache::EntryStaleness> stale_info_;
+  base::Optional<std::vector<std::string>> sanitized_dns_alias_results_;
   ResolveErrorInfo error_info_;
 
   const base::TickClock* const tick_clock_;
@@ -2372,6 +2395,11 @@
       if (results.error() == OK && !req->parameters().is_speculative) {
         req->set_results(
             results.CopyWithDefaultPort(req->request_host().port()));
+
+        // TODO(cammie): Move the sanitization deeper, possibly in
+        // HttpCache::Entry::SetResult(AddressList addresses), so that it
+        // doesn't happen on a per-request basis.
+        req->SanitizeDnsAliasResults();
       }
       req->OnJobCompleted(
           this, results.error(),
@@ -2766,6 +2794,9 @@
     if (results.error() == OK && !request->parameters().is_speculative) {
       request->set_results(
           results.CopyWithDefaultPort(request->request_host().port()));
+
+      // TODO(cammie): Sanitize before adding to the cache instead.
+      request->SanitizeDnsAliasResults();
     }
     if (stale_info && !request->parameters().is_speculative)
       request->set_stale_info(std::move(stale_info).value());
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index 6de0929..8dc9641 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -175,7 +175,10 @@
                HostResolverFlags flags = 0,
                const std::string& canonical_name = "") {
     AddressList result;
-    int rv = ParseAddressList(ip_list, canonical_name, &result);
+    std::vector<std::string> dns_aliases;
+    if (canonical_name != "")
+      dns_aliases = {canonical_name};
+    int rv = ParseAddressList(ip_list, dns_aliases, &result);
     DCHECK_EQ(OK, rv);
     AddRule(hostname, family, result, flags);
   }
@@ -185,7 +188,10 @@
                              HostResolverFlags flags = 0,
                              const std::string& canonical_name = "") {
     AddressList result;
-    int rv = ParseAddressList(ip_list, canonical_name, &result);
+    std::vector<std::string> dns_aliases;
+    if (canonical_name != "")
+      dns_aliases = {canonical_name};
+    int rv = ParseAddressList(ip_list, dns_aliases, &result);
     DCHECK_EQ(OK, rv);
     AddRule(hostname, ADDRESS_FAMILY_UNSPECIFIED, result, flags);
     AddRule(hostname, ADDRESS_FAMILY_IPV4, result, flags);
@@ -212,7 +218,7 @@
     --num_slots_available_;
     --num_requests_waiting_;
     if (rules_.empty()) {
-      int rv = ParseAddressList("127.0.0.1", std::string(), addrlist);
+      int rv = ParseAddressList("127.0.0.1", {} /* dns_aliases */, addrlist);
       DCHECK_EQ(OK, rv);
       return OK;
     }
@@ -747,6 +753,24 @@
               testing::ElementsAre(CreateExpected("::5", 80)));
 }
 
+TEST_F(HostResolverManagerTest, DnsQueryWithoutAliases) {
+  proc_->AddRule("host", ADDRESS_FAMILY_IPV4, "192.168.1.20");
+
+  HostResolver::ResolveHostParameters parameters;
+
+  parameters.dns_query_type = DnsQueryType::A;
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
+      parameters, resolve_context_.get(), resolve_context_->host_cache()));
+
+  proc_->SignalMultiple(1u);
+
+  EXPECT_THAT(response.result_error(), IsOk());
+  EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(),
+              testing::ElementsAre(CreateExpected("192.168.1.20", 80)));
+  EXPECT_FALSE(response.request()->GetDnsAliasResults());
+}
+
 TEST_F(HostResolverManagerTest, LocalhostIPV4IPV6Lookup) {
   HostResolver::ResolveHostParameters parameters;
 
@@ -4532,6 +4556,7 @@
   EXPECT_THAT(response_ipv4.result_error(), IsOk());
   EXPECT_THAT(response_ipv4.request()->GetAddressResults().value().endpoints(),
               testing::ElementsAre(CreateExpected("127.0.0.1", 80)));
+  EXPECT_FALSE(response_ipv4.request()->GetDnsAliasResults());
 
   ResolveHostResponseHelper response_ipv6(resolver_->CreateRequest(
       HostPortPair("nx_ipv6", 80), NetworkIsolationKey(), NetLogWithSource(),
@@ -4539,6 +4564,7 @@
   EXPECT_THAT(response_ipv6.result_error(), IsOk());
   EXPECT_THAT(response_ipv6.request()->GetAddressResults().value().endpoints(),
               testing::ElementsAre(CreateExpected("::1", 80)));
+  EXPECT_FALSE(response_ipv6.request()->GetDnsAliasResults());
 
   ResolveHostResponseHelper response_both(resolver_->CreateRequest(
       HostPortPair("nx_both", 80), NetworkIsolationKey(), NetLogWithSource(),
@@ -4547,6 +4573,7 @@
   EXPECT_THAT(response_both.request()->GetAddressResults().value().endpoints(),
               testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80),
                                             CreateExpected("::1", 80)));
+  EXPECT_FALSE(response_both.request()->GetDnsAliasResults());
 
   // Requests with specified DNS query type.
   HostResolver::ResolveHostParameters parameters;
@@ -4561,6 +4588,7 @@
                   .value()
                   .endpoints(),
               testing::ElementsAre(CreateExpected("127.0.0.1", 80)));
+  EXPECT_FALSE(response_specified_ipv4.request()->GetDnsAliasResults());
 
   parameters.dns_query_type = DnsQueryType::AAAA;
   ResolveHostResponseHelper response_specified_ipv6(resolver_->CreateRequest(
@@ -4572,6 +4600,7 @@
                   .value()
                   .endpoints(),
               testing::ElementsAre(CreateExpected("::1", 80)));
+  EXPECT_FALSE(response_specified_ipv6.request()->GetDnsAliasResults());
 
   // Request with upper case.
   ResolveHostResponseHelper response_upper(resolver_->CreateRequest(
@@ -4580,6 +4609,7 @@
   EXPECT_THAT(response_upper.result_error(), IsOk());
   EXPECT_THAT(response_upper.request()->GetAddressResults().value().endpoints(),
               testing::ElementsAre(CreateExpected("127.0.0.1", 80)));
+  EXPECT_FALSE(response_upper.request()->GetDnsAliasResults());
 }
 
 TEST_F(HostResolverManagerDnsTest, SkipHostsWithUpcomingProcTask) {
@@ -6867,7 +6897,6 @@
   DnsResponse expected_A_response = BuildTestDnsResponse(
       "first.test", dns_protocol::kTypeA,
       {BuildTestAddressRecord("fourth.test", IPAddress::IPv4Localhost()),
-
        BuildTestCnameRecord("third.test", "fourth.test"),
        BuildTestCnameRecord("second.test", "third.test"),
        BuildTestCnameRecord("first.test", "second.test")});
@@ -6903,6 +6932,84 @@
   EXPECT_THAT(response.request()->GetAddressResults().value().dns_aliases(),
               testing::ElementsAre("fourth.test", "third.test", "second.test",
                                    "first.test"));
+
+  EXPECT_THAT(response.request()->GetDnsAliasResults(),
+              testing::Optional(testing::ElementsAre(
+                  "fourth.test", "third.test", "second.test", "first.test")));
+}
+
+TEST_F(HostResolverManagerDnsTest, DnsAliasesAreSanitized) {
+  MockDnsClientRuleList rules;
+
+  DnsResponse expected_A_response = BuildTestDnsResponse(
+      "host.test", dns_protocol::kTypeA,
+      {BuildTestAddressRecord("localhost", IPAddress::IPv4Localhost()),
+       BuildTestCnameRecord("host.test", "localhost")});
+
+  AddDnsRule(&rules, "host.test", dns_protocol::kTypeA,
+             std::move(expected_A_response), false /* delay */);
+
+  DnsResponse expected_AAAA_response = BuildTestDnsResponse(
+      "host.test", dns_protocol::kTypeAAAA,
+      {BuildTestAddressRecord("localhost", IPAddress::IPv6Localhost()),
+       BuildTestCnameRecord("host.test", "localhost")});
+
+  AddDnsRule(&rules, "host.test", dns_protocol::kTypeAAAA,
+             std::move(expected_AAAA_response), false /* delay */);
+
+  CreateResolver();
+  UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
+  set_allow_fallback_to_proctask(false);
+  HostResolver::ResolveHostParameters params;
+  params.include_canonical_name = true;
+  params.source = HostResolverSource::DNS;
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("host.test", 80), NetworkIsolationKey(), NetLogWithSource(),
+      params, resolve_context_.get(), resolve_context_->host_cache()));
+
+  // Verify that, while the AddressResults contain the full unsanitized alias
+  // list (which has "localhost" has first element and canonical name i.e.
+  // address record name), the call to ResolveHostRequest::GetDnsAliasResults
+  // returns a sanitized list.
+  ASSERT_THAT(response.result_error(), IsOk());
+  ASSERT_TRUE(response.request()->GetAddressResults());
+  EXPECT_EQ(response.request()->GetAddressResults().value().GetCanonicalName(),
+            "localhost");
+  EXPECT_THAT(response.request()->GetAddressResults().value().dns_aliases(),
+              testing::ElementsAre("localhost", "host.test"));
+  EXPECT_THAT(response.request()->GetDnsAliasResults(),
+              testing::Optional(testing::ElementsAre("host.test")));
+}
+
+TEST_F(HostResolverManagerDnsTest, NoAdditionalDnsAliases) {
+  MockDnsClientRuleList rules;
+
+  AddDnsRule(&rules, "first.test", dns_protocol::kTypeA,
+             IPAddress::IPv4Localhost(), false /* delay */);
+
+  AddDnsRule(&rules, "first.test", dns_protocol::kTypeAAAA,
+             IPAddress::IPv6Localhost(), false /* delay */);
+
+  CreateResolver();
+  UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
+  set_allow_fallback_to_proctask(false);
+  HostResolver::ResolveHostParameters params;
+  params.include_canonical_name = true;
+  params.source = HostResolverSource::DNS;
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("first.test", 80), NetworkIsolationKey(), NetLogWithSource(),
+      params, resolve_context_.get(), resolve_context_->host_cache()));
+
+  ASSERT_THAT(response.result_error(), IsOk());
+  ASSERT_TRUE(response.request()->GetAddressResults());
+  EXPECT_EQ(response.request()->GetAddressResults().value().GetCanonicalName(),
+            "first.test");
+  EXPECT_THAT(response.request()->GetAddressResults().value().dns_aliases(),
+              testing::ElementsAre("first.test"));
+  EXPECT_THAT(response.request()->GetDnsAliasResults(),
+              testing::Optional(testing::ElementsAre("first.test")));
 }
 
 TEST_F(HostResolverManagerDnsTest, SortsAndDeduplicatesAddresses) {
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index de9e445..af9c60a 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -4,6 +4,7 @@
 
 #include "net/dns/mock_host_resolver.h"
 
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -28,6 +29,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
+#include "net/dns/dns_alias_utility.h"
 #include "net/dns/host_cache.h"
 #include "net/dns/public/resolve_error_info.h"
 #include "net/url_request/url_request_context.h"
@@ -48,11 +50,10 @@
 }  // namespace
 
 int ParseAddressList(const std::string& host_list,
-                     const std::string& canonical_name,
+                     const std::vector<std::string>& dns_aliases,
                      AddressList* addrlist) {
   *addrlist = AddressList();
-  std::vector<std::string> aliases({canonical_name});
-  addrlist->SetDnsAliases(std::move(aliases));
+  addrlist->SetDnsAliases(dns_aliases);
   for (const base::StringPiece& address : base::SplitStringPiece(
            host_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
     IPAddress ip_address;
@@ -140,6 +141,12 @@
     return *nullopt_result;
   }
 
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override {
+    DCHECK(complete_);
+    return sanitized_dns_alias_results_;
+  }
+
   net::ResolveErrorInfo GetResolveErrorInfo() const override {
     DCHECK(complete_);
     return resolve_error_info_;
@@ -161,9 +168,8 @@
     resolve_error_info_ = ResolveErrorInfo(error);
   }
 
-  void set_address_results(
-      const AddressList& address_results,
-      base::Optional<HostCache::EntryStaleness> staleness) {
+  void SetAddressResults(const AddressList& address_results,
+                         base::Optional<HostCache::EntryStaleness> staleness) {
     // Should only be called at most once and before request is marked
     // completed.
     DCHECK(!complete_);
@@ -171,6 +177,8 @@
     DCHECK(!parameters_.is_speculative);
 
     address_results_ = address_results;
+    sanitized_dns_alias_results_ =
+        dns_alias_utility::SanitizeDnsAliases(address_results_->dns_aliases());
     staleness_ = std::move(staleness);
   }
 
@@ -221,6 +229,7 @@
   int host_resolver_flags_;
 
   base::Optional<AddressList> address_results_;
+  base::Optional<std::vector<std::string>> sanitized_dns_alias_results_;
   base::Optional<HostCache::EntryStaleness> staleness_;
   ResolveErrorInfo resolve_error_info_;
 
@@ -438,7 +447,7 @@
       req->host_resolver_flags(), req->parameters().source, &addresses);
   req->SetError(error);
   if (error == OK && !req->parameters().is_speculative)
-    req->set_address_results(addresses, base::nullopt);
+    req->SetAddressResults(addresses, base::nullopt);
   req->OnAsyncCompleted(id, SquashErrorCode(error));
 }
 
@@ -561,7 +570,7 @@
 
   request->SetError(rv);
   if (rv == OK && !request->parameters().is_speculative)
-    request->set_address_results(addresses, std::move(stale_info));
+    request->SetAddressResults(addresses, std::move(stale_info));
   if (rv != ERR_DNS_CACHE_MISS ||
       request->parameters().source == HostResolverSource::LOCAL_ONLY) {
     return SquashErrorCode(rv);
@@ -583,7 +592,7 @@
 
     request->SetError(rv);
     if (rv == OK && !request->parameters().is_speculative)
-      request->set_address_results(addresses, base::nullopt);
+      request->SetAddressResults(addresses, base::nullopt);
     return SquashErrorCode(rv);
   }
 
@@ -754,18 +763,22 @@
                                       AddressFamily address_family,
                                       HostResolverFlags host_resolver_flags,
                                       const std::string& replacement,
-                                      const std::string& canonical_name,
+                                      std::vector<std::string> dns_aliases,
                                       int latency_ms)
     : resolver_type(resolver_type),
       host_pattern(host_pattern),
       address_family(address_family),
       host_resolver_flags(host_resolver_flags),
       replacement(replacement),
-      canonical_name(canonical_name),
-      latency_ms(latency_ms) {}
+      dns_aliases(std::move(dns_aliases)),
+      latency_ms(latency_ms) {
+  DCHECK(dns_aliases != std::vector<std::string>({""}));
+}
 
 RuleBasedHostResolverProc::Rule::Rule(const Rule& other) = default;
 
+RuleBasedHostResolverProc::Rule::~Rule() = default;
+
 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous)
     : HostResolverProc(previous), modifications_allowed_(true) {}
 
@@ -783,7 +796,7 @@
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
-            replacement, std::string(), 0);
+            replacement, {} /* dns_aliases */, 0);
   AddRuleInternal(rule);
 }
 
@@ -793,8 +806,11 @@
     HostResolverFlags flags,
     const std::string& canonical_name) {
   DCHECK(!replacement.empty());
+  std::vector<std::string> aliases;
+  if (!canonical_name.empty())
+    aliases.emplace_back(canonical_name);
   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
-            flags, replacement, canonical_name, 0);
+            flags, replacement, std::move(aliases), 0);
   AddRuleInternal(rule);
 }
 
@@ -808,11 +824,34 @@
   DCHECK(!ip_address.AssignFromIPLiteral(host_pattern));
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
-  if (!canonical_name.empty())
+  std::vector<std::string> aliases;
+  if (!canonical_name.empty()) {
+    flags |= HOST_RESOLVER_CANONNAME;
+    aliases.emplace_back(canonical_name);
+  }
+
+  Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
+            ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, std::move(aliases),
+            0);
+  AddRuleInternal(rule);
+}
+
+void RuleBasedHostResolverProc::AddIPLiteralRuleWithDnsAliases(
+    const std::string& host_pattern,
+    const std::string& ip_literal,
+    std::vector<std::string> dns_aliases) {
+  // Literals are always resolved to themselves by HostResolverImpl,
+  // consequently we do not support remapping them.
+  IPAddress ip_address;
+  DCHECK(!ip_address.AssignFromIPLiteral(host_pattern));
+  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
+                            HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
+  if (!dns_aliases.empty())
     flags |= HOST_RESOLVER_CANONNAME;
 
   Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
-            ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name, 0);
+            ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal,
+            std::move(dns_aliases), 0);
   AddRuleInternal(rule);
 }
 
@@ -824,7 +863,7 @@
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
-            flags, replacement, std::string(), latency_ms);
+            flags, replacement, {} /* dns_aliases */, latency_ms);
   AddRuleInternal(rule);
 }
 
@@ -833,7 +872,7 @@
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
-            flags, std::string(), std::string(), 0);
+            flags, std::string(), {} /* dns_aliases */, 0);
   AddRuleInternal(rule);
 }
 
@@ -842,7 +881,7 @@
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
-            flags, std::string(), std::string(), 0);
+            flags, std::string(), {} /* dns_aliases */, 0);
   AddRuleInternal(rule);
 }
 
@@ -851,7 +890,8 @@
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
                             HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   Rule rule(Rule::kResolverTypeFailTimeout, host_pattern,
-            ADDRESS_FAMILY_UNSPECIFIED, flags, std::string(), std::string(), 0);
+            ADDRESS_FAMILY_UNSPECIFIED, flags, std::string(),
+            {} /* dns_aliases */, 0);
   AddRuleInternal(rule);
 }
 
@@ -922,10 +962,12 @@
                                         os_error);
         case Rule::kResolverTypeIPLiteral: {
           AddressList raw_addr_list;
-          int result = ParseAddressList(
-              effective_host,
-              !r->canonical_name.empty() ? r->canonical_name : host,
-              &raw_addr_list);
+          std::vector<std::string> aliases;
+          aliases = (!r->dns_aliases.empty())
+                        ? r->dns_aliases
+                        : std::vector<std::string>({host});
+          int result =
+              ParseAddressList(effective_host, aliases, &raw_addr_list);
           // Filter out addresses with the wrong family.
           *addrlist = AddressList();
           for (const auto& address : raw_addr_list) {
@@ -934,8 +976,7 @@
               addrlist->push_back(address);
             }
           }
-          std::vector<std::string> aliases({raw_addr_list.GetCanonicalName()});
-          addrlist->SetDnsAliases(std::move(aliases));
+          addrlist->SetDnsAliases(raw_addr_list.dns_aliases());
 
           if (result == OK && addrlist->empty())
             return ERR_NAME_NOT_RESOLVED;
@@ -1024,6 +1065,11 @@
     IMMEDIATE_CRASH();
   }
 
+  const base::Optional<std::vector<std::string>>& GetDnsAliasResults()
+      const override {
+    IMMEDIATE_CRASH();
+  }
+
   net::ResolveErrorInfo GetResolveErrorInfo() const override {
     IMMEDIATE_CRASH();
   }
diff --git a/net/dns/mock_host_resolver.h b/net/dns/mock_host_resolver.h
index 24a9eb8..1acec5e 100644
--- a/net/dns/mock_host_resolver.h
+++ b/net/dns/mock_host_resolver.h
@@ -39,12 +39,14 @@
 class RuleBasedHostResolverProc;
 class URLRequestContext;
 
-// Fills |*addrlist| with a socket address for |host_list| which should be a
+// Fills `*addrlist` with a socket address for `host_list` which should be a
 // comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets.
-// If |canonical_name| is non-empty it is used as the DNS canonical name for
-// the host. Returns OK on success, ERR_UNEXPECTED otherwise.
+// If `dns_aliases` is non-empty, its first entry is considered the DNS
+// canonical name (i.e. address record name) for the host, and the alias
+// chain is listed in reverse order through to the last entry, the query name.
+// Returns OK on success, ERR_UNEXPECTED otherwise.
 int ParseAddressList(const std::string& host_list,
-                     const std::string& canonical_name,
+                     const std::vector<std::string>& dns_aliases,
                      AddressList* addrlist);
 
 // In most cases, it is important that unit tests avoid relying on making actual
@@ -390,6 +392,17 @@
                         const std::string& ip_literal,
                         const std::string& canonical_name);
 
+  // Same as AddIPLiteralRule, but with a parameter allowing multiple DNS
+  // aliases, such as CNAME aliases, instead of only the canonical name. While
+  // a simulation using HostResolverProc to obtain more than a single DNS alias
+  // is currently unrealistic, this capability is useful for clients of
+  // MockHostResolver who need to be able to obtain aliases and can be
+  // agnostic about how the host resolution took place, as the alternative,
+  // MockDnsClient, is not currently hooked up to MockHostResolver.
+  void AddIPLiteralRuleWithDnsAliases(const std::string& host_pattern,
+                                      const std::string& ip_literal,
+                                      std::vector<std::string> dns_aliases);
+
   void AddRuleWithLatency(const std::string& host_pattern,
                           const std::string& replacement,
                           int latency_ms);
@@ -434,16 +447,17 @@
          AddressFamily address_family,
          HostResolverFlags host_resolver_flags,
          const std::string& replacement,
-         const std::string& canonical_name,
+         std::vector<std::string> dns_aliases,
          int latency_ms);
     Rule(const Rule& other);
+    ~Rule();
 
     ResolverType resolver_type;
     std::string host_pattern;
     AddressFamily address_family;
     HostResolverFlags host_resolver_flags;
     std::string replacement;
-    std::string canonical_name;
+    std::vector<std::string> dns_aliases;
     int latency_ms;  // In milliseconds.
   };
 
diff --git a/net/dns/public/dns_protocol.h b/net/dns/public/dns_protocol.h
index 4c7bb93..01ccc0c 100644
--- a/net/dns/public/dns_protocol.h
+++ b/net/dns/public/dns_protocol.h
@@ -110,10 +110,17 @@
 static const uint16_t kMDnsClassMask = 0x7FFF;
 
 // RFC 1035, section 3.1: To simplify implementations, the total length of
-// a domain name (i.e., label octets and label length octets) is restricted
-// to 255 octets or less.
+// a domain name in wire form (i.e., label octets and label length octets) is
+// restricted to 255 octets or less.
 static const int kMaxNameLength = 255;
 
+// The maximum number of ASCII characters allowed in a domain in dotted form,
+// derived from `kMaxNameLength` above by subtracting two from the count to
+// correspond to the first and last byte, which, except in the case of a
+// fully-qualified domain name (where the last byte encodes '.'), are not
+// available to encode characters.
+static const uint16_t kMaxCharNameLength = 253;
+
 // RFC 1035, section 2.3.4: labels 63 octets or less.
 // Section 3.1: Each label is represented as a one octet length field followed
 // by that number of octets.
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index 463f50e..e4d4f61 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -797,7 +797,7 @@
 
 int HttpProxyConnectJob::HandleConnectResult(int result) {
   if (result == OK)
-    SetSocket(std::move(transport_socket_));
+    SetSocket(std::move(transport_socket_), base::nullopt /* dns_aliases */);
   return result;
 }
 
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 395322f0..6abad01 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -287,6 +287,9 @@
                                           io_mode == SYNCHRONOUS);
     EXPECT_FALSE(proxy_delegate_->on_before_tunnel_request_called());
 
+    // Proxies should not set any DNS aliases.
+    EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
+
     bool is_secure_proxy = GetParam() == HTTPS || GetParam() == SPDY;
     histogram_tester.ExpectTotalCount(
         "Net.HttpProxy.ConnectLatency.Insecure.Success",
@@ -445,6 +448,9 @@
   // Finish the read, and run the job until it's complete.
   sequenced_data->Resume();
   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
+
+  // Proxies should not set any DNS aliases.
+  EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
 }
 
 TEST_P(HttpProxyConnectJobTest, ProxyDelegateExtraHeaders) {
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index bcdbd8e..4566433 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -470,7 +470,7 @@
         return ERR_IO_PENDING;
       default:
         NOTREACHED();
-        SetSocket(std::unique_ptr<StreamSocket>());
+        SetSocket(std::unique_ptr<StreamSocket>(), base::nullopt);
         return ERR_FAILED;
     }
   }
@@ -481,14 +481,16 @@
     int result = OK;
     has_established_connection_ = true;
     if (succeed) {
-      SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
+      SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
+                base::nullopt);
       socket()->Connect(CompletionOnceCallback());
     } else if (cert_error) {
-      SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
+      SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
+                base::nullopt);
       result = ERR_CERT_COMMON_NAME_INVALID;
     } else {
       result = ERR_CONNECTION_FAILED;
-      SetSocket(std::unique_ptr<StreamSocket>());
+      SetSocket(std::unique_ptr<StreamSocket>(), base::nullopt);
     }
 
     if (was_async)
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index ffb9031..e81a16d 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -225,9 +225,14 @@
   return nullptr;
 }
 
-void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) {
-  if (socket)
+void ConnectJob::SetSocket(
+    std::unique_ptr<StreamSocket> socket,
+    base::Optional<std::vector<std::string>> dns_aliases) {
+  if (socket) {
     net_log().AddEvent(NetLogEventType::CONNECT_JOB_SET_SOCKET);
+    if (dns_aliases)
+      socket->SetDnsAliases(std::move(dns_aliases.value()));
+  }
   socket_ = std::move(socket);
 }
 
@@ -271,7 +276,7 @@
 
 void ConnectJob::OnTimeout() {
   // Make sure the socket is NULL before calling into |delegate|.
-  SetSocket(nullptr);
+  SetSocket(nullptr, base::nullopt /* dns_aliases */);
 
   OnTimedOutInternal();
 
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index 0235808..5886eac 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
@@ -284,7 +285,8 @@
     return common_connect_job_params_;
   }
 
-  void SetSocket(std::unique_ptr<StreamSocket> socket);
+  void SetSocket(std::unique_ptr<StreamSocket> socket,
+                 base::Optional<std::vector<std::string>> dns_aliases);
   void NotifyDelegateOfCompletion(int rv);
   void NotifyDelegateOfProxyAuth(const HttpResponseInfo& response,
                                  HttpAuthController* auth_controller,
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index 4f1c8e9..5ec9c06 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -68,7 +68,8 @@
   }
   int ConnectInternal() override {
     SetSocket(std::unique_ptr<StreamSocket>(new MockTCPClientSocket(
-        AddressList(), net_log().net_log(), &socket_data_provider_)));
+                  AddressList(), net_log().net_log(), &socket_data_provider_)),
+              base::nullopt /* dns_aliases */);
     return socket()->Connect(base::BindOnce(
         &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
   }
diff --git a/net/socket/socket.cc b/net/socket/socket.cc
index 09d619e..b5b79e8 100644
--- a/net/socket/socket.cc
+++ b/net/socket/socket.cc
@@ -8,6 +8,10 @@
 
 namespace net {
 
+Socket::Socket() = default;
+
+Socket::~Socket() = default;
+
 int Socket::ReadIfReady(IOBuffer* buf,
                         int buf_len,
                         CompletionOnceCallback callback) {
@@ -18,4 +22,19 @@
   return ERR_READ_IF_READY_NOT_IMPLEMENTED;
 }
 
+void Socket::SetDnsAliases(std::vector<std::string> aliases) {
+  if (aliases == std::vector<std::string>({""})) {
+    // Reset field to empty vector. Necessary because some tests and other
+    // inputs still use a trivial canonical name of std::string().
+    dns_aliases_ = std::vector<std::string>();
+    return;
+  }
+
+  dns_aliases_ = std::move(aliases);
+}
+
+const std::vector<std::string>& Socket::GetDnsAliases() const {
+  return dns_aliases_;
+}
+
 }  // namespace net
diff --git a/net/socket/socket.h b/net/socket/socket.h
index d0b91b7..beecf2325 100644
--- a/net/socket/socket.h
+++ b/net/socket/socket.h
@@ -7,6 +7,9 @@
 
 #include <stdint.h>
 
+#include <string>
+#include <vector>
+
 #include "net/base/completion_once_callback.h"
 #include "net/base/net_export.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -18,7 +21,8 @@
 // Represents a read/write socket.
 class NET_EXPORT Socket {
  public:
-  virtual ~Socket() {}
+  Socket();
+  virtual ~Socket();
 
   // Reads data, up to |buf_len| bytes, from the socket.  The number of bytes
   // read is returned, or an error is returned upon failure.
@@ -81,6 +85,18 @@
   // Note: changing this value can affect the TCP window size on some platforms.
   // Returns a net error code.
   virtual int SetSendBufferSize(int32_t size) = 0;
+
+  // DNS aliases must be stored in sockets in case of socket reuse.
+  // Sets the field storing the aliases. Empty if using a proxy.
+  // The alias chain order is preserved in reverse, from canonical name (i.e.
+  // address record name) through to query name.
+  virtual void SetDnsAliases(std::vector<std::string> aliases);
+
+  // Retrieves any DNS aliases for the socket's remote endpoint.
+  virtual const std::vector<std::string>& GetDnsAliases() const;
+
+ protected:
+  std::vector<std::string> dns_aliases_;
 };
 
 }  // namespace net
diff --git a/net/socket/socks_connect_job.cc b/net/socket/socks_connect_job.cc
index 6d0e6889..93c02b3 100644
--- a/net/socket/socks_connect_job.cc
+++ b/net/socket/socks_connect_job.cc
@@ -190,7 +190,7 @@
     return result;
   }
 
-  SetSocket(std::move(socket_));
+  SetSocket(std::move(socket_), base::nullopt /* dns_aliases */);
   return result;
 }
 
diff --git a/net/socket/socks_connect_job_unittest.cc b/net/socket/socks_connect_job_unittest.cc
index 0167484..f7614b0 100644
--- a/net/socket/socks_connect_job_unittest.cc
+++ b/net/socket/socks_connect_job_unittest.cc
@@ -196,6 +196,9 @@
       test_delegate.StartJobExpectingResult(
           &socks_connect_job, OK,
           host_resolution_synchronous && read_and_writes_synchronous);
+
+      // Proxies should not set any DNS aliases.
+      EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
     }
   }
 }
@@ -233,6 +236,9 @@
       test_delegate.StartJobExpectingResult(
           &socks_connect_job, OK,
           host_resolution_synchronous && read_and_writes_synchronous);
+
+      // Proxies should not set any DNS aliases.
+      EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
     }
   }
 }
diff --git a/net/socket/ssl_connect_job.cc b/net/socket/ssl_connect_job.cc
index fe29b37..0466614 100644
--- a/net/socket/ssl_connect_job.cc
+++ b/net/socket/ssl_connect_job.cc
@@ -280,6 +280,7 @@
     next_state_ = STATE_SSL_CONNECT;
     nested_socket_ = nested_connect_job_->PassSocket();
     nested_socket_->GetPeerAddress(&server_address_);
+    dns_aliases_ = nested_socket_->GetDnsAliases();
   }
 
   return result;
@@ -497,7 +498,7 @@
   }
 
   if (result == OK || IsCertificateError(result)) {
-    SetSocket(std::move(ssl_socket_));
+    SetSocket(std::move(ssl_socket_), std::move(dns_aliases_));
   } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
     ssl_cert_request_info_ = base::MakeRefCounted<SSLCertRequestInfo>();
     ssl_socket_->GetSSLCertRequestInfo(ssl_cert_request_info_.get());
diff --git a/net/socket/ssl_connect_job.h b/net/socket/ssl_connect_job.h
index 177d85f..f5ea9b9 100644
--- a/net/socket/ssl_connect_job.h
+++ b/net/socket/ssl_connect_job.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -180,6 +181,13 @@
   // through an HTTPS CONNECT request or a SOCKS proxy).
   IPEndPoint server_address_;
 
+  // Any DNS aliases for the remote endpoint. The alias chain order is
+  // preserved in reverse, from canonical name (i.e. address record name)
+  // through to query name. Stored because `nested_connect_job_` has a
+  // limited lifetime and the aliases can no longer be retrieved from there by
+  // by the time that the aliases are needed to be passed in SetSocket.
+  std::vector<std::string> dns_aliases_;
+
   DISALLOW_COPY_AND_ASSIGN(SSLConnectJob);
 };
 
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index 9ef6e6e..ac17b0c 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -792,6 +792,9 @@
     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
                                           io_mode == SYNCHRONOUS);
     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
+
+    // Proxies should not set any DNS aliases.
+    EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
   }
 }
 
@@ -966,6 +969,9 @@
   test_delegate.RunAuthCallback();
 
   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
+
+  // Proxies should not set any DNS aliases.
+  EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
 }
 
 TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
@@ -995,6 +1001,7 @@
     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
                                           io_mode == SYNCHRONOUS);
     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
+    EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
   }
 }
 
@@ -1218,5 +1225,59 @@
   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
 }
 
+TEST_F(SSLConnectJobTest, DnsAliases) {
+  host_resolver_.set_synchronous_mode(true);
+
+  // Resolve an AddressList with DNS aliases.
+  std::vector<std::string> aliases({"alias1", "alias2", "host"});
+  host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
+                                                         std::move(aliases));
+  StaticSocketDataProvider data;
+  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl);
+  TestConnectJobDelegate test_delegate;
+
+  std::unique_ptr<ConnectJob> ssl_connect_job =
+      CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
+
+  EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
+
+  base::RunLoop().RunUntilIdle();
+
+  // Verify that the elements of the alias list are those from the
+  // parameter vector.
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre("alias1", "alias2", "host"));
+}
+
+TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
+  host_resolver_.set_synchronous_mode(true);
+
+  // Resolve an AddressList without additional DNS aliases. (The parameter
+  // is an empty vector.)
+  std::vector<std::string> aliases;
+  host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
+                                                         std::move(aliases));
+  StaticSocketDataProvider data;
+  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl);
+  TestConnectJobDelegate test_delegate;
+
+  std::unique_ptr<ConnectJob> ssl_connect_job =
+      CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
+
+  EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
+
+  base::RunLoop().RunUntilIdle();
+
+  // Verify that the alias list only contains "host".
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre("host"));
+}
+
 }  // namespace
 }  // namespace net
diff --git a/net/socket/tcp_client_socket_unittest.cc b/net/socket/tcp_client_socket_unittest.cc
index 525def8..8bc6f48f 100644
--- a/net/socket/tcp_client_socket_unittest.cc
+++ b/net/socket/tcp_client_socket_unittest.cc
@@ -10,6 +10,9 @@
 
 #include <stddef.h>
 
+#include <string>
+#include <vector>
+
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_source.h"
 #include "base/strings/string_number_conversions.h"
@@ -255,6 +258,64 @@
   EXPECT_FALSE(socket.WasEverUsed());
 }
 
+// Tests that DNS aliases can be stored in a socket for reuse.
+TEST_F(TCPClientSocketTest, DnsAliasesPersistForReuse) {
+  IPAddress lo_address = IPAddress::IPv4Localhost();
+  TCPServerSocket server(nullptr, NetLogSource());
+  ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1), IsOk());
+  IPEndPoint server_address;
+  ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
+
+  // Create a socket.
+  TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
+                         NetLogSource());
+  EXPECT_FALSE(socket.WasEverUsed());
+  EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
+
+  // The socket's DNS aliases are unset.
+  EXPECT_TRUE(socket.GetDnsAliases().empty());
+
+  // Set the aliases.
+  std::vector<std::string> dns_aliases({"alias1", "alias2", "host"});
+  socket.SetDnsAliases(dns_aliases);
+
+  // Verify that the aliases are set.
+  EXPECT_THAT(socket.GetDnsAliases(),
+              testing::ElementsAre("alias1", "alias2", "host"));
+
+  // Connect the socket.
+  TestCompletionCallback connect_callback;
+  int connect_result = socket.Connect(connect_callback.callback());
+  EXPECT_FALSE(socket.WasEverUsed());
+  TestCompletionCallback accept_callback;
+  std::unique_ptr<StreamSocket> accepted_socket;
+  int result = server.Accept(&accepted_socket, accept_callback.callback());
+  ASSERT_THAT(accept_callback.GetResult(result), IsOk());
+  EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
+  EXPECT_FALSE(socket.WasEverUsed());
+  EXPECT_TRUE(socket.IsConnected());
+
+  // Write some data to the socket to set WasEverUsed, so that the
+  // socket can be re-used.
+  const char kRequest[] = "GET / HTTP/1.0";
+  auto write_buffer = base::MakeRefCounted<StringIOBuffer>(kRequest);
+  TestCompletionCallback write_callback;
+  socket.Write(write_buffer.get(), write_buffer->size(),
+               write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+  EXPECT_TRUE(socket.WasEverUsed());
+  socket.Disconnect();
+  EXPECT_FALSE(socket.IsConnected());
+  EXPECT_TRUE(socket.WasEverUsed());
+
+  // Re-use the socket, and verify that the aliases are still set.
+  EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
+  TestCompletionCallback connect_callback2;
+  connect_result = socket.Connect(connect_callback2.callback());
+  EXPECT_FALSE(socket.WasEverUsed());
+  EXPECT_THAT(socket.GetDnsAliases(),
+              testing::ElementsAre("alias1", "alias2", "host"));
+}
+
 class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
  public:
   TestSocketPerformanceWatcher() : connection_changed_count_(0u) {}
diff --git a/net/socket/transport_connect_job.cc b/net/socket/transport_connect_job.cc
index 1576493..e4a5be3 100644
--- a/net/socket/transport_connect_job.cc
+++ b/net/socket/transport_connect_job.cc
@@ -370,7 +370,8 @@
       race_result = RACE_IPV6_WINS;
     HistogramDuration(connect_timing_, race_result);
 
-    SetSocket(std::move(transport_socket_));
+    DCHECK(request_);
+    SetSocket(std::move(transport_socket_), request_->GetDnsAliasResults());
   } else {
     // Failure will be returned via |GetAdditionalErrorState|, so save
     // connection attempts from both sockets for use there.
@@ -448,7 +449,9 @@
 
     connect_timing_.connect_start = fallback_connect_start_time_;
     HistogramDuration(connect_timing_, RACE_IPV4_WINS);
-    SetSocket(std::move(fallback_transport_socket_));
+    DCHECK(request_);
+    SetSocket(std::move(fallback_transport_socket_),
+              request_->GetDnsAliasResults());
     next_state_ = STATE_NONE;
   } else {
     // Failure will be returned via |GetAdditionalErrorState|, so save
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index 9def530..9dc9725 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -5,6 +5,8 @@
 #include "net/socket/transport_connect_job.h"
 
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -405,5 +407,53 @@
   EXPECT_EQ(1, client_socket_factory_.allocation_count());
 }
 
+TEST_F(TransportConnectJobTest, DnsAliases) {
+  host_resolver_.set_synchronous_mode(true);
+  client_socket_factory_.set_default_client_socket_type(
+      MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
+
+  // Resolve an AddressList with DNS aliases.
+  std::vector<std::string> aliases({"alias1", "alias2", kHostName});
+  host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
+                                                         std::move(aliases));
+
+  TestConnectJobDelegate test_delegate;
+  TransportConnectJob transport_connect_job(
+      DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
+      DefaultParams(), &test_delegate, nullptr /* net_log */);
+
+  test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
+                                        true /* expect_sync_result */);
+
+  // Verify that the elements of the alias list are those from the
+  // parameter vector.
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre("alias1", "alias2", kHostName));
+}
+
+TEST_F(TransportConnectJobTest, NoAdditionalDnsAliases) {
+  host_resolver_.set_synchronous_mode(true);
+  client_socket_factory_.set_default_client_socket_type(
+      MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
+
+  // Resolve an AddressList without additional DNS aliases. (The parameter
+  // is an empty vector.)
+  std::vector<std::string> aliases;
+  host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
+                                                         std::move(aliases));
+
+  TestConnectJobDelegate test_delegate;
+  TransportConnectJob transport_connect_job(
+      DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
+      DefaultParams(), &test_delegate, nullptr /* net_log */);
+
+  test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
+                                        true /* expect_sync_result */);
+
+  // Verify that the alias list only contains kHostName.
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre(kHostName));
+}
+
 }  // namespace
 }  // namespace net
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 63a19f9a..9608895 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -31,6 +31,7 @@
 #include "net/log/test_net_log.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/connect_job.h"
+#include "net/socket/connect_job_test_util.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/ssl_client_socket.h"
@@ -38,6 +39,7 @@
 #include "net/socket/transport_client_socket_pool_test_util.h"
 #include "net/socket/transport_connect_job.h"
 #include "net/socket/websocket_endpoint_lock_manager.h"
+#include "net/socket/websocket_transport_connect_job.h"
 #include "net/test/gtest_util.h"
 #include "net/test/test_with_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -1164,6 +1166,68 @@
             host_resolver_->request_network_isolation_key(1));
 }
 
+TEST_F(WebSocketTransportClientSocketPoolTest,
+       WebSocketTransportConnectJobWithDnsAliases) {
+  host_resolver_->set_synchronous_mode(true);
+  client_socket_factory_.set_default_client_socket_type(
+      MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
+
+  // Resolve an AddressList with DNS aliases.
+  std::string kHostName("host");
+  std::vector<std::string> aliases({"alias1", "alias2", kHostName});
+  host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
+                                                          std::move(aliases));
+
+  TestConnectJobDelegate test_delegate;
+  scoped_refptr<TransportSocketParams> params =
+      base::MakeRefCounted<TransportSocketParams>(
+          HostPortPair(kHostName, 80), NetworkIsolationKey(),
+          false /* disable_secure_dns */, OnHostResolutionCallback());
+
+  WebSocketTransportConnectJob transport_connect_job(
+      DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
+      &test_delegate, nullptr /* net_log */);
+
+  test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
+                                        true /* expect_sync_result */);
+
+  // Verify that the elements of the alias list are those from the
+  // parameter vector.
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre("alias1", "alias2", kHostName));
+}
+
+TEST_F(WebSocketTransportClientSocketPoolTest,
+       WebSocketTransportConnectJobWithNoAdditionalDnsAliases) {
+  host_resolver_->set_synchronous_mode(true);
+  client_socket_factory_.set_default_client_socket_type(
+      MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
+
+  // Resolve an AddressList without additional DNS aliases. (The parameter
+  // is an empty vector.)
+  std::string kHostName("host");
+  std::vector<std::string> aliases;
+  host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
+                                                          std::move(aliases));
+
+  TestConnectJobDelegate test_delegate;
+  scoped_refptr<TransportSocketParams> params =
+      base::MakeRefCounted<TransportSocketParams>(
+          HostPortPair(kHostName, 80), NetworkIsolationKey(),
+          false /* disable_secure_dns */, OnHostResolutionCallback());
+
+  WebSocketTransportConnectJob transport_connect_job(
+      DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
+      &test_delegate, nullptr /* net_log */);
+
+  test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
+                                        true /* expect_sync_result */);
+
+  // Verify that the alias list only contains kHostName.
+  EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
+              testing::ElementsAre(kHostName));
+}
+
 }  // namespace
 
 }  // namespace net
diff --git a/net/socket/websocket_transport_connect_job.cc b/net/socket/websocket_transport_connect_job.cc
index 59ebac2..e3af56b 100644
--- a/net/socket/websocket_transport_connect_job.cc
+++ b/net/socket/websocket_transport_connect_job.cc
@@ -193,7 +193,8 @@
     result = ipv6_job_->Start();
     switch (result) {
       case OK:
-        SetSocket(ipv6_job_->PassSocket());
+        DCHECK(request_);
+        SetSocket(ipv6_job_->PassSocket(), request_->GetDnsAliasResults());
         race_result_ = had_ipv4_ ? TransportConnectJob::RACE_IPV6_WINS
                                  : TransportConnectJob::RACE_IPV6_SOLO;
         return result;
@@ -220,7 +221,8 @@
   if (ipv4_job_) {
     result = ipv4_job_->Start();
     if (result == OK) {
-      SetSocket(ipv4_job_->PassSocket());
+      DCHECK(request_);
+      SetSocket(ipv4_job_->PassSocket(), request_->GetDnsAliasResults());
       race_result_ = had_ipv6_ ? TransportConnectJob::RACE_IPV4_WINS
                                : TransportConnectJob::RACE_IPV4_SOLO;
     }
@@ -250,7 +252,8 @@
                                  : TransportConnectJob::RACE_IPV6_SOLO;
         break;
     }
-    SetSocket(job->PassSocket());
+    DCHECK(request_);
+    SetSocket(job->PassSocket(), request_->GetDnsAliasResults());
 
     // Make sure all connections are cancelled even if this object fails to be
     // deleted.
diff --git a/net/socket/websocket_transport_connect_sub_job.cc b/net/socket/websocket_transport_connect_sub_job.cc
index 21c8a53..3d05d53 100644
--- a/net/socket/websocket_transport_connect_sub_job.cc
+++ b/net/socket/websocket_transport_connect_sub_job.cc
@@ -4,6 +4,9 @@
 
 #include "net/socket/websocket_transport_connect_sub_job.h"
 
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/check_op.h"
 #include "base/notreached.h"
@@ -57,6 +60,12 @@
   int SetSendBufferSize(int32_t size) override {
     return wrapped_socket_->SetSendBufferSize(size);
   }
+  void SetDnsAliases(std::vector<std::string> aliases) override {
+    wrapped_socket_->SetDnsAliases(aliases);
+  }
+  const std::vector<std::string>& GetDnsAliases() const override {
+    return wrapped_socket_->GetDnsAliases();
+  }
 
   // StreamSocket implementation:
   int Connect(CompletionOnceCallback callback) override {
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index 6a5e091..2c1c2e4 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -134,8 +134,7 @@
 
   AddressList address_list;
   EXPECT_THAT(
-      ParseAddressList(ip_address_list, /* canonical_name = */ std::string(),
-                       &address_list),
+      ParseAddressList(ip_address_list, /* dns_aliases = */ {}, &address_list),
       IsOk());
   address_list = AddressList::CopyWithPort(address_list, 443);
 
diff --git a/services/network/public/mojom/websocket.mojom b/services/network/public/mojom/websocket.mojom
index 3b38ab4..2128df90 100644
--- a/services/network/public/mojom/websocket.mojom
+++ b/services/network/public/mojom/websocket.mojom
@@ -127,11 +127,6 @@
 // The interface for the server side of WebSocket. Implemented by the network
 // service. Used to send out data to the network service.
 interface WebSocket {
-  // The client side may observe the following disconnection reason from the
-  // service side:
-  const uint32 kInsufficientResources = 1;
-  const uint32 kInternalFailure = 2;
-
   // Sends a message via mojo datapipe to the remote server.
   // - |type| is the type of the message. It must be set to either
   //   WebSocketMessageType.TEXT or WebSocketMessageType.BINARY.
diff --git a/services/network/websocket.cc b/services/network/websocket.cc
index d3db7ac8..525a2c5 100644
--- a/services/network/websocket.cc
+++ b/services/network/websocket.cc
@@ -305,10 +305,10 @@
   if (impl_->handshake_client_.is_bound()) {
     impl_->handshake_client_->OnFailure(message, net_error,
                                         response_code.value_or(-1));
-    impl_->handshake_client_.ResetWithReason(mojom::WebSocket::kInternalFailure,
-                                             message);
+    // Additional error information is provided via OnFailure in this case.
+    impl_->handshake_client_.reset();
   }
-  impl_->client_.ResetWithReason(mojom::WebSocket::kInternalFailure, message);
+  impl_->client_.ResetWithReason(0, message);
   impl_->Reset();
 }
 
diff --git a/services/network/websocket_factory.cc b/services/network/websocket_factory.cc
index b7c8a8a..2ac4e3b 100644
--- a/services/network/websocket_factory.cc
+++ b/services/network/websocket_factory.cc
@@ -52,9 +52,9 @@
     // Too many websockets!
     mojo::Remote<mojom::WebSocketHandshakeClient> handshake_client_remote(
         std::move(handshake_client));
-    handshake_client_remote.ResetWithReason(
-        mojom::WebSocket::kInsufficientResources,
-        "Error in connection establishment: net::ERR_INSUFFICIENT_RESOURCES");
+    handshake_client_remote->OnFailure("Insufficient resources",
+                                       net::ERR_INSUFFICIENT_RESOURCES, -1);
+    handshake_client_remote.reset();
     return;
   }
   WebSocket::HasRawHeadersAccess has_raw_headers_access(
diff --git a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
index 3fff869..bbae9516 100644
--- a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
@@ -117,4 +117,7 @@
 -org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerViewTest.testDismissArticleWithContextMenu
 
 # crbug.com/1153888
--org.chromium.chrome.browser.autofill.AutofillUpstreamTest.testSaveCardInfoBarWithEmptyName
\ No newline at end of file
+-org.chromium.chrome.browser.autofill.AutofillUpstreamTest.testSaveCardInfoBarWithEmptyName
+
+# crbug.com/1159805
+-org.chromium.chrome.browser.customtabs.DetachedResourceRequestTest.testRepeatedIntents
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 7c182027..fa2cdba 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -218,10 +218,10 @@
 
 // Determines if the SDP attrbute extmap-allow-mixed should be offered by
 // default or not. The default value can be overridden by passing
-// {offerExtmapAllowMixed:true} as an argument to the RTCPeerConnection
+// {offerExtmapAllowMixed:false} as an argument to the RTCPeerConnection
 // constructor.
-const base::Feature kRTCOfferExtmapAllowMixed{
-    "RTCOfferExtmapAllowMixed", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kRTCOfferExtmapAllowMixed{"RTCOfferExtmapAllowMixed",
+                                              base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables waiting for codec support status notification from GPU factory in RTC
 // codec factories.
@@ -307,11 +307,6 @@
 const base::Feature kFreezeBackgroundTabOnNetworkIdle{
     "freeze-background-tab-on-network-idle", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Freeze non-timer task queues in background, after allowed grace time.
-// "stop" is a legacy name.
-const base::Feature kStopNonTimersInBackground{
-    "stop-non-timers-in-background", base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enable the Storage Access API. https://crbug.com/989663.
 const base::Feature kStorageAccessAPI{"StorageAccessAPI",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 3dec35a..8863bf3 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -88,7 +88,6 @@
 BLINK_COMMON_EXPORT extern const base::Feature kStopInBackground;
 BLINK_COMMON_EXPORT extern const base::Feature
     kFreezeBackgroundTabOnNetworkIdle;
-BLINK_COMMON_EXPORT extern const base::Feature kStopNonTimersInBackground;
 BLINK_COMMON_EXPORT extern const base::Feature kStorageAccessAPI;
 BLINK_COMMON_EXPORT extern const base::Feature kTextFragmentAnchor;
 BLINK_COMMON_EXPORT extern const base::Feature kFontAccess;
diff --git a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
index 47a74ec..853ee1b 100644
--- a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
+++ b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
@@ -153,7 +153,8 @@
         script_state_->GetContext(),
         ScriptSourceCode(code_,
                          ScriptSourceLocationType::kEvalForScheduledAction),
-        KURL(), SanitizeScriptErrors::kDoNotSanitize);
+        KURL(), SanitizeScriptErrors::kDoNotSanitize, ScriptFetchOptions(),
+        ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled);
   } else {
     WorkerGlobalScope* worker = To<WorkerGlobalScope>(context);
     DCHECK(worker->GetThread()->IsCurrentThread());
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
index b45755f0..f33d32c2 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -87,16 +87,17 @@
     const ScriptSourceCode& source,
     const KURL& base_url,
     SanitizeScriptErrors sanitize_script_errors,
-    const ScriptFetchOptions& fetch_options) {
-    ScriptEvaluationResult result = V8ScriptRunner::CompileAndRunScript(
-        GetIsolate(), ScriptState::From(context), window_.Get(), source,
-        base_url, sanitize_script_errors, fetch_options,
-        V8ScriptRunner::RethrowErrorsOption::DoNotRethrow());
+    const ScriptFetchOptions& fetch_options,
+    ExecuteScriptPolicy policy) {
+  ScriptEvaluationResult result = V8ScriptRunner::CompileAndRunScript(
+      GetIsolate(), ScriptState::From(context), window_.Get(), source, base_url,
+      sanitize_script_errors, fetch_options, policy,
+      V8ScriptRunner::RethrowErrorsOption::DoNotRethrow());
 
-    if (result.GetResultType() == ScriptEvaluationResult::ResultType::kSuccess)
-      return result.GetSuccessValue();
+  if (result.GetResultType() == ScriptEvaluationResult::ResultType::kSuccess)
+    return result.GetSuccessValue();
 
-    return v8::Local<v8::Value>();
+  return v8::Local<v8::Value>();
 }
 
 TextPosition ScriptController::EventHandlerPosition() const {
@@ -283,10 +284,6 @@
     SanitizeScriptErrors sanitize_script_errors,
     const ScriptFetchOptions& fetch_options,
     ExecuteScriptPolicy policy) {
-  if (!CanExecuteScript(policy)) {
-    return v8::Local<v8::Value>();
-  }
-
   // |script_state->GetContext()| should be initialized already due to the
   // WindowProxy() call inside ToScriptStateForMainWorld().
   ScriptState* script_state = ToScriptStateForMainWorld(window_->GetFrame());
@@ -297,16 +294,16 @@
 
   return ExecuteScriptAndReturnValue(script_state->GetContext(), source_code,
                                      base_url, sanitize_script_errors,
-                                     fetch_options);
+                                     fetch_options, policy);
 }
 
 v8::Local<v8::Value> ScriptController::EvaluateMethodInMainWorld(
     v8::Local<v8::Function> function,
     v8::Local<v8::Value> receiver,
     int argc,
-    v8::Local<v8::Value> argv[],
-    ExecuteScriptPolicy policy) {
-  if (!CanExecuteScript(policy)) {
+    v8::Local<v8::Value> argv[]) {
+  if (!CanExecuteScript(
+          ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled)) {
     return v8::Local<v8::Value>();
   }
 
@@ -337,7 +334,7 @@
 }
 
 bool ScriptController::CanExecuteScript(ExecuteScriptPolicy policy) {
-  if (policy == kDoNotExecuteScriptWhenScriptsDisabled &&
+  if (policy == ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled &&
       !window_->CanExecuteScripts(kAboutToExecuteScript))
     return false;
 
@@ -364,8 +361,10 @@
   // WindowProxy() inside ToScriptState() above. Add a helper which makes that
   // obvious?
 
-  return ExecuteScriptAndReturnValue(script_state->GetContext(), source,
-                                     base_url, sanitize_script_errors);
+  return ExecuteScriptAndReturnValue(
+      script_state->GetContext(), source, base_url, sanitize_script_errors,
+      ScriptFetchOptions(),
+      ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
 }
 
 scoped_refptr<DOMWrapperWorld>
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.h b/third_party/blink/renderer/bindings/core/v8/script_controller.h
index 992b5ec..8dfcd147 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.h
@@ -55,17 +55,14 @@
 class ScriptSourceCode;
 class SecurityOrigin;
 
+enum class ExecuteScriptPolicy;
+
 // This class exposes methods to run script in a frame (in the main world and
 // in isolated worlds). An instance can be obtained by using
 // LocalDOMWindow::GetScriptController().
 class CORE_EXPORT ScriptController final
     : public GarbageCollected<ScriptController> {
  public:
-  enum ExecuteScriptPolicy {
-    kExecuteScriptWhenScriptsDisabled,
-    kDoNotExecuteScriptWhenScriptsDisabled
-  };
-
   ScriptController(LocalDOMWindow& window,
                    LocalWindowProxyManager& window_proxy_manager)
       : window_(&window), window_proxy_manager_(&window_proxy_manager) {}
@@ -77,20 +74,18 @@
     return window_proxy_manager_->WindowProxy(world);
   }
 
-  v8::Local<v8::Value> ExecuteScriptAndReturnValue(
-      v8::Local<v8::Context>,
-      const ScriptSourceCode&,
-      const KURL& base_url,
-      SanitizeScriptErrors,
-      const ScriptFetchOptions& = ScriptFetchOptions());
+  v8::Local<v8::Value> ExecuteScriptAndReturnValue(v8::Local<v8::Context>,
+                                                   const ScriptSourceCode&,
+                                                   const KURL& base_url,
+                                                   SanitizeScriptErrors,
+                                                   const ScriptFetchOptions&,
+                                                   ExecuteScriptPolicy);
 
   v8::Local<v8::Value> EvaluateMethodInMainWorld(
       v8::Local<v8::Function> function,
       v8::Local<v8::Value> receiver,
       int argc,
-      v8::Local<v8::Value> argv[],
-      ScriptController::ExecuteScriptPolicy = ScriptController::
-          ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled);
+      v8::Local<v8::Value> argv[]);
 
   // Evaluate JavaScript in the main world.
   v8::Local<v8::Value> EvaluateScriptInMainWorld(const ScriptSourceCode&,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
index 2693444d..1cb6706ab 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -383,13 +383,24 @@
     const KURL& base_url,
     SanitizeScriptErrors sanitize_script_errors,
     const ScriptFetchOptions& fetch_options,
+    ExecuteScriptPolicy policy,
     RethrowErrorsOption rethrow_errors) {
   DCHECK_EQ(isolate, script_state->GetIsolate());
 
-  v8::Context::Scope scope(script_state->GetContext());
+  if (policy == ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled &&
+      !execution_context->CanExecuteScripts(kAboutToExecuteScript)) {
+    return ScriptEvaluationResult::FromClassicNotRun();
+  }
 
   LocalDOMWindow* window = DynamicTo<LocalDOMWindow>(execution_context);
   LocalFrame* frame = window ? window->GetFrame() : nullptr;
+
+  if (window && window->document()->IsInitialEmptyDocument()) {
+    window->GetFrame()->Loader().DidAccessInitialDocument();
+  }
+
+  v8::Context::Scope scope(script_state->GetContext());
+
   TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data",
                inspector_evaluate_script_event::Data(
                    frame, source.Url().GetString(), source.StartPosition()));
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
index e5f21163..4aca2e5 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
+++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -49,6 +49,11 @@
 class ScriptSourceCode;
 class ScriptState;
 
+enum class ExecuteScriptPolicy {
+  kExecuteScriptWhenScriptsDisabled,
+  kDoNotExecuteScriptWhenScriptsDisabled
+};
+
 class CORE_EXPORT V8ScriptRunner final {
   STATIC_ONLY(V8ScriptRunner);
 
@@ -118,15 +123,15 @@
       v8::ScriptCompiler::CompileOptions,
       v8::ScriptCompiler::NoCacheReason,
       const ReferrerScriptInfo&);
-  static ScriptEvaluationResult CompileAndRunScript(
-      v8::Isolate*,
-      ScriptState*,
-      ExecutionContext*,
-      const ScriptSourceCode&,
-      const KURL&,
-      SanitizeScriptErrors,
-      const ScriptFetchOptions&,
-      RethrowErrorsOption);
+  static ScriptEvaluationResult CompileAndRunScript(v8::Isolate*,
+                                                    ScriptState*,
+                                                    ExecutionContext*,
+                                                    const ScriptSourceCode&,
+                                                    const KURL&,
+                                                    SanitizeScriptErrors,
+                                                    const ScriptFetchOptions&,
+                                                    ExecuteScriptPolicy,
+                                                    RethrowErrorsOption);
   static v8::MaybeLocal<v8::Value> CompileAndRunInternalScript(
       v8::Isolate*,
       ScriptState*,
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index bad464b..a14ccef 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -317,9 +317,6 @@
     const ScriptSourceCode& source_code,
     SanitizeScriptErrors sanitize_script_errors,
     V8ScriptRunner::RethrowErrorsOption rethrow_errors) {
-  if (IsExecutionForbidden())
-    return ScriptEvaluationResult::FromClassicNotRun();
-
   DCHECK(IsContextInitialized());
   DCHECK(is_ready_to_evaluate_);
 
@@ -332,7 +329,9 @@
   // TODO(crbug/1114989): Plumb ScriptFetchOptions from ClassicScript.
   ScriptEvaluationResult result = V8ScriptRunner::CompileAndRunScript(
       isolate_, script_state_, global_scope_, source_code, base_url,
-      sanitize_script_errors, ScriptFetchOptions(), std::move(rethrow_errors));
+      sanitize_script_errors, ScriptFetchOptions(),
+      ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled,
+      std::move(rethrow_errors));
 
   if (result.GetResultType() == ScriptEvaluationResult::ResultType::kAborted)
     ForbidExecution();
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
index f0d37c90..c68f7885 100644
--- a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
+++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -224,10 +224,8 @@
   if (DispatchEventPreProcess(activation_target,
                               pre_dispatch_event_handler_result) ==
       kContinueDispatching) {
-    if (DispatchEventAtCapturing() == kContinueDispatching) {
-      if (DispatchEventAtTarget() == kContinueDispatching)
-        DispatchEventAtBubbling();
-    }
+    if (DispatchEventAtCapturing() == kContinueDispatching)
+      DispatchEventAtBubbling();
   }
   DispatchEventPostProcess(activation_target,
                            pre_dispatch_event_handler_result);
@@ -255,7 +253,8 @@
 
 inline EventDispatchContinuation EventDispatcher::DispatchEventAtCapturing() {
   // Trigger capturing event handlers, starting at the top and working our way
-  // down.
+  // down. When we get to the last one, the target, change the event phase to
+  // AT_TARGET and fire only the capture listeners on it.
   event_->SetEventPhase(Event::kCapturingPhase);
 
   if (event_->GetEventPath().GetWindowEventContext().HandleLocalEvents(
@@ -263,8 +262,8 @@
       event_->PropagationStopped())
     return kDoneDispatching;
 
-  for (wtf_size_t i = event_->GetEventPath().size() - 1; i > 0; --i) {
-    const NodeEventContext& event_context = event_->GetEventPath()[i];
+  for (wtf_size_t i = event_->GetEventPath().size(); i > 0; --i) {
+    const NodeEventContext& event_context = event_->GetEventPath()[i - 1];
     if (event_context.CurrentTargetSameAsTarget()) {
       event_->SetEventPhase(Event::kAtTarget);
       event_->SetFireOnlyCaptureListenersAtTarget(true);
@@ -281,17 +280,12 @@
   return kContinueDispatching;
 }
 
-inline EventDispatchContinuation EventDispatcher::DispatchEventAtTarget() {
-  event_->SetEventPhase(Event::kAtTarget);
-  event_->GetEventPath()[0].HandleLocalEvents(*event_);
-  return event_->PropagationStopped() ? kDoneDispatching : kContinueDispatching;
-}
-
 inline void EventDispatcher::DispatchEventAtBubbling() {
   // Trigger bubbling event handlers, starting at the bottom and working our way
-  // up.
+  // up. On the first one, the target, change the event phase to AT_TARGET and
+  // fire only the bubble listeners on it.
   wtf_size_t size = event_->GetEventPath().size();
-  for (wtf_size_t i = 1; i < size; ++i) {
+  for (wtf_size_t i = 0; i < size; ++i) {
     const NodeEventContext& event_context = event_->GetEventPath()[i];
     if (event_context.CurrentTargetSameAsTarget()) {
       // TODO(hayato): Need to check cancelBubble() also here?
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.h b/third_party/blink/renderer/core/dom/events/event_dispatcher.h
index d7d2b1f..1683296 100644
--- a/third_party/blink/renderer/core/dom/events/event_dispatcher.h
+++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.h
@@ -71,7 +71,6 @@
       Node* activation_target,
       EventDispatchHandlingState*&);
   EventDispatchContinuation DispatchEventAtCapturing();
-  EventDispatchContinuation DispatchEventAtTarget();
   void DispatchEventAtBubbling();
   void DispatchEventPostProcess(Node* activation_target,
                                 EventDispatchHandlingState*);
diff --git a/third_party/blink/renderer/core/events/pointer_event.cc b/third_party/blink/renderer/core/events/pointer_event.cc
index 6d69c300..c5f45f6 100644
--- a/third_party/blink/renderer/core/events/pointer_event.cc
+++ b/third_party/blink/renderer/core/events/pointer_event.cc
@@ -93,29 +93,27 @@
     for (auto predicted_event : initializer->predictedEvents())
       predicted_events_.push_back(predicted_event);
   }
-  if (RuntimeEnabledFeatures::AzimuthAltitudeEnabled()) {
-    if (initializer->hasAzimuthAngle())
-      azimuth_angle_ = initializer->azimuthAngle();
-    if (initializer->hasAltitudeAngle())
-      altitude_angle_ = initializer->altitudeAngle();
-    if ((initializer->hasTiltX() || initializer->hasTiltY()) &&
-        !initializer->hasAzimuthAngle() && !initializer->hasAltitudeAngle()) {
-      azimuth_angle_ = PointerEventUtil::AzimuthFromTilt(
-          PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
-          PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
-      altitude_angle_ = PointerEventUtil::AltitudeFromTilt(
-          PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
-          PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
-    }
-    if ((initializer->hasAzimuthAngle() || initializer->hasAltitudeAngle()) &&
-        !initializer->hasTiltX() && !initializer->hasTiltY()) {
-      tilt_x_ = PointerEventUtil::TiltXFromSpherical(
-          PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
-          PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
-      tilt_y_ = PointerEventUtil::TiltYFromSpherical(
-          PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
-          PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
-    }
+  if (initializer->hasAzimuthAngle())
+    azimuth_angle_ = initializer->azimuthAngle();
+  if (initializer->hasAltitudeAngle())
+    altitude_angle_ = initializer->altitudeAngle();
+  if ((initializer->hasTiltX() || initializer->hasTiltY()) &&
+      !initializer->hasAzimuthAngle() && !initializer->hasAltitudeAngle()) {
+    azimuth_angle_ = PointerEventUtil::AzimuthFromTilt(
+        PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
+        PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
+    altitude_angle_ = PointerEventUtil::AltitudeFromTilt(
+        PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
+        PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
+  }
+  if ((initializer->hasAzimuthAngle() || initializer->hasAltitudeAngle()) &&
+      !initializer->hasTiltX() && !initializer->hasTiltY()) {
+    tilt_x_ = PointerEventUtil::TiltXFromSpherical(
+        PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
+        PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
+    tilt_y_ = PointerEventUtil::TiltYFromSpherical(
+        PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
+        PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
   }
 }
 
diff --git a/third_party/blink/renderer/core/events/pointer_event.idl b/third_party/blink/renderer/core/events/pointer_event.idl
index 39e7ad8f..60bc5ec 100644
--- a/third_party/blink/renderer/core/events/pointer_event.idl
+++ b/third_party/blink/renderer/core/events/pointer_event.idl
@@ -14,8 +14,8 @@
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute float     pressure;
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute long      tiltX;
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute long      tiltY;
-    [RuntimeEnabled=AzimuthAltitude, Measure] readonly    attribute double    azimuthAngle;
-    [RuntimeEnabled=AzimuthAltitude, Measure] readonly    attribute double    altitudeAngle;
+    [MeasureAs=PointerEventAttributeCount]   readonly    attribute double    azimuthAngle;
+    [MeasureAs=PointerEventAttributeCount]   readonly    attribute double    altitudeAngle;
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute float     tangentialPressure;
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute long      twist;
     [MeasureAs=PointerEventAttributeCount]   readonly    attribute DOMString pointerType;
diff --git a/third_party/blink/renderer/core/events/pointer_event_init.idl b/third_party/blink/renderer/core/events/pointer_event_init.idl
index ef9620ec..a1888c78 100644
--- a/third_party/blink/renderer/core/events/pointer_event_init.idl
+++ b/third_party/blink/renderer/core/events/pointer_event_init.idl
@@ -11,8 +11,8 @@
     float     pressure = 0;
     long      tiltX;
     long      tiltY;
-    [RuntimeEnabled=AzimuthAltitude] double azimuthAngle;
-    [RuntimeEnabled=AzimuthAltitude] double altitudeAngle;
+    double azimuthAngle;
+    double altitudeAngle;
     float     tangentialPressure = 0;
     long      twist = 0;
     DOMString pointerType = "";
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 1a5a792..3cd9f679 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -393,7 +393,7 @@
     ClassicScript::CreateUnspecifiedScript(
         ScriptSourceCode(script, ScriptSourceLocationType::kInternal))
         ->RunScript(web_frame_->GetFrame()->DomWindow(),
-                    ScriptController::kExecuteScriptWhenScriptsDisabled);
+                    ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   }
 
   if (web_frame_->Client()) {
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css
index 5b8d5fc..4af4dcfe 100644
--- a/third_party/blink/renderer/core/html/resources/html.css
+++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -847,7 +847,7 @@
     font-weight: normal;
     display: block;
     padding: 0 2px 1px 2px;
-    white-space: pre;
+    white-space: nowrap;
     min-height: 1.2em;
 }
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
index 4ed17a4d..cbd0b5ff 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -1221,7 +1221,7 @@
               ")",
           ScriptSourceLocationType::kInspector))
       ->RunScript(To<LocalFrame>(OverlayMainFrame())->DomWindow(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
 }
 
 void InspectorOverlayAgent::EvaluateInOverlay(
@@ -1240,7 +1240,7 @@
               ")",
           ScriptSourceLocationType::kInspector))
       ->RunScript(To<LocalFrame>(OverlayMainFrame())->DomWindow(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
 }
 
 String InspectorOverlayAgent::EvaluateInOverlayForTest(const String& script) {
@@ -1251,7 +1251,7 @@
           ScriptSourceCode(script, ScriptSourceLocationType::kInspector))
           ->RunScriptAndReturnValue(
               To<LocalFrame>(OverlayMainFrame())->DomWindow(),
-              ScriptController::kExecuteScriptWhenScriptsDisabled);
+              ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   return ToCoreStringWithUndefinedOrNullCheck(string);
 }
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index a8042899..500d4f2 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -898,7 +898,7 @@
     if (world_name.IsEmpty()) {
       ClassicScript::CreateUnspecifiedScript(ScriptSourceCode(source))
           ->RunScript(frame->DomWindow(),
-                      ScriptController::kExecuteScriptWhenScriptsDisabled);
+                      ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
       continue;
     }
 
@@ -919,7 +919,7 @@
     ClassicScript::CreateUnspecifiedScript(
         ScriptSourceCode(script_to_evaluate_on_load_once_))
         ->RunScript(frame->DomWindow(),
-                    ScriptController::kExecuteScriptWhenScriptsDisabled);
+                    ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   }
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index e40f668..72e6d25a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -26,9 +26,11 @@
     const NGPhysicalContainerFragment& fragment,
     WritingDirectionMode writing_direction) {
   WritingModeConverter converter(writing_direction, fragment.Size());
-  // TODO(mstensho): Once LayoutNG is capable of calculating overflow on its
-  // own, we should probably just move over to relying on that machinery,
-  // instead of doing all this on our own.
+  // Note that what we're doing here is almost the same as what we do when
+  // calculating overflow, with at least one important difference: If the
+  // inline-size of a fragment is 0, the overflow rectangle becomes empty, even
+  // if the fragment's block-size is non-zero. This is correct for overflow
+  // handling, but it would be wrong for column balancing.
   LayoutUnit total_size;
   for (const auto& child : fragment.Children()) {
     LayoutUnit size = converter.ToLogical(child->Size()).block_size;
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
index f930bc9..fc5fee6 100644
--- a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
+++ b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
@@ -261,11 +261,11 @@
   ClassicScript::CreateUnspecifiedScript(
       ScriptSourceCode("var ro = new ResizeObserver( entries => {});"))
       ->RunScript(&Window(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   ASSERT_EQ(observers.size(), 1U);
   ClassicScript::CreateUnspecifiedScript(ScriptSourceCode("ro = undefined;"))
       ->RunScript(&Window(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   ThreadState::Current()->CollectAllGarbageForTesting();
   WebHeap::CollectAllGarbageForTesting();
   ASSERT_EQ(observers.IsEmpty(), true);
@@ -279,14 +279,14 @@
                        "ro.observe(el);"
                        "ro = undefined;"))
       ->RunScript(&Window(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   ASSERT_EQ(observers.size(), 1U);
   ThreadState::Current()->CollectAllGarbageForTesting();
   WebHeap::CollectAllGarbageForTesting();
   ASSERT_EQ(observers.size(), 1U);
   ClassicScript::CreateUnspecifiedScript(ScriptSourceCode("el = undefined;"))
       ->RunScript(&Window(),
-                  ScriptController::kExecuteScriptWhenScriptsDisabled);
+                  ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled);
   ThreadState::Current()->CollectAllGarbageForTesting();
   WebHeap::CollectAllGarbageForTesting();
   ASSERT_EQ(observers.IsEmpty(), true);
diff --git a/third_party/blink/renderer/core/script/classic_script.cc b/third_party/blink/renderer/core/script/classic_script.cc
index f1b2a92..87481ab8 100644
--- a/third_party/blink/renderer/core/script/classic_script.cc
+++ b/third_party/blink/renderer/core/script/classic_script.cc
@@ -27,18 +27,18 @@
 
 void ClassicScript::RunScript(LocalDOMWindow* window) {
   return RunScript(window,
-                   ScriptController::kDoNotExecuteScriptWhenScriptsDisabled);
+                   ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled);
 }
 
 void ClassicScript::RunScript(LocalDOMWindow* window,
-                              ScriptController::ExecuteScriptPolicy policy) {
+                              ExecuteScriptPolicy policy) {
   v8::HandleScope handle_scope(window->GetIsolate());
   RunScriptAndReturnValue(window, policy);
 }
 
 v8::Local<v8::Value> ClassicScript::RunScriptAndReturnValue(
     LocalDOMWindow* window,
-    ScriptController::ExecuteScriptPolicy policy) {
+    ExecuteScriptPolicy policy) {
   return window->GetScriptController().EvaluateScriptInMainWorld(
       GetScriptSourceCode(), BaseURL(), sanitize_script_errors_, FetchOptions(),
       policy);
diff --git a/third_party/blink/renderer/core/script/classic_script.h b/third_party/blink/renderer/core/script/classic_script.h
index e094c23..2f972b5 100644
--- a/third_party/blink/renderer/core/script/classic_script.h
+++ b/third_party/blink/renderer/core/script/classic_script.h
@@ -6,8 +6,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_CLASSIC_SCRIPT_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/loader/resource/script_resource.h"
 #include "third_party/blink/renderer/core/script/script.h"
@@ -49,14 +49,14 @@
   // and overloaded here to avoid modifying Script::RunScript(), because this is
   // a tentative interface. When crbug/1111134 is done, this should be gone.
   void RunScript(LocalDOMWindow*) override;
-  void RunScript(LocalDOMWindow*, ScriptController::ExecuteScriptPolicy);
+  void RunScript(LocalDOMWindow*, ExecuteScriptPolicy);
   bool RunScriptOnWorkerOrWorklet(WorkerOrWorkletGlobalScope&) override;
 
   // Unlike RunScript() and RunScriptOnWorkerOrWorklet(), callers of the
   // following methods must enter a v8::HandleScope before calling.
   v8::Local<v8::Value> RunScriptAndReturnValue(
       LocalDOMWindow*,
-      ScriptController::ExecuteScriptPolicy = ScriptController::
+      ExecuteScriptPolicy =
           ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled);
   v8::Local<v8::Value> RunScriptInIsolatedWorldAndReturnValue(LocalDOMWindow*,
                                                               int32_t world_id);
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
index 117f331..51f6076a 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
@@ -8,6 +8,7 @@
 
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 #include "third_party/webrtc/api/scoped_refptr.h"
 
@@ -307,51 +308,6 @@
 void MockWebRtcVideoTrackSource::RemoveSink(
     rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {}
 
-class MockSessionDescription : public SessionDescriptionInterface {
- public:
-  MockSessionDescription(const std::string& type, const std::string& sdp)
-      : type_(type), sdp_(sdp) {}
-  ~MockSessionDescription() override {}
-  cricket::SessionDescription* description() override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-  const cricket::SessionDescription* description() const override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-  std::string session_id() const override {
-    NOTIMPLEMENTED();
-    return std::string();
-  }
-  std::string session_version() const override {
-    NOTIMPLEMENTED();
-    return std::string();
-  }
-  std::string type() const override { return type_; }
-  bool AddCandidate(const IceCandidateInterface* candidate) override {
-    NOTIMPLEMENTED();
-    return false;
-  }
-  size_t number_of_mediasections() const override {
-    NOTIMPLEMENTED();
-    return 0;
-  }
-  const IceCandidateCollection* candidates(
-      size_t mediasection_index) const override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-
-  bool ToString(std::string* out) const override {
-    *out = sdp_;
-    return true;
-  }
-
- private:
-  std::string type_;
-  std::string sdp_;
-};
 
 class MockIceCandidate : public IceCandidateInterface {
  public:
@@ -417,16 +373,6 @@
   return track;
 }
 
-SessionDescriptionInterface*
-MockPeerConnectionDependencyFactory::CreateSessionDescription(
-    const String& type,
-    const String& sdp,
-    webrtc::SdpParseError* error) {
-  if (fail_to_create_session_description_)
-    return nullptr;
-  return new MockSessionDescription(type.Utf8(), sdp.Utf8());
-}
-
 webrtc::IceCandidateInterface*
 MockPeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid,
                                                         int sdp_mline_index,
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
index 64f84a8..c904047 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
@@ -180,10 +180,6 @@
   scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack(
       const String& id,
       webrtc::VideoTrackSourceInterface* source) override;
-  webrtc::SessionDescriptionInterface* CreateSessionDescription(
-      const String& type,
-      const String& sdp,
-      webrtc::SdpParseError* error) override;
   webrtc::IceCandidateInterface* CreateIceCandidate(const String& sdp_mid,
                                                     int sdp_mline_index,
                                                     const String& sdp) override;
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
index 6bacb89..5bd05d8b 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
@@ -14,6 +14,7 @@
 #include "base/notreached.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h"
 #include "third_party/blink/renderer/platform/peerconnection/webrtc_util.h"
 #include "third_party/webrtc/api/rtp_receiver_interface.h"
 #include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -324,8 +325,7 @@
 MockPeerConnectionImpl::MockPeerConnectionImpl(
     MockPeerConnectionDependencyFactory* factory,
     webrtc::PeerConnectionObserver* observer)
-    : dependency_factory_(factory),
-      remote_streams_(new rtc::RefCountedObject<MockStreamCollection>),
+    : remote_streams_(new rtc::RefCountedObject<MockStreamCollection>),
       hint_audio_(false),
       hint_video_(false),
       getstats_result_(true),
@@ -503,18 +503,16 @@
     CreateSessionDescriptionObserver* observer,
     const RTCOfferAnswerOptions& options) {
   DCHECK(observer);
-  created_sessiondescription_.reset(
-      dependency_factory_->CreateSessionDescription("unknown", kDummyOffer,
-                                                    nullptr));
+  created_sessiondescription_ =
+      MockParsedSessionDescription("unknown", kDummyAnswer).release();
 }
 
 void MockPeerConnectionImpl::CreateAnswer(
     CreateSessionDescriptionObserver* observer,
     const RTCOfferAnswerOptions& options) {
   DCHECK(observer);
-  created_sessiondescription_.reset(
-      dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer,
-                                                    nullptr));
+  created_sessiondescription_ =
+      MockParsedSessionDescription("unknown", kDummyAnswer).release();
 }
 
 void MockPeerConnectionImpl::SetLocalDescriptionWorker(
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
index 4adc6ce..fcd6afac 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
@@ -386,9 +386,6 @@
   ~MockPeerConnectionImpl() override;
 
  private:
-  // Used for creating MockSessionDescription.
-  MockPeerConnectionDependencyFactory* dependency_factory_;
-
   std::string stream_label_;
   std::vector<std::string> local_stream_ids_;
   rtc::scoped_refptr<MockStreamCollection> remote_streams_;
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
index 098c1c5a..f7375194 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
+++ b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
@@ -281,11 +281,11 @@
 
 void MockRTCPeerConnectionHandlerPlatform::SetLocalDescription(
     RTCVoidRequest*,
-    RTCSessionDescriptionPlatform*) {}
+    ParsedSessionDescription) {}
 
 void MockRTCPeerConnectionHandlerPlatform::SetRemoteDescription(
     RTCVoidRequest*,
-    RTCSessionDescriptionPlatform*) {}
+    ParsedSessionDescription) {}
 
 const webrtc::PeerConnectionInterface::RTCConfiguration&
 MockRTCPeerConnectionHandlerPlatform::GetConfiguration() const {
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h
index a2f93c4..2a76d5e 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h
+++ b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h
@@ -17,6 +17,65 @@
 
 namespace blink {
 
+class MockSessionDescription : public webrtc::SessionDescriptionInterface {
+ public:
+  MockSessionDescription(const std::string& type, const std::string& sdp)
+      : type_(type), sdp_(sdp) {}
+  ~MockSessionDescription() override = default;
+  cricket::SessionDescription* description() override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+  const cricket::SessionDescription* description() const override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+  std::string session_id() const override {
+    NOTIMPLEMENTED();
+    return std::string();
+  }
+  std::string session_version() const override {
+    NOTIMPLEMENTED();
+    return std::string();
+  }
+  std::string type() const override { return type_; }
+  bool AddCandidate(const webrtc::IceCandidateInterface* candidate) override {
+    NOTIMPLEMENTED();
+    return false;
+  }
+  size_t number_of_mediasections() const override {
+    NOTIMPLEMENTED();
+    return 0;
+  }
+  const webrtc::IceCandidateCollection* candidates(
+      size_t mediasection_index) const override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+
+  bool ToString(std::string* out) const override {
+    *out = sdp_;
+    return true;
+  }
+
+ private:
+  std::string type_;
+  std::string sdp_;
+};
+
+// Class for creating a ParsedSessionDescription without running the parser.
+// It returns an empty (but non-null) description object.
+class MockParsedSessionDescription : public ParsedSessionDescription {
+ public:
+  MockParsedSessionDescription(const String& type, const String& sdp)
+      : ParsedSessionDescription(type, sdp) {
+    description_ =
+        std::make_unique<MockSessionDescription>(type.Utf8(), sdp.Utf8());
+  }
+  // Constructor for creating an error-returning session description.
+  MockParsedSessionDescription() : ParsedSessionDescription("error", "error") {}
+};
+
 // TODO(https://crbug.com/908461): This is currently implemented as NO-OPs or to
 // create dummy objects whose methods return default values. Consider renaming
 // the class, changing it to be GMOCK friendly or deleting it.
@@ -45,10 +104,8 @@
   void CreateAnswer(RTCSessionDescriptionRequest*,
                     RTCAnswerOptionsPlatform*) override;
   void SetLocalDescription(RTCVoidRequest*) override;
-  void SetLocalDescription(RTCVoidRequest*,
-                           RTCSessionDescriptionPlatform*) override;
-  void SetRemoteDescription(RTCVoidRequest*,
-                            RTCSessionDescriptionPlatform*) override;
+  void SetLocalDescription(RTCVoidRequest*, ParsedSessionDescription) override;
+  void SetRemoteDescription(RTCVoidRequest*, ParsedSessionDescription) override;
   const webrtc::PeerConnectionInterface::RTCConfiguration& GetConfiguration()
       const override;
   webrtc::RTCErrorType SetConfiguration(
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
index ceccf0d7..a56c93b 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
@@ -534,14 +534,6 @@
   return GetPcFactory()->CreateVideoTrack(id.Utf8(), source).get();
 }
 
-webrtc::SessionDescriptionInterface*
-PeerConnectionDependencyFactory::CreateSessionDescription(
-    const String& type,
-    const String& sdp,
-    webrtc::SdpParseError* error) {
-  return webrtc::CreateSessionDescription(type.Utf8(), sdp.Utf8(), error);
-}
-
 webrtc::IceCandidateInterface*
 PeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid,
                                                     int sdp_mline_index,
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
index c936ee3..64ac82d9 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
@@ -92,13 +92,6 @@
   virtual std::unique_ptr<webrtc::AsyncResolverFactory>
   CreateAsyncResolverFactory();
 
-  // Creates a libjingle representation of a Session description. Used by a
-  // RTCPeerConnectionHandler instance.
-  virtual webrtc::SessionDescriptionInterface* CreateSessionDescription(
-      const String& type,
-      const String& sdp,
-      webrtc::SdpParseError* error);
-
   // Creates a libjingle representation of an ice candidate.
   virtual webrtc::IceCandidateInterface* CreateIceCandidate(
       const String& sdp_mid,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index f48d0290..cca15035 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -542,11 +542,9 @@
   kComplexUnifiedPlan,
 };
 
-base::Optional<SdpFormat> DeduceSdpFormat(const String& type,
-                                          const String& sdp) {
-  std::unique_ptr<webrtc::SessionDescriptionInterface> session_description(
-      webrtc::CreateSessionDescription(type.Utf8().c_str(), sdp.Utf8().c_str(),
-                                       nullptr));
+base::Optional<SdpFormat> DeduceSdpFormat(
+    const ParsedSessionDescription& parsed_sdp) {
+  auto* session_description = parsed_sdp.description();
   if (!session_description)
     return base::nullopt;
   size_t num_audio_mlines = 0u;
@@ -604,11 +602,11 @@
 const char kOnlySupportedInUnifiedPlanMessage[] =
     "This operation is only supported in 'unified-plan'.";
 
-SdpUsageCategory DeduceSdpUsageCategory(const String& sdp_type,
-                                        const String& sdp,
-                                        bool sdp_semantics_specified,
-                                        webrtc::SdpSemantics sdp_semantics) {
-  auto sdp_format = DeduceSdpFormat(sdp_type, sdp);
+SdpUsageCategory DeduceSdpUsageCategory(
+    const ParsedSessionDescription& parsed_sdp,
+    bool sdp_semantics_specified,
+    webrtc::SdpSemantics sdp_semantics) {
+  auto sdp_format = DeduceSdpFormat(parsed_sdp);
   if (!sdp_format)
     return SdpUsageCategory::kUnknown;
   switch (*sdp_format) {
@@ -1070,25 +1068,21 @@
 
 DOMException* RTCPeerConnection::checkSdpForStateErrors(
     ExecutionContext* context,
-    const RTCSessionDescriptionInit* session_description_init,
-    String* sdp) {
+    const ParsedSessionDescription& parsed_sdp) {
   if (signaling_state_ ==
       webrtc::PeerConnectionInterface::SignalingState::kClosed) {
     return MakeGarbageCollected<DOMException>(
         DOMExceptionCode::kInvalidStateError, kSignalingStateClosedMessage);
   }
 
-  *sdp = session_description_init->sdp();
-  if (session_description_init->type() == "offer") {
-    if (sdp->IsNull() || sdp->IsEmpty()) {
-      *sdp = last_offer_;
-    } else if (session_description_init->sdp() != last_offer_) {
-      if (FingerprintMismatch(last_offer_, *sdp)) {
+  if (parsed_sdp.type() == "offer") {
+    if (parsed_sdp.sdp() != last_offer_) {
+      if (FingerprintMismatch(last_offer_, parsed_sdp.sdp())) {
         return MakeGarbageCollected<DOMException>(
             DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage);
       } else {
         UseCounter::Count(context, WebFeature::kRTCLocalSdpModification);
-        if (ContainsLegacySimulcast(*sdp)) {
+        if (ContainsLegacySimulcast(parsed_sdp.sdp())) {
           UseCounter::Count(context,
                             WebFeature::kRTCLocalSdpModificationSimulcast);
         }
@@ -1096,17 +1090,14 @@
         // TODO(https://crbug.com/823036): Return failure for all modification.
       }
     }
-  } else if (session_description_init->type() == "answer" ||
-             session_description_init->type() == "pranswer") {
-    if (sdp->IsNull() || sdp->IsEmpty()) {
-      *sdp = last_answer_;
-    } else if (session_description_init->sdp() != last_answer_) {
-      if (FingerprintMismatch(last_answer_, *sdp)) {
+  } else if (parsed_sdp.type() == "answer" || parsed_sdp.type() == "pranswer") {
+    if (parsed_sdp.sdp() != last_answer_) {
+      if (FingerprintMismatch(last_answer_, parsed_sdp.sdp())) {
         return MakeGarbageCollected<DOMException>(
             DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage);
       } else {
         UseCounter::Count(context, WebFeature::kRTCLocalSdpModification);
-        if (ContainsLegacySimulcast(*sdp)) {
+        if (ContainsLegacySimulcast(parsed_sdp.sdp())) {
           UseCounter::Count(context,
                             WebFeature::kRTCLocalSdpModificationSimulcast);
         }
@@ -1119,12 +1110,8 @@
 }
 
 base::Optional<ComplexSdpCategory> RTCPeerConnection::CheckForComplexSdp(
-    const RTCSessionDescriptionInit* session_description_init) const {
-  if (!session_description_init->hasType())
-    return base::nullopt;
-
-  base::Optional<SdpFormat> sdp_format = DeduceSdpFormat(
-      session_description_init->type(), session_description_init->sdp());
+    const ParsedSessionDescription& parsed_sdp) const {
+  base::Optional<SdpFormat> sdp_format = DeduceSdpFormat(parsed_sdp);
   if (!sdp_format) {
     return sdp_semantics_specified_
                ? ComplexSdpCategory::kErrorExplicitSemantics
@@ -1145,9 +1132,9 @@
 }
 
 void RTCPeerConnection::MaybeWarnAboutUnsafeSdp(
-    const RTCSessionDescriptionInit* session_description_init) const {
+    const ParsedSessionDescription& parsed_sdp) const {
   base::Optional<ComplexSdpCategory> complex_sdp_category =
-      CheckForComplexSdp(session_description_init);
+      CheckForComplexSdp(parsed_sdp);
   if (!complex_sdp_category || !GetExecutionContext())
     return;
 
@@ -1308,11 +1295,14 @@
 
 void RTCPeerConnection::ReportSetSdpUsage(
     SetSdpOperationType operation_type,
-    const RTCSessionDescriptionInit* session_description_init) const {
+    const ParsedSessionDescription& parsed_sdp) const {
+  if (!parsed_sdp.description()) {
+    LOG(ERROR) << "ReportSetSdpUsage called on SDP that failed parsing";
+    return;
+  }
   SdpUsageCategory sdp_usage = DeduceSdpUsageCategory(
-      session_description_init->type(), session_description_init->sdp(),
-      sdp_semantics_specified_, sdp_semantics_);
-  if (session_description_init->type() == "offer") {
+      parsed_sdp, sdp_semantics_specified_, sdp_semantics_);
+  if (parsed_sdp.description()->GetType() == webrtc::SdpType::kOffer) {
     switch (operation_type) {
       case SetSdpOperationType::kSetLocalDescription:
         UMA_HISTOGRAM_ENUMERATION(
@@ -1323,8 +1313,9 @@
             "WebRTC.PeerConnection.SdpComplexUsage.SetRemoteOffer", sdp_usage);
         break;
     }
-  } else if (session_description_init->type() == "answer" ||
-             session_description_init->type() == "pranswer") {
+  } else if (parsed_sdp.description()->GetType() == webrtc::SdpType::kAnswer ||
+             parsed_sdp.description()->GetType() ==
+                 webrtc::SdpType::kPrAnswer) {
     switch (operation_type) {
       case SetSdpOperationType::kSetLocalDescription:
         UMA_HISTOGRAM_ENUMERATION(
@@ -1364,14 +1355,25 @@
   if (!session_description_init->hasType()) {
     return setLocalDescription(script_state);
   }
-  String sdp;
+  String sdp = session_description_init->sdp();
+  // https://w3c.github.io/webrtc-pc/#dom-peerconnection-setlocaldescription
+  // step 4.4 and 4.5: If SDP is empty, return the last created offer or answer.
+  if (sdp.IsNull() || sdp.IsEmpty()) {
+    if (session_description_init->type() == "offer") {
+      sdp = last_offer_;
+    } else if (session_description_init->type() == "answer" ||
+               session_description_init->type() == "pranswer") {
+      sdp = last_answer_;
+    }
+  }
+  ParsedSessionDescription parsed_sdp =
+      ParsedSessionDescription::Parse(session_description_init->type(), sdp);
   if (session_description_init->type() != "rollback") {
-    MaybeWarnAboutUnsafeSdp(session_description_init);
-    ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription,
-                      session_description_init);
+    MaybeWarnAboutUnsafeSdp(parsed_sdp);
+    ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, parsed_sdp);
 
     DOMException* exception = checkSdpForStateErrors(
-        ExecutionContext::From(script_state), session_description_init, &sdp);
+        ExecutionContext::From(script_state), parsed_sdp);
     if (exception) {
       exception_state.ThrowDOMException(
           static_cast<DOMExceptionCode>(exception->code()),
@@ -1392,9 +1394,7 @@
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription,
                                      *session_description_init),
       this, resolver, "RTCPeerConnection", "setLocalDescription");
-  peer_handler_->SetLocalDescription(
-      request, MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-                   session_description_init->type(), sdp));
+  peer_handler_->SetLocalDescription(request, std::move(parsed_sdp));
   return promise;
 }
 
@@ -1409,10 +1409,22 @@
   }
 
   DCHECK(script_state->ContextIsValid());
+  String sdp = session_description_init->sdp();
+  // https://w3c.github.io/webrtc-pc/#dom-peerconnection-setlocaldescription
+  // step 4.4 and 4.5: If SDP is empty, return the last created offer or answer.
+  if (sdp.IsNull() || sdp.IsEmpty()) {
+    if (session_description_init->type() == "offer") {
+      sdp = last_offer_;
+    } else if (session_description_init->type() == "answer" ||
+               session_description_init->type() == "pranswer") {
+      sdp = last_answer_;
+    }
+  }
+  ParsedSessionDescription parsed_sdp =
+      ParsedSessionDescription::Parse(session_description_init->type(), sdp);
   if (session_description_init->type() != "rollback") {
-    MaybeWarnAboutUnsafeSdp(session_description_init);
-    ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription,
-                      session_description_init);
+    MaybeWarnAboutUnsafeSdp(parsed_sdp);
+    ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, parsed_sdp);
   }
   ExecutionContext* context = ExecutionContext::From(script_state);
   UseCounter::Count(context, WebFeature::kRTCPeerConnectionSetLocalDescription);
@@ -1432,10 +1444,8 @@
           WebFeature::
               kRTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback);
   }
-  String sdp;
   if (session_description_init->type() != "rollback") {
-    DOMException* exception =
-        checkSdpForStateErrors(context, session_description_init, &sdp);
+    DOMException* exception = checkSdpForStateErrors(context, parsed_sdp);
     if (exception) {
       if (error_callback)
         AsyncCallErrorCallback(error_callback, exception);
@@ -1449,10 +1459,7 @@
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription,
                                      *session_description_init),
       this, success_callback, error_callback);
-  peer_handler_->SetLocalDescription(
-      request,
-      MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-          session_description_init->type(), session_description_init->sdp()));
+  peer_handler_->SetLocalDescription(request, std::move(parsed_sdp));
   return ScriptPromise::CastUndefined(script_state);
 }
 
@@ -1480,10 +1487,11 @@
   }
 
   DCHECK(script_state->ContextIsValid());
+  ParsedSessionDescription parsed_sdp =
+      ParsedSessionDescription::Parse(session_description_init);
   if (session_description_init->type() != "rollback") {
-    MaybeWarnAboutUnsafeSdp(session_description_init);
-    ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription,
-                      session_description_init);
+    MaybeWarnAboutUnsafeSdp(parsed_sdp);
+    ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, parsed_sdp);
   }
   if (signaling_state_ ==
       webrtc::PeerConnectionInterface::SignalingState::kClosed) {
@@ -1510,10 +1518,7 @@
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription,
                                      *session_description_init),
       this, resolver, "RTCPeerConnection", "setRemoteDescription");
-  peer_handler_->SetRemoteDescription(
-      request,
-      MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-          session_description_init->type(), session_description_init->sdp()));
+  peer_handler_->SetRemoteDescription(request, std::move(parsed_sdp));
   return promise;
 }
 
@@ -1528,10 +1533,11 @@
   }
 
   DCHECK(script_state->ContextIsValid());
+  ParsedSessionDescription parsed_sdp =
+      ParsedSessionDescription::Parse(session_description_init);
   if (session_description_init->type() != "rollback") {
-    MaybeWarnAboutUnsafeSdp(session_description_init);
-    ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription,
-                      session_description_init);
+    MaybeWarnAboutUnsafeSdp(parsed_sdp);
+    ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, parsed_sdp);
   }
   ExecutionContext* context = ExecutionContext::From(script_state);
   UseCounter::Count(context,
@@ -1566,10 +1572,7 @@
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription,
                                      *session_description_init),
       this, success_callback, error_callback);
-  peer_handler_->SetRemoteDescription(
-      request,
-      MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-          session_description_init->type(), session_description_init->sdp()));
+  peer_handler_->SetRemoteDescription(request, std::move(parsed_sdp));
   return ScriptPromise::CastUndefined(script_state);
 }
 
@@ -2790,8 +2793,12 @@
 }
 
 void RTCPeerConnection::NoteSdpCreated(const RTCSessionDescription& desc) {
+  // TODO(https://bugs.webrtc.org/12215): Don't re-parse the description here,
+  // it's passed in as a parsed structure into
+  // CreateSessionDescriptionRequest::OnSuccess.
   SdpUsageCategory sdp_usage = DeduceSdpUsageCategory(
-      desc.type(), desc.sdp(), sdp_semantics_specified_, sdp_semantics_);
+      ParsedSessionDescription::Parse(desc.type(), desc.sdp()),
+      sdp_semantics_specified_, sdp_semantics_);
   if (desc.type() == "offer") {
     last_offer_ = desc.sdp();
     UMA_HISTOGRAM_ENUMERATION(
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 4e9fb84..ebce392 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -103,8 +103,7 @@
 };
 
 MODULES_EXPORT SdpUsageCategory
-DeduceSdpUsageCategory(const String& sdp_type,
-                       const String& sdp,
+DeduceSdpUsageCategory(const ParsedSessionDescription& parsed_sdp,
                        bool sdp_semantics_specified,
                        webrtc::SdpSemantics sdp_semantics);
 
@@ -319,9 +318,8 @@
     kSetLocalDescription,
     kSetRemoteDescription,
   };
-  void ReportSetSdpUsage(
-      SetSdpOperationType operation_type,
-      const RTCSessionDescriptionInit* session_description_init) const;
+  void ReportSetSdpUsage(SetSdpOperationType operation_type,
+                         const ParsedSessionDescription& parsed_sdp) const;
 
   // MediaStreamObserver
   void OnStreamAddTrack(MediaStream*, MediaStreamTrack*) override;
@@ -389,7 +387,7 @@
   // explicitly specifying the SDP format, there may be errors if the
   // application assumes a format that differs from the actual default format.
   base::Optional<ComplexSdpCategory> CheckForComplexSdp(
-      const RTCSessionDescriptionInit* session_description_init) const;
+      const ParsedSessionDescription&) const;
 
   const CallSetupStateTracker& call_setup_state_tracker() const;
   void NoteCallSetupStateEventPending(
@@ -571,10 +569,8 @@
   void RecordRapporMetrics();
 
   DOMException* checkSdpForStateErrors(ExecutionContext*,
-                                       const RTCSessionDescriptionInit*,
-                                       String* sdp);
-  void MaybeWarnAboutUnsafeSdp(
-      const RTCSessionDescriptionInit* session_description_init) const;
+                                       const ParsedSessionDescription&);
+  void MaybeWarnAboutUnsafeSdp(const ParsedSessionDescription&) const;
 
   HeapHashSet<Member<RTCIceTransport>> ActiveIceTransports() const;
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index d3b17a5..fad33f8 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -605,6 +605,42 @@
 
 }  // namespace
 
+// Implementation of ParsedSessionDescription
+ParsedSessionDescription::ParsedSessionDescription(const String& sdp_type,
+                                                   const String& sdp)
+    : type_(sdp_type), sdp_(sdp) {}
+
+// static
+ParsedSessionDescription ParsedSessionDescription::Parse(
+    const RTCSessionDescriptionInit* session_description_init) {
+  ParsedSessionDescription temp(session_description_init->type(),
+                                session_description_init->sdp());
+  temp.DoParse();
+  return temp;
+}
+
+// static
+ParsedSessionDescription ParsedSessionDescription::Parse(
+    const RTCSessionDescriptionPlatform* session_description_platform) {
+  ParsedSessionDescription temp(session_description_platform->GetType(),
+                                session_description_platform->Sdp());
+  temp.DoParse();
+  return temp;
+}
+
+// static
+ParsedSessionDescription ParsedSessionDescription::Parse(const String& sdp_type,
+                                                         const String& sdp) {
+  ParsedSessionDescription temp(sdp_type, sdp);
+  temp.DoParse();
+  return temp;
+}
+
+void ParsedSessionDescription::DoParse() {
+  description_.reset(webrtc::CreateSessionDescription(
+      type_.Utf8().c_str(), sdp_.Utf8().c_str(), &error_));
+}
+
 // Implementation of LocalRTCStatsRequest.
 LocalRTCStatsRequest::LocalRTCStatsRequest(RTCStatsRequest* impl)
     : impl_(impl) {}
@@ -1346,24 +1382,22 @@
 
 void RTCPeerConnectionHandler::SetLocalDescription(
     blink::RTCVoidRequest* request,
-    RTCSessionDescriptionPlatform* description) {
+    ParsedSessionDescription parsed_sdp) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setLocalDescription");
 
-  String sdp = description->Sdp();
-  String type = description->GetType();
+  String sdp = parsed_sdp.sdp();
+  String type = parsed_sdp.type();
 
   if (peer_connection_tracker_) {
     peer_connection_tracker_->TrackSetSessionDescription(
         this, sdp, type, PeerConnectionTracker::SOURCE_LOCAL);
   }
 
-  webrtc::SdpParseError error;
-  // Since CreateNativeSessionDescription uses the dependency factory, we need
-  // to make this call on the current thread to be safe.
-  std::unique_ptr<webrtc::SessionDescriptionInterface> native_desc(
-      CreateNativeSessionDescription(sdp, type, &error));
+  const webrtc::SessionDescriptionInterface* native_desc =
+      parsed_sdp.description();
   if (!native_desc) {
+    webrtc::SdpParseError error(parsed_sdp.error());
     StringBuilder reason_str;
     reason_str.Append("Failed to parse SessionDescription. ");
     reason_str.Append(error.line.c_str());
@@ -1386,9 +1420,9 @@
     return;
   }
 
-  if (!first_local_description_ && IsOfferOrAnswer(native_desc.get())) {
+  if (!first_local_description_ && IsOfferOrAnswer(native_desc)) {
     first_local_description_ =
-        std::make_unique<FirstSessionDescription>(native_desc.get());
+        std::make_unique<FirstSessionDescription>(native_desc);
     if (first_remote_description_) {
       ReportFirstSessionDescriptions(*first_local_description_,
                                      *first_remote_description_);
@@ -1420,30 +1454,28 @@
                   rtc::scoped_refptr<
                       webrtc::SetLocalDescriptionObserverInterface>)>(
                   &webrtc::PeerConnectionInterface::SetLocalDescription),
-              native_peer_connection_, WTF::Passed(std::move(native_desc)),
+              native_peer_connection_, WTF::Passed(parsed_sdp.release()),
               webrtc_observer),
           CrossThreadUnretained("SetLocalDescription")));
 }
 
 void RTCPeerConnectionHandler::SetRemoteDescription(
     blink::RTCVoidRequest* request,
-    RTCSessionDescriptionPlatform* description) {
+    ParsedSessionDescription parsed_sdp) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setRemoteDescription");
 
-  String sdp = description->Sdp();
-  String type = description->GetType();
+  String sdp = parsed_sdp.sdp();
+  String type = parsed_sdp.type();
 
   if (peer_connection_tracker_) {
     peer_connection_tracker_->TrackSetSessionDescription(
         this, sdp, type, PeerConnectionTracker::SOURCE_REMOTE);
   }
 
-  webrtc::SdpParseError error;
-  // Since CreateNativeSessionDescription uses the dependency factory, we need
-  // to make this call on the current thread to be safe.
-  std::unique_ptr<webrtc::SessionDescriptionInterface> native_desc(
-      CreateNativeSessionDescription(sdp, type, &error));
+  webrtc::SdpParseError error(parsed_sdp.error());
+  const webrtc::SessionDescriptionInterface* native_desc =
+      parsed_sdp.description();
   if (!native_desc) {
     StringBuilder reason_str;
     reason_str.Append("Failed to parse SessionDescription. ");
@@ -1468,9 +1500,9 @@
     return;
   }
 
-  if (!first_remote_description_ && IsOfferOrAnswer(native_desc.get())) {
-    first_remote_description_.reset(
-        new FirstSessionDescription(native_desc.get()));
+  if (!first_remote_description_ && IsOfferOrAnswer(native_desc)) {
+    first_remote_description_ =
+        std::make_unique<FirstSessionDescription>(native_desc);
     if (first_local_description_) {
       ReportFirstSessionDescriptions(*first_local_description_,
                                      *first_remote_description_);
@@ -1502,7 +1534,7 @@
                   rtc::scoped_refptr<
                       webrtc::SetRemoteDescriptionObserverInterface>)>(
                   &webrtc::PeerConnectionInterface::SetRemoteDescription),
-              native_peer_connection_, WTF::Passed(std::move(native_desc)),
+              native_peer_connection_, WTF::Passed(parsed_sdp.release()),
               webrtc_observer),
           CrossThreadUnretained("SetRemoteDescription")));
 }
@@ -2569,20 +2601,6 @@
     client_->DidNoteInterestingUsage(usage_pattern);
 }
 
-webrtc::SessionDescriptionInterface*
-RTCPeerConnectionHandler::CreateNativeSessionDescription(
-    const String& sdp,
-    const String& type,
-    webrtc::SdpParseError* error) {
-  webrtc::SessionDescriptionInterface* native_desc =
-      dependency_factory_->CreateSessionDescription(type, sdp, error);
-
-  LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
-                              << " Type: " << type << " SDP: " << sdp;
-
-  return native_desc;
-}
-
 RTCPeerConnectionHandler::FirstSessionDescription::FirstSessionDescription(
     const webrtc::SessionDescriptionInterface* sdesc) {
   DCHECK(sdesc);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
index cbf6bd1..76ff7f54 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h"
 #include "third_party/blink/renderer/modules/peerconnection/thermal_resource.h"
 #include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h"
 #include "third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h"
@@ -57,6 +58,55 @@
 class SetLocalDescriptionRequest;
 class WebLocalFrame;
 
+// Helper class for passing pre-parsed session descriptions to functions.
+// Create a ParsedSessionDescription by calling one of the Parse functions.
+// The function allows you to access its input SDP string, as well as the
+// parsed form. If parse failed, description() returns null, and error()
+// returns an error description. The class can't be modified or reused,
+// but can be neutered by calling release().
+class MODULES_EXPORT ParsedSessionDescription {
+ public:
+  static ParsedSessionDescription Parse(const RTCSessionDescriptionInit*);
+  static ParsedSessionDescription Parse(const RTCSessionDescriptionPlatform*);
+  static ParsedSessionDescription Parse(const String& type, const String& sdp);
+
+  // Moveable, but not copyable.
+  ParsedSessionDescription(ParsedSessionDescription&& other) = default;
+  ParsedSessionDescription& operator=(ParsedSessionDescription&& other) =
+      default;
+  ParsedSessionDescription(const ParsedSessionDescription&) = delete;
+  ParsedSessionDescription operator=(const ParsedSessionDescription&) = delete;
+
+  const webrtc::SessionDescriptionInterface* description() const {
+    return description_.get();
+  }
+  const webrtc::SdpParseError& error() const { return error_; }
+  const String& type() const { return type_; }
+  const String& sdp() const { return sdp_; }
+
+  std::unique_ptr<webrtc::SessionDescriptionInterface> release() {
+    return std::unique_ptr<webrtc::SessionDescriptionInterface>(
+        description_.release());
+  }
+
+ protected:
+  // The constructor will not parse the SDP.
+  // It is protected, not private, in order to allow it to be used to construct
+  // mock objects.
+  ParsedSessionDescription(const String& type, const String& sdp);
+  // The mock object also needs access to the description.
+  std::unique_ptr<webrtc::SessionDescriptionInterface> description_;
+
+ private:
+  // Does the actual parsing. Only called from the static Parse methods.
+  void DoParse();
+
+  String type_;
+  String sdp_;
+
+  webrtc::SdpParseError error_;
+};
+
 // Mockable wrapper for blink::RTCStatsResponseBase
 class MODULES_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface {
  public:
@@ -152,10 +202,12 @@
                             blink::RTCAnswerOptionsPlatform* options);
 
   virtual void SetLocalDescription(blink::RTCVoidRequest* request);
+  // Set local and remote description.
+  // The parsed_sdp argument must be passed in with std::move.
   virtual void SetLocalDescription(blink::RTCVoidRequest* request,
-                                   RTCSessionDescriptionPlatform* description);
+                                   ParsedSessionDescription parsed_sdp);
   virtual void SetRemoteDescription(blink::RTCVoidRequest* request,
-                                    RTCSessionDescriptionPlatform* description);
+                                    ParsedSessionDescription parsed_sdp);
 
   virtual const webrtc::PeerConnectionInterface::RTCConfiguration&
   GetConfiguration() const;
@@ -320,11 +372,6 @@
     kFailure,
   };
 
-  webrtc::SessionDescriptionInterface* CreateNativeSessionDescription(
-      const String& sdp,
-      const String& type,
-      webrtc::SdpParseError* error);
-
   RTCSessionDescriptionPlatform*
   GetRTCSessionDescriptionPlatformOnSignalingThread(
       CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
index e321466f..5c821af 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h"
 #include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h"
 #include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
 #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
@@ -662,8 +663,6 @@
 }
 
 TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
-  auto* description = MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-      kDummySdpType, kDummySdp);
   // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
   // before |mock_peer_connection| is called.
   testing::InSequence sequence;
@@ -673,7 +672,9 @@
                                          PeerConnectionTracker::SOURCE_LOCAL));
   EXPECT_CALL(*mock_peer_connection_, SetLocalDescriptionForMock(_, _));
 
-  pc_handler_->SetLocalDescription(nullptr /*RTCVoidRequest*/, description);
+  pc_handler_->SetLocalDescription(
+      nullptr /*RTCVoidRequest*/,
+      MockParsedSessionDescription(kDummySdpType, kDummySdp));
   RunMessageLoopsUntilIdle();
 
   std::string sdp_string;
@@ -706,14 +707,12 @@
 
   // Used to simulate a parse failure.
   mock_dependency_factory_->SetFailToCreateSessionDescription(true);
-  pc_handler_->SetLocalDescription(nullptr /*RTCVoidRequest*/, description);
+  pc_handler_->SetLocalDescription(
+      nullptr /*RTCVoidRequest*/, ParsedSessionDescription::Parse(description));
   RunMessageLoopsUntilIdle();
 }
 
 TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
-  auto* description = MakeGarbageCollected<RTCSessionDescriptionPlatform>(
-      kDummySdpType, kDummySdp);
-
   // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
   // before |mock_peer_connection| is called.
   testing::InSequence sequence;
@@ -723,7 +722,9 @@
                                          PeerConnectionTracker::SOURCE_REMOTE));
   EXPECT_CALL(*mock_peer_connection_, SetRemoteDescriptionForMock(_, _));
 
-  pc_handler_->SetRemoteDescription(nullptr /*RTCVoidRequest*/, description);
+  pc_handler_->SetRemoteDescription(
+      nullptr /*RTCVoidRequest*/,
+      MockParsedSessionDescription(kDummySdpType, kDummySdp));
   RunMessageLoopsUntilIdle();
 
   std::string sdp_string;
@@ -756,7 +757,8 @@
 
   // Used to simulate a parse failure.
   mock_dependency_factory_->SetFailToCreateSessionDescription(true);
-  pc_handler_->SetRemoteDescription(nullptr /*RTCVoidRequest*/, description);
+  pc_handler_->SetRemoteDescription(
+      nullptr /*RTCVoidRequest*/, ParsedSessionDescription::Parse(description));
   RunMessageLoopsUntilIdle();
 }
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
index 1e6208438..1417fe37 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
@@ -584,22 +584,27 @@
   RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create();
   sdp->setType("offer");
   sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kUnifiedPlanExplicitSemantics);
   sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kPlanBExplicitSemantics);
   sdp->setSdp("invalid sdp");
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kErrorExplicitSemantics);
   // No Complex SDP is detected if only a single track per m= section is used.
   sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
   sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
 }
 
 TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnifiedPlan) {
@@ -608,22 +613,27 @@
   RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create();
   sdp->setType("offer");
   sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kUnifiedPlanExplicitSemantics);
   sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kPlanBExplicitSemantics);
   sdp->setSdp("invalid sdp");
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kErrorExplicitSemantics);
   // No Complex SDP is detected if only a single track per m= section is used.
   sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
   sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
 }
 
 TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnspecified) {
@@ -632,22 +642,27 @@
   RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create();
   sdp->setType("offer");
   sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kPlanBImplicitSemantics);
   sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kUnifiedPlanImplicitSemantics);
   sdp->setSdp("invalid sdp");
-  ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value());
-  ASSERT_EQ(pc->CheckForComplexSdp(sdp),
+  ASSERT_TRUE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
+  ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)),
             ComplexSdpCategory::kErrorImplicitSemantics);
   // No Complex SDP is detected if only a single track per m= section is used.
   sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
   sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
-  ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
+  ASSERT_FALSE(
+      pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value());
 }
 
 TEST_F(RTCPeerConnectionTest, CheckInsertableStreamsConfig) {
@@ -746,12 +761,12 @@
   }
 
   void SetLocalDescription(RTCVoidRequest* request,
-                           RTCSessionDescriptionPlatform*) override {
+                           ParsedSessionDescription) override {
     PostToCompleteRequest<RTCVoidRequest>(async_operation_action_, request);
   }
 
   void SetRemoteDescription(RTCVoidRequest* request,
-                            RTCSessionDescriptionPlatform*) override {
+                            ParsedSessionDescription) override {
     PostToCompleteRequest<RTCVoidRequest>(async_operation_action_, request);
   }
 
@@ -1058,22 +1073,26 @@
   // If the default is Plan B.
   EXPECT_EQ(
       SdpUsageCategory::kSafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBSingleAudioSingleVideo),
                              false, webrtc::SdpSemantics::kPlanB));
   // If the default is Unified Plan.
   EXPECT_EQ(
       SdpUsageCategory::kSafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBSingleAudioSingleVideo),
                              false, webrtc::SdpSemantics::kUnifiedPlan));
   // If sdpSemantics is explicitly set to Plan B.
   EXPECT_EQ(
       SdpUsageCategory::kSafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBSingleAudioSingleVideo),
                              true, webrtc::SdpSemantics::kPlanB));
   // If sdpSemantics is explicitly set to Unified Plan.
   EXPECT_EQ(
       SdpUsageCategory::kSafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBSingleAudioSingleVideo),
                              true, webrtc::SdpSemantics::kUnifiedPlan));
 }
 
@@ -1082,72 +1101,88 @@
 TEST(DeduceSdpUsageCategory, SimpleUnifiedPlanIsAlwaysSafe) {
   // If the default is Plan B.
   EXPECT_EQ(SdpUsageCategory::kSafe,
-            DeduceSdpUsageCategory("offer",
-                                   kOfferSdpUnifiedPlanSingleAudioSingleVideo,
-                                   false, webrtc::SdpSemantics::kPlanB));
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo),
+                false, webrtc::SdpSemantics::kPlanB));
   // If the default is Unified Plan.
   EXPECT_EQ(SdpUsageCategory::kSafe,
-            DeduceSdpUsageCategory("offer",
-                                   kOfferSdpUnifiedPlanSingleAudioSingleVideo,
-                                   false, webrtc::SdpSemantics::kUnifiedPlan));
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo),
+                false, webrtc::SdpSemantics::kUnifiedPlan));
   // If sdpSemantics is explicitly set to Plan B.
   EXPECT_EQ(SdpUsageCategory::kSafe,
-            DeduceSdpUsageCategory("offer",
-                                   kOfferSdpUnifiedPlanSingleAudioSingleVideo,
-                                   true, webrtc::SdpSemantics::kPlanB));
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo),
+                true, webrtc::SdpSemantics::kPlanB));
   // If sdpSemantics is explicitly set to Unified Plan.
   EXPECT_EQ(SdpUsageCategory::kSafe,
-            DeduceSdpUsageCategory("offer",
-                                   kOfferSdpUnifiedPlanSingleAudioSingleVideo,
-                                   true, webrtc::SdpSemantics::kUnifiedPlan));
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo),
+                true, webrtc::SdpSemantics::kUnifiedPlan));
 }
 
 // Test that complex SDP is always unsafe when relying on default sdpSemantics.
 TEST(DeduceSdpUsageCategory, ComplexSdpIsAlwaysUnsafeWithDefaultSdpSemantics) {
   // If the default is Plan B and the SDP is complex Plan B.
-  EXPECT_EQ(SdpUsageCategory::kUnsafe,
-            DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks,
-                                   false, webrtc::SdpSemantics::kPlanB));
-  // If the default is Plan B and the SDP is complex Unified Plan.
   EXPECT_EQ(
       SdpUsageCategory::kUnsafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBMultipleAudioTracks),
                              false, webrtc::SdpSemantics::kPlanB));
-  // If the default is Unified Plan and the SDP is complex Plan B.
+  // If the default is Plan B and the SDP is complex Unified Plan.
   EXPECT_EQ(SdpUsageCategory::kUnsafe,
-            DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks,
-                                   false, webrtc::SdpSemantics::kUnifiedPlan));
-  // If the default is Unified Plan and the SDP is complex UNified Plan.
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanMultipleAudioTracks),
+                false, webrtc::SdpSemantics::kPlanB));
+  // If the default is Unified Plan and the SDP is complex Plan B.
   EXPECT_EQ(
       SdpUsageCategory::kUnsafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBMultipleAudioTracks),
                              false, webrtc::SdpSemantics::kUnifiedPlan));
+  // If the default is Unified Plan and the SDP is complex UNified Plan.
+  EXPECT_EQ(SdpUsageCategory::kUnsafe,
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanMultipleAudioTracks),
+                false, webrtc::SdpSemantics::kUnifiedPlan));
 }
 
 // Test that when sdpSemantics is explicitly set, complex SDP is safe if it is
 // of the same format and unsafe if the format is different.
 TEST(DeduceSdpUsageCategory, ComplexSdpIsSafeIfMatchingExplicitSdpSemantics) {
   // If sdpSemantics is explicitly set to Plan B and the SDP is complex Plan B.
-  EXPECT_EQ(SdpUsageCategory::kSafe,
-            DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks,
-                                   true, webrtc::SdpSemantics::kPlanB));
-  // If sdpSemantics is explicitly set to Unified Plan and the SDP is complex
-  // Unified Plan.
   EXPECT_EQ(
       SdpUsageCategory::kSafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks,
-                             true, webrtc::SdpSemantics::kUnifiedPlan));
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBMultipleAudioTracks),
+                             true, webrtc::SdpSemantics::kPlanB));
+  // If sdpSemantics is explicitly set to Unified Plan and the SDP is complex
+  // Unified Plan.
+  EXPECT_EQ(SdpUsageCategory::kSafe,
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanMultipleAudioTracks),
+                true, webrtc::SdpSemantics::kUnifiedPlan));
   // If the sdpSemantics is explicitly set to Plan B but the SDP is complex
   // Unified Plan.
-  EXPECT_EQ(
-      SdpUsageCategory::kUnsafe,
-      DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks,
-                             true, webrtc::SdpSemantics::kPlanB));
+  EXPECT_EQ(SdpUsageCategory::kUnsafe,
+            DeduceSdpUsageCategory(
+                ParsedSessionDescription::Parse(
+                    "offer", kOfferSdpUnifiedPlanMultipleAudioTracks),
+                true, webrtc::SdpSemantics::kPlanB));
   // If the sdpSemantics is explicitly set to Unified Plan but the SDP is
   // complex Plan B.
-  EXPECT_EQ(SdpUsageCategory::kUnsafe,
-            DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks,
-                                   true, webrtc::SdpSemantics::kUnifiedPlan));
+  EXPECT_EQ(
+      SdpUsageCategory::kUnsafe,
+      DeduceSdpUsageCategory(ParsedSessionDescription::Parse(
+                                 "offer", kOfferSdpPlanBMultipleAudioTracks),
+                             true, webrtc::SdpSemantics::kUnifiedPlan));
 }
 
 TEST_F(RTCPeerConnectionTest, MediaStreamTrackStopsThrottling) {
diff --git a/third_party/blink/renderer/modules/url_pattern/DIR_METADATA b/third_party/blink/renderer/modules/url_pattern/DIR_METADATA
index f0962523..76f0164 100644
--- a/third_party/blink/renderer/modules/url_pattern/DIR_METADATA
+++ b/third_party/blink/renderer/modules/url_pattern/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
-  component: "Blink>ServiceWorker"
+  component: "Blink>URLPattern"
 }
-team_email: "worker-dev@chromium.org"
\ No newline at end of file
+team_email: "worker-dev@chromium.org"
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 3928e9e..2fb40d2 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -505,6 +505,8 @@
     DCHECK(pending_req);
     if (pending_req->resolver)
       pending_req->resolver.Release()->Resolve();
+    if (pending_req->frame)
+      pending_req->frame.Release()->destroy();
   }
   stall_request_processing_ = false;
 }
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 ef54efd..bd6db3af2 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -467,7 +467,11 @@
 
 void WebSocketChannelImpl::OnFailure(const WTF::String& message,
                                      int net_error,
-                                     int response_code) {}
+                                     int response_code) {
+  NETWORK_DVLOG(1) << this << " OnFailure(" << message << ", " << net_error
+                   << ", " << response_code << ")";
+  failure_message_ = message;
+}
 
 void WebSocketChannelImpl::OnConnectionEstablished(
     mojo::PendingRemote<network::mojom::blink::WebSocket> websocket,
@@ -1078,11 +1082,13 @@
                                              const std::string& description) {
   DCHECK_NE(GetState(), State::kDisconnected);
   NETWORK_DVLOG(1) << " OnConnectionError("
-                   << " reason: " << custom_reason
                    << ", description:" << description
+                   << ", failure_message:" << failure_message_
                    << "), set_from:" << set_from.ToString();
-  String message = "Unknown reason";
-  if (custom_reason == network::mojom::blink::WebSocket::kInternalFailure) {
+  String message;
+  if (description.empty()) {
+    message = failure_message_;
+  } else {
     message = String::FromUTF8(description.c_str(), description.size());
   }
 
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
index 54f07d8f..67b62299 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -316,6 +316,7 @@
   size_t sent_size_of_top_message_ = 0;
   FrameScheduler::SchedulingAffectingFeatureHandle
       feature_handle_for_scheduler_;
+  WTF::String failure_message_;
 
   const std::unique_ptr<const SourceLocation> location_at_construction_;
   network::mojom::blink::WebSocketHandshakeRequestPtr handshake_request_;
diff --git a/third_party/blink/renderer/modules/xr/xr_cube_map.cc b/third_party/blink/renderer/modules/xr/xr_cube_map.cc
index 1d8aff9..f9c654d 100644
--- a/third_party/blink/renderer/modules/xr/xr_cube_map.cc
+++ b/third_party/blink/renderer/modules/xr/xr_cube_map.cc
@@ -27,8 +27,8 @@
 // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_framebuffer_sRGB.txt
 uint8_t LinearToSrgb(float cl) {
   float cs = base::ClampToRange(
-      cl < 0.0031308f ? 12.92f * cl : 1.055f * pow(cl, 0.41666f) - 0.055f, 0.0f,
-      1.0f);
+      cl < 0.0031308f ? 12.92f * cl : 1.055f * std::pow(cl, 0.41666f) - 0.055f,
+      0.0f, 1.0f);
   return static_cast<uint8_t>(255.0f * cs + 0.5f);
 }
 
diff --git a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
index 6bbc2dd1..06524fe 100644
--- a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
+++ b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/fonts/font_matching_metrics.h"
 
+#include "base/metrics/histogram_macros.h"
 #include "services/metrics/public/cpp/metrics_utils.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
@@ -318,6 +319,8 @@
       .SetLocalFontSuccesses(ukm::GetExponentialBucketMin(
           local_fonts_succeeded_.size(), kUkmFontLoadCountBucketSpacing))
       .Record(ukm_recorder_);
+  UMA_HISTOGRAM_COUNTS_10000("Blink.Fonts.FontFamilyMatchAttempts.System",
+                             system_font_families_.size());
 }
 
 void FontMatchingMetrics::OnFontLookup() {
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h b/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
index cac5d130..1a2e67b 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
@@ -17,10 +17,10 @@
  public:
   RTCSessionDescriptionPlatform(const String& type, const String& sdp);
 
-  String GetType() { return type_; }
+  String GetType() const { return type_; }
   void SetType(const String& type) { type_ = type; }
 
-  String Sdp() { return sdp_; }
+  String Sdp() const { return sdp_; }
   void SetSdp(const String& sdp) { sdp_ = sdp; }
 
   void Trace(Visitor* visitor) const {}
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index ac3bd6f..e167fbc 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -225,10 +225,6 @@
       settable_from_internals: true,
     },
     {
-      name: "AzimuthAltitude",
-      status: "stable",
-    },
-    {
       name: "BackForwardCache",
     },
     {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index c2aa6bc..4868df6a0 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -1351,8 +1351,7 @@
 FrameSchedulerImpl::DeferrableTaskQueueTraits() {
   return QueueTraits()
       .SetCanBeDeferred(true)
-      .SetCanBeFrozen(base::FeatureList::IsEnabled(
-          blink::features::kStopNonTimersInBackground))
+      .SetCanBeFrozen(true)
       .SetCanBePaused(true)
       .SetCanRunWhenVirtualTimePaused(false)
       .SetCanBePausedForAndroidWebview(true);
@@ -1361,8 +1360,7 @@
 // static
 MainThreadTaskQueue::QueueTraits FrameSchedulerImpl::PausableTaskQueueTraits() {
   return QueueTraits()
-      .SetCanBeFrozen(base::FeatureList::IsEnabled(
-          blink::features::kStopNonTimersInBackground))
+      .SetCanBeFrozen(true)
       .SetCanBePaused(true)
       .SetCanRunWhenVirtualTimePaused(false)
       .SetCanBePausedForAndroidWebview(true);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index da9593f..d7c1ee70 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -430,22 +430,6 @@
   scoped_refptr<MainThreadTaskQueue> throttleable_task_queue_;
 };
 
-class FrameSchedulerImplStopNonTimersInBackgroundEnabledTest
-    : public FrameSchedulerImplTest {
- public:
-  FrameSchedulerImplStopNonTimersInBackgroundEnabledTest()
-      : FrameSchedulerImplTest({blink::features::kStopNonTimersInBackground},
-                               {}) {}
-};
-
-class FrameSchedulerImplStopNonTimersInBackgroundDisabledTest
-    : public FrameSchedulerImplTest {
- public:
-  FrameSchedulerImplStopNonTimersInBackgroundDisabledTest()
-      : FrameSchedulerImplTest({},
-                               {blink::features::kStopNonTimersInBackground}) {}
-};
-
 class FrameSchedulerImplStopInBackgroundDisabledTest
     : public FrameSchedulerImplTest,
       public ::testing::WithParamInterface<TaskType> {
@@ -857,8 +841,7 @@
   EXPECT_EQ(1, counter);
 }
 
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
-       PageFreezeAndUnfreezeFlagEnabled) {
+TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreeze) {
   int counter = 0;
   LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
       FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -882,13 +865,13 @@
   page_scheduler_->SetPageFrozen(false);
 
   EXPECT_EQ(1, counter);
-  // Same as RunUntilIdle but also advances the clock if necessary.
   task_environment_.FastForwardUntilNoTasksRemain();
   EXPECT_EQ(5, counter);
 }
 
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundDisabledTest,
-       PageFreezeAndUnfreezeFlagDisabled) {
+// Similar to PageFreezeAndUnfreeze, but unfreezes task queues by making the
+// page visible instead of by invoking SetPageFrozen(false).
+TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) {
   int counter = 0;
   LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
       FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -906,13 +889,13 @@
 
   EXPECT_EQ(0, counter);
   base::RunLoop().RunUntilIdle();
-  // throttleable tasks and loading tasks are frozen, others continue to run.
-  EXPECT_EQ(3, counter);
+  // unpausable tasks continue to run.
+  EXPECT_EQ(1, counter);
 
-  page_scheduler_->SetPageFrozen(false);
+  // Making the page visible should cause frozen queues to resume.
+  page_scheduler_->SetPageVisible(true);
 
-  EXPECT_EQ(3, counter);
-  // Same as RunUntilIdle but also advances the clock if necessary.
+  EXPECT_EQ(1, counter);
   task_environment_.FastForwardUntilNoTasksRemain();
   EXPECT_EQ(5, counter);
 }
@@ -1048,35 +1031,6 @@
                          LoadingTaskQueue()->GetTaskQueue()->GetName())));
 }
 
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
-       PageFreezeAndPageVisible) {
-  int counter = 0;
-  LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
-      FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-  ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
-      FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-  DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
-      FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-  PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
-      FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-  UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
-      FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-
-  page_scheduler_->SetPageVisible(false);
-  page_scheduler_->SetPageFrozen(true);
-
-  EXPECT_EQ(0, counter);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1, counter);
-
-  // Making the page visible should cause frozen queues to resume.
-  page_scheduler_->SetPageVisible(true);
-
-  EXPECT_EQ(1, counter);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(5, counter);
-}
-
 class FrameSchedulerImplTestWithUnfreezableLoading
     : public FrameSchedulerImplTest {
  public:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
index f5f478dd..d5fe56d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -287,17 +287,6 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-class PageSchedulerImplStopNonTimersInBackgroundEnabledTest
-    : public PageSchedulerImplTest {
- public:
-  PageSchedulerImplStopNonTimersInBackgroundEnabledTest()
-      : PageSchedulerImplTest({blink::features::kStopInBackground,
-                               blink::features::kStopNonTimersInBackground},
-                              {}) {}
-
-  ~PageSchedulerImplStopNonTimersInBackgroundEnabledTest() override = default;
-};
-
 TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersBefore) {
   std::unique_ptr<blink::FrameScheduler> frame1(
       page_scheduler_->CreateFrameScheduler(
@@ -1320,15 +1309,13 @@
 // Verify that freezing a page prevents tasks in its task queues from running.
 // Then, verify that making the page visible unfreezes it and allows tasks in
 // its task queues to run.
-TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
-       PageFreezeAndSetVisible) {
+TEST_F(PageSchedulerImplTest, PageFreezeAndSetVisible) {
   TestFreeze(true);
 }
 
 // Same as before, but unfreeze the page explicitly instead of making it
 // visible.
-TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
-       PageFreezeAndUnfreeze) {
+TEST_F(PageSchedulerImplTest, PageFreezeAndUnfreeze) {
   TestFreeze(false);
 }
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index d565972..ec726cfbd 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -4076,8 +4076,6 @@
 crbug.com/689781 [ Win ] http/tests/media/media-source/mediasource-duration.html [ Failure Pass ]
 crbug.com/689781 [ Mac ] http/tests/media/media-source/mediasource-duration.html [ Failure Pass ]
 
-crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
-crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ]
 crbug.com/681468 [ Win ] virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure Pass Timeout ]
 crbug.com/681468 [ Win ] virtual/scalefactor200withzoom/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure Pass Timeout ]
 crbug.com/681468 [ Win ] virtual/scalefactor200/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure Pass Timeout ]
@@ -5261,10 +5259,6 @@
 crbug.com/1045472 external/wpt/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https.html [ Pass Failure ]
 crbug.com/1045472 external/wpt/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.https.worker.html [ Pass Failure ]
 
-crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance.html [ Pass Failure ]
-crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
-crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
-
 crbug.com/1046784 http/tests/devtools/oopif/oopif-storage.js [ Pass Failure ]
 crbug.com/1046784 http/tests/inspector-protocol/service-worker/target-reloaded-after-crash.js [ Pass Failure Timeout ]
 
@@ -5822,6 +5816,10 @@
 crbug.com/1130020 virtual/scroll-unification/fast/scrolling/scrollbars/scrollbar-mousedown-move-mouseup.html [ Pass Failure Timeout ]
 crbug.com/1130020 virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-mousedown-move-mouseup.html [ Pass Failure Timeout ]
 
+# Disable tests temporarily for devtools frontend check-in
+crbug.com/1159502 http/tests/devtools/service-workers/service-workers-view.js [ Pass Failure ]
+crbug.com/1159502 http/tests/devtools/service-workers/service-workers-redundant.js [ Pass Failure ]
+
 # Sheriff 2020-11-16
 crbug.com/1149734 http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Pass Failure Timeout ]
 crbug.com/1149734 http/tests/devtools/sources/debugger-ui/reveal-execution-line.js [ Pass Failure Timeout ]
@@ -5866,6 +5864,22 @@
 skbug.com/11019 virtual/gpu-rasterization/images/yuv-decode-eligible/color-profile-filter.html [ Pass Failure ]
 skbug.com/11019 virtual/gpu-rasterization/images/yuv-decode-eligible/color-profile-image.html [ Pass Failure ]
 
+# Win7 suggestion picker appearance tests have a scrollbar flakiness issue
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-locale-hebrew.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+crbug.com/1045510 [ Win7 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
+
+crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
+crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ]
 
 # These tests will only run in the virtual test suite where the frequency
 # capping for overlay popup detection is disabled. This eliminates the need
@@ -5901,16 +5915,7 @@
 crbug.com/626703 [ Linux ] wpt_internal/storage/estimate-usage-details-filesystem.https.tentative.any.html [ Pass Failure ]
 crbug.com/626703 [ Mac ] external/wpt/mediacapture-image/MediaStreamTrack-getConstraints.https.html [ Pass Failure ]
 
-# WPT importer Sheriff 2020-12-14
-crbug.com/1158672 [ Mac ] external/wpt/html/dom/idlharness.https.html?include=(Document|Window) [ Pass Failure ]
-
 # Sheriff 2020-12-14
 crbug.com/1046784 http/tests/devtools/console/console-context-selector.js [ Pass Timeout ]
 
-# Sheriff 2020-12-17
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-with-scroll-bar.html [ Pass Failure ]
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew.html [ Pass Failure ]
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Pass Failure ]
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl.html [ Pass Failure ]
-crbug.com/1043488 [ Win7 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl.html [ Pass Failure ]
+
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 6b0b6033..abfff766 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -255573,7 +255573,7 @@
       []
      ],
      "requirements.txt": [
-      "d83f5eb89fab1eb9734a90d262e21c33fa162a1f",
+      "a387544f3475cc88f93ca13ba13422cf1f208198",
       []
      ],
      "revlist.py": [
@@ -255619,7 +255619,7 @@
       []
      ],
      "requirements.txt": [
-      "a266c322e2cf453221e4a11e4302879e413baa94",
+      "5cfa9f3faf9c0088348c78b4030df450989066b7",
       []
      ],
      "requirements_android_webview.txt": [
@@ -255667,7 +255667,7 @@
       []
      ],
      "requirements_sauce.txt": [
-      "47e268df17307a701bd966a9dbe89c3d542d8d3b",
+      "eae7ef3f004852071565e769edd87809194829b5",
       []
      ],
      "requirements_servo.txt": [
@@ -255733,7 +255733,7 @@
         []
        ],
        "edgechromium.py": [
-        "67105e425c794c32cd99f8216418d47e640dc7ba",
+        "1d45983a11ef0d3fdcfabd6e81fe2974ab2d68eb",
         []
        ],
        "epiphany.py": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-fill-balance-006.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-fill-balance-006.html
new file mode 100644
index 0000000..3dc2022a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-fill-balance-006.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-multicol-1/#filling-columns">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="float:left; width:50px; height:100px; background:green;"></div>
+<div style="float:left; width:50px; background:green;">
+  <div style="columns:2; width:0;">
+    <div style="height:200px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-handlers-changed-expected.txt b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-handlers-changed-expected.txt
deleted file mode 100644
index 4e26515..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-handlers-changed-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-FAIL  Dispatch additional events inside an event listener  assert_array_equals: actual_targets lengths differ, expected array [object "[object Window]", Document node with 2 children, Element node <html><head><meta charset="utf-8">
-<title> Dispatch addit..., Element node <body><div id="log"></div>
-
-<table id="table" border="1" ..., Element node <table id="table" border="1" style="display: none">
-    <..., Element node <tbody id="table-body">
-    <tr id="table-row">
-        <..., Element node <tr id="parent">
-        <td id="target">Over the river, ..., Element node <td id="target">Over the river, Charlie</td>, [...], [...], [...], [...], [...], [...], [...], [...], [...]] length 17, got [object "[object Window]", Document node with 2 children, Element node <html><head><meta charset="utf-8">
-<title> Dispatch addit..., Element node <body><div id="log"></div>
-
-<table id="table" border="1" ..., Element node <table id="table" border="1" style="display: none">
-    <..., Element node <tbody id="table-body">
-    <tr id="table-row">
-        <..., Element node <tr id="parent">
-        <td id="target">Over the river, ..., Element node <td id="target">Over the river, Charlie</td>, [...], [...], [...], [...], [...], [...], [...], [...]] length 16
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-listener-order.window-expected.txt b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-listener-order.window-expected.txt
deleted file mode 100644
index 65eec96..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-listener-order.window-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Event-dispatch-listener-order assert_array_equals: expected property 4 to be "capturing SPAN" but got "bubbling SPAN" (expected array ["capturing SECTION", "capturing DIV", "capturing #document-fragment", "capturing P", "capturing SPAN", "bubbling SPAN", "bubbling P", "bubbling #document-fragment", "bubbling DIV", "bubbling SECTION"] got ["capturing SECTION", "capturing DIV", "capturing #document-fragment", "capturing P", "bubbling SPAN", "capturing SPAN", "bubbling P", "bubbling #document-fragment", "bubbling DIV", "bubbling SECTION"])
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-order-at-target-expected.txt b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-order-at-target-expected.txt
deleted file mode 100644
index ad4f3809..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-order-at-target-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Listeners are invoked in correct order (AT_TARGET phase) assert_array_equals: bubbles: true expected property 0 to be "capturing" but got "bubbling" (expected array ["capturing", "bubbling"] got ["bubbling", "capturing"])
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-stopPropagation-cancel-bubbling.html b/third_party/blink/web_tests/external/wpt/dom/events/Event-stopPropagation-cancel-bubbling.html
new file mode 100644
index 0000000..5c2c49f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/events/Event-stopPropagation-cancel-bubbling.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" title="Joey Arhar" href="mailto:jarhar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+test(t => {
+  const element = document.createElement('div');
+
+  element.addEventListener('click', () => {
+    event.stopPropagation();
+  }, { capture: true });
+
+  element.addEventListener('click',
+    t.unreached_func('stopPropagation in the capture handler should have canceled this bubble handler.'));
+
+  element.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/EventTarget-dispatchEvent-expected.txt b/third_party/blink/web_tests/external/wpt/dom/events/EventTarget-dispatchEvent-expected.txt
deleted file mode 100644
index 0e719cd..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/events/EventTarget-dispatchEvent-expected.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-This is a testharness.js-based test.
-PASS Calling dispatchEvent(null).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (BeforeUnloadEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (CompositionEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (CustomEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (DeviceMotionEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (DeviceOrientationEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (DragEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (Event).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (Events).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (FocusEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (HashChangeEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (HTMLEvents).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (KeyboardEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (MessageEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (MouseEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (MouseEvents).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (StorageEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (SVGEvents).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (TextEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (TouchEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (UIEvent).
-PASS If the event's initialized flag is not set, an InvalidStateError must be thrown (UIEvents).
-PASS If the event's dispatch flag is set, an InvalidStateError must be thrown.
-PASS Exceptions from event listeners must not be propagated.
-PASS Event listeners added during dispatch should be called
-FAIL Capturing event listeners should be called before non-capturing ones assert_array_equals: expected property 1 to be 3 but got 2 (expected array [1, 3, 2] got [1, 2, 3])
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees-expected.txt b/third_party/blink/web_tests/external/wpt/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees-expected.txt
deleted file mode 100644
index 13b5ae9d..0000000
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Capturing event listeners should be invoked before bubbling event listeners on the target without shadow trees assert_object_equals: property "0" expected "capturing" got "bubbling"
-FAIL Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched inside a shadow tree assert_object_equals: property "0" expected "capturing" got "bubbling"
-FAIL Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched inside a doubly nested shadow tree assert_object_equals: property "0" expected "capturing" got "bubbling"
-FAIL Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched via a slot assert_object_equals: property "0" expected "capturing" got "bubbling"
-FAIL Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched inside a shadow tree which passes through another shadow tree assert_object_equals: property "0" expected "capturing" got "bubbling"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wpt/requirements.txt
index d83f5eb8..a387544 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wpt/requirements.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wpt/requirements.txt
@@ -1,2 +1,2 @@
-requests==2.25.0
+requests==2.25.1
 mozinfo==1.2.1  # https://bugzilla.mozilla.org/show_bug.cgi?id=1621226
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
index a266c32..5cfa9f3 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
@@ -6,5 +6,5 @@
 pillow==6.2.2; python_version <= '2.7'  # pyup: <7.0
 pillow==8.0.1; python_version >= '3.0'
 urllib3[secure]==1.26.2
-requests==2.25.0
+requests==2.25.1
 six==1.15.0
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_sauce.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_sauce.txt
index 47e268d..eae7ef3 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_sauce.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_sauce.txt
@@ -1,3 +1,3 @@
 mozprocess==1.2.1
 selenium==3.141.0
-requests==2.25.0
+requests==2.25.1
diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
index 5a1a3ec..fe38505 100644
--- a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
+++ b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
@@ -650,6 +650,14 @@
     }
   },
   {
+    "pattern": { "protocol": "foo-bar" },
+    "input": { "protocol": "foo-bar" },
+    "expected": {
+      "input": { "protocol": "foo-bar" },
+      "protocol": { "input": "foo-bar", "groups": {} }
+    }
+  },
+  {
     "pattern": { "username": "caf%C3%A9" },
     "input": { "username" : "café" },
     "expected": {
@@ -684,24 +692,6 @@
     }
   },
   {
-    "pattern": { "hostname": "cafe%7C.com" },
-    "input": { "hostname" : "cafe|.com" },
-    "expected": {
-      "input": { "hostname" : "cafe|.com" },
-      "hostname": { "input": "cafe%7C.com", "groups": {}}
-    }
-  },
-  {
-    "pattern": { "hostname": "cafe%7c.com" },
-    "input": { "hostname" : "cafe|.com" },
-    "expected": null
-  },
-  {
-    "pattern": { "hostname": "(.*)" },
-    "input": { "hostname" : "cafe^.com" },
-    "expected": null
-  },
-  {
     "pattern": { "port": "" },
     "input": { "protocol": "http", "port": "80" },
     "expected": {
diff --git a/third_party/blink/web_tests/fast/forms/select/options-default-white-space.html b/third_party/blink/web_tests/fast/forms/select/options-default-white-space.html
new file mode 100644
index 0000000..78c47861
--- /dev/null
+++ b/third_party/blink/web_tests/fast/forms/select/options-default-white-space.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+
+<select>
+  <option id=option value="hello">Hello</option>
+</select>
+
+<script>
+test(() => {
+  assert_equals(
+    window.getComputedStyle(option)['white-space'],
+    'nowrap');
+}, `<option>'s user agent 'white-space' should be 'nowrap'.`);
+</script>
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTracks.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTracks.html
new file mode 100644
index 0000000..09f0cff16
--- /dev/null
+++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTracks.html
@@ -0,0 +1,115 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>RTCPeerConnection.addTrack multiple times</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../external/wpt/webrtc/RTCPeerConnection-helper.js"></script>
+<script>
+
+'use strict';
+
+const reasonableNegotiationTimeMs = 1000; // 1 second
+const reasonableTotalTestTimeMs = 2000;  // The overall time for a test of this type is 10 secs, so timeout must be small
+
+function maybeLog(arg) {
+  // Uncomment to log performance data
+  // console.log(arg);
+}
+
+async function doNegotiation(caller, callee) {
+  const startTime = performance.now();
+  const offer = await caller.createOffer();
+  await caller.setLocalDescription(offer);
+  await callee.setRemoteDescription(offer);
+  const answer = await callee.createAnswer();
+  await callee.setLocalDescription(answer);
+  await caller.setRemoteDescription(answer);
+  return performance.now() - startTime;
+}
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const stream = await getNoiseStream({audio: true});
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+    const testStartTime = performance.now();
+    let timeTakenMs = 0;
+    let count = 0;
+    while (timeTakenMs < reasonableNegotiationTimeMs &&
+           performance.now() - testStartTime < reasonableTotalTestTimeMs) {
+      count += 1;
+      const transceiver = caller.addTrack(track.clone());
+      timeTakenMs = await doNegotiation(caller, callee);
+      maybeLog('Audio: Count ' + count +  ', timeTakenMs is ' + timeTakenMs);
+      assert_equals(callee.getReceivers().length, count);
+    }
+    assert_greater_than_equal(count, 9);
+  }, 'Adding multiple audio tracks with addTrack(), one at a time');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const stream = await getNoiseStream({audio: true});
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+    const kTrackCount = 10;
+    for (let count = 1; count <= kTrackCount; count++) {
+      const transceiver = caller.addTrack(track.clone());
+    }
+    const timeTakenMs = await doNegotiation(caller, callee);
+    assert_equals(caller.getSenders().length, kTrackCount);
+    assert_equals(callee.getReceivers().length, kTrackCount);
+    assert_less_than(timeTakenMs, reasonableNegotiationTimeMs);
+  }, 'Adding multiple audio tracks with addTrack(), all at once');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const stream = await getNoiseStream({video: true});
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+    const testStartTime = performance.now();
+    let timeTakenMs = 0;
+    let count = 0;
+    while (timeTakenMs < reasonableNegotiationTimeMs &&
+           performance.now() - testStartTime < reasonableTotalTestTimeMs) {
+      count += 1;
+      const transceiver = caller.addTrack(track.clone());
+      timeTakenMs = await doNegotiation(caller, callee);
+      maybeLog('Video: Count ' + count +  ', timeTakenMs is ' + timeTakenMs);
+      assert_equals(callee.getReceivers().length, count);
+    }
+    assert_greater_than_equal(count, 4);
+  }, 'Adding multiple video tracks with addTrack(), one at a time');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const stream = await getNoiseStream({video: true});
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+    const kTrackCount = 3;
+    for (let count = 1; count <= kTrackCount; count++) {
+      const transceiver = caller.addTrack(track.clone());
+    }
+    const timeTakenMs = await doNegotiation(caller, callee);
+    assert_equals(caller.getSenders().length, kTrackCount);
+    assert_equals(callee.getReceivers().length, kTrackCount);
+    assert_less_than(timeTakenMs, reasonableNegotiationTimeMs);
+  }, 'Adding multiple video tracks with addTrack(), all at once');
+
+</script>
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTransceivers.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTransceivers.html
new file mode 100644
index 0000000..44b6859e9
--- /dev/null
+++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-addMultipleTransceivers.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>RTCPeerConnection.addTransceiver multiple times</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../external/wpt/webrtc/RTCPeerConnection-helper.js"></script>
+<script>
+
+'use strict';
+
+const reasonableNegotiationTimeMs = 1000;
+const reasonableTotalTestTimeMs = 2000;  // The overall time for a test of this type is 10 secs, so timeout must be small
+
+function maybeLog(arg) {
+  // Uncomment to get performance recordings on console
+  // console.log(arg);
+}
+
+function noteTime(str, base) {
+  const nowTime = performance.now();
+  maybeLog(str + ' ' + (nowTime - base.old));
+  base.old = nowTime;
+}
+
+
+async function doNegotiation(caller, callee) {
+  const startTime = performance.now();
+  let curTime =  {old: startTime};
+  const offer = await caller.createOffer();
+  noteTime('caller.createOffer', curTime);
+  await caller.setLocalDescription(offer);
+  noteTime('caller.SLD', curTime);
+  await callee.setRemoteDescription(offer);
+  noteTime('callee.SRD', curTime);
+  const answer = await callee.createAnswer();
+  noteTime('callee.createAnswer', curTime);
+  await callee.setLocalDescription(answer);
+  noteTime('callee.SLD', curTime);
+  await caller.setRemoteDescription(answer);
+  noteTime('caller.SRD', curTime);
+  return performance.now() - startTime;
+}
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const testStartTime = performance.now();
+    let timeTakenMs = 0;
+    let count = 0;
+    while (timeTakenMs < reasonableNegotiationTimeMs &&
+           performance.now() - testStartTime < reasonableTotalTestTimeMs) {
+      count += 1;
+      caller.addTransceiver('audio');
+      timeTakenMs = await doNegotiation(caller, callee);
+      maybeLog('Audio: Count ' + count +  ', timeTakenMs is ' + timeTakenMs);
+      assert_equals(callee.getReceivers().length, count);
+    }
+    assert_greater_than_equal(count, 9);
+  }, 'Adding multiple audio tracks with AddTransceiver(), one at a time');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const kTrackCount = 10;
+    for (let count = 1; count <= kTrackCount; count++) {
+      caller.addTransceiver('audio');
+    }
+    const timeTakenMs = await doNegotiation(caller, callee);
+    assert_equals(caller.getSenders().length, kTrackCount);
+    assert_equals(callee.getReceivers().length, kTrackCount);
+    assert_less_than(timeTakenMs, reasonableNegotiationTimeMs);
+  }, 'Adding multiple audio tracks with AddTransceiver(), all at once');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const testStartTime = performance.now();
+    let timeTakenMs = 0;
+    let count = 0;
+    while (timeTakenMs < reasonableNegotiationTimeMs &&
+           performance.now() - testStartTime < reasonableTotalTestTimeMs) {
+      count += 1;
+      caller.addTransceiver('video');
+      timeTakenMs = await doNegotiation(caller, callee);
+      maybeLog('Video: Count ' + count +  ', timeTakenMs is ' + timeTakenMs);
+      assert_equals(callee.getReceivers().length, count);
+    }
+    assert_greater_than_equal(count, 4);
+  }, 'Adding multiple video tracks with AddTransceiver(), one at a time');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    const kTrackCount = 3;
+    for (let count = 1; count <= kTrackCount; count++) {
+      caller.addTransceiver('video');
+    }
+    const timeTakenMs = await doNegotiation(caller, callee);
+    assert_equals(caller.getSenders().length, kTrackCount);
+    assert_equals(callee.getReceivers().length, kTrackCount);
+    assert_less_than(timeTakenMs, reasonableNegotiationTimeMs);
+  }, 'Adding multiple video tracks with AddTransceiver(), all at once');
+
+</script>
diff --git a/third_party/blink/web_tests/http/tests/websocket/multiple-connections-throttled-expected.txt b/third_party/blink/web_tests/http/tests/websocket/multiple-connections-throttled-expected.txt
index d7ae331..1c36636 100644
--- a/third_party/blink/web_tests/http/tests/websocket/multiple-connections-throttled-expected.txt
+++ b/third_party/blink/web_tests/http/tests/websocket/multiple-connections-throttled-expected.txt
@@ -1,48 +1,48 @@
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
-CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Unknown reason
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
+CONSOLE ERROR: line 24: WebSocket connection to 'ws://127.0.0.1:8880/echo' failed: Insufficient resources
 Test that WebSocket connections are throttled.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git "a/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" "b/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
deleted file mode 100644
index d4fb556..0000000
--- "a/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
+++ /dev/null
@@ -1,969 +0,0 @@
-This is a testharness.js-based test.
-Found 965 tests; 954 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined
-PASS Partial interface mixin DocumentOrShadowRoot: member names are unique
-PASS Partial interface mixin NavigatorID: original interface mixin defined
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface HTMLAnchorElement: original interface defined
-PASS Partial interface HTMLAnchorElement: member names are unique
-PASS Partial interface HTMLAreaElement: original interface defined
-PASS Partial interface HTMLAreaElement: member names are unique
-PASS Partial interface HTMLBodyElement: original interface defined
-PASS Partial interface HTMLBodyElement: member names are unique
-PASS Partial interface HTMLBRElement: original interface defined
-PASS Partial interface HTMLBRElement: member names are unique
-PASS Partial interface HTMLTableCaptionElement: original interface defined
-PASS Partial interface HTMLTableCaptionElement: member names are unique
-PASS Partial interface HTMLTableColElement: original interface defined
-PASS Partial interface HTMLTableColElement: member names are unique
-PASS Partial interface HTMLDivElement: original interface defined
-PASS Partial interface HTMLDivElement: member names are unique
-PASS Partial interface HTMLDListElement: original interface defined
-PASS Partial interface HTMLDListElement: member names are unique
-PASS Partial interface HTMLEmbedElement: original interface defined
-PASS Partial interface HTMLEmbedElement: member names are unique
-PASS Partial interface HTMLHeadingElement: original interface defined
-PASS Partial interface HTMLHeadingElement: member names are unique
-PASS Partial interface HTMLHRElement: original interface defined
-PASS Partial interface HTMLHRElement: member names are unique
-PASS Partial interface HTMLHtmlElement: original interface defined
-PASS Partial interface HTMLHtmlElement: member names are unique
-PASS Partial interface HTMLIFrameElement: original interface defined
-PASS Partial interface HTMLIFrameElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface HTMLInputElement: original interface defined
-PASS Partial interface HTMLInputElement: member names are unique
-PASS Partial interface HTMLLegendElement: original interface defined
-PASS Partial interface HTMLLegendElement: member names are unique
-PASS Partial interface HTMLLIElement: original interface defined
-PASS Partial interface HTMLLIElement: member names are unique
-PASS Partial interface HTMLLinkElement: original interface defined
-PASS Partial interface HTMLLinkElement: member names are unique
-PASS Partial interface HTMLMenuElement: original interface defined
-PASS Partial interface HTMLMenuElement: member names are unique
-PASS Partial interface HTMLMetaElement: original interface defined
-PASS Partial interface HTMLMetaElement: member names are unique
-PASS Partial interface HTMLObjectElement: original interface defined
-PASS Partial interface HTMLObjectElement: member names are unique
-PASS Partial interface HTMLOListElement: original interface defined
-PASS Partial interface HTMLOListElement: member names are unique
-PASS Partial interface HTMLParagraphElement: original interface defined
-PASS Partial interface HTMLParagraphElement: member names are unique
-PASS Partial interface HTMLParamElement: original interface defined
-PASS Partial interface HTMLParamElement: member names are unique
-PASS Partial interface HTMLPreElement: original interface defined
-PASS Partial interface HTMLPreElement: member names are unique
-PASS Partial interface HTMLStyleElement: original interface defined
-PASS Partial interface HTMLStyleElement: member names are unique
-PASS Partial interface HTMLScriptElement: original interface defined
-PASS Partial interface HTMLScriptElement: member names are unique
-PASS Partial interface HTMLTableElement: original interface defined
-PASS Partial interface HTMLTableElement: member names are unique
-PASS Partial interface HTMLTableSectionElement: original interface defined
-PASS Partial interface HTMLTableSectionElement: member names are unique
-PASS Partial interface HTMLTableCellElement: original interface defined
-PASS Partial interface HTMLTableCellElement: member names are unique
-PASS Partial interface HTMLTableRowElement: original interface defined
-PASS Partial interface HTMLTableRowElement: member names are unique
-PASS Partial interface HTMLUListElement: original interface defined
-PASS Partial interface HTMLUListElement: member names are unique
-PASS Partial interface Document[2]: original interface defined
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes DocumentOrShadowRoot: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS HTMLLinkElement includes LinkStyle: member names are unique
-PASS HTMLStyleElement includes LinkStyle: member names are unique
-PASS HTMLBodyElement includes WindowEventHandlers: member names are unique
-PASS HTMLAnchorElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS HTMLAreaElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS CanvasRenderingContext2D includes CanvasState: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS CanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS CanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS CanvasRenderingContext2D includes CanvasUserInterface: member names are unique
-PASS CanvasRenderingContext2D includes CanvasText: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS Path2D includes CanvasPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasState: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasText: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS ElementInternals includes ARIAMixin: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS DedicatedWorkerGlobalScope includes AnimationFrameProvider: member names are unique
-PASS Worker includes AbstractWorker: member names are unique
-PASS SharedWorker includes AbstractWorker: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS HTMLFrameSetElement includes WindowEventHandlers: member names are unique
-PASS Element includes ARIAMixin: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS SVGElement includes GlobalEventHandlers: member names are unique
-PASS SVGElement includes DocumentAndElementEventHandlers: member names are unique
-PASS SVGElement includes SVGElementInstance: member names are unique
-PASS SVGElement includes HTMLOrSVGElement: member names are unique
-PASS SVGElement includes ElementCSSInlineStyle: member names are unique
-PASS SVGGraphicsElement includes SVGTests: member names are unique
-PASS SVGSVGElement includes SVGFitToViewBox: member names are unique
-PASS SVGSVGElement includes WindowEventHandlers: member names are unique
-PASS SVGImageElement includes SVGURIReference: member names are unique
-PASS SVGScriptElement includes SVGURIReference: member names are unique
-PASS SVGAElement includes SVGURIReference: member names are unique
-FAIL SVGAElement includes HTMLHyperlinkElementUtils: member names are unique assert_true: member href is unique expected true got false
-PASS DocumentFragment includes NonElementParentNode: member names are unique
-PASS DocumentFragment includes ParentNode: member names are unique
-PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique
-PASS Window interface: existence and properties of interface object
-PASS Window interface object length
-PASS Window interface object name
-PASS Window interface: existence and properties of interface prototype object
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window interface: existence and properties of interface prototype object's "constructor" property
-PASS Window interface: existence and properties of interface prototype object's @@unscopables property
-PASS Window interface: attribute self
-PASS Window interface: attribute name
-PASS Window interface: attribute history
-PASS Window interface: attribute customElements
-PASS Window interface: attribute locationbar
-PASS Window interface: attribute menubar
-PASS Window interface: attribute personalbar
-PASS Window interface: attribute scrollbars
-PASS Window interface: attribute statusbar
-PASS Window interface: attribute toolbar
-PASS Window interface: attribute status
-PASS Window interface: operation close()
-PASS Window interface: attribute closed
-PASS Window interface: operation stop()
-PASS Window interface: operation focus()
-PASS Window interface: operation blur()
-PASS Window interface: attribute frames
-PASS Window interface: attribute length
-PASS Window interface: attribute opener
-PASS Window interface: attribute parent
-PASS Window interface: attribute frameElement
-PASS Window interface: operation open(optional USVString, optional DOMString, optional DOMString)
-PASS Window interface: attribute navigator
-FAIL Window interface: attribute applicationCache assert_own_property: The global object must have a property "applicationCache" expected property "applicationCache" missing
-PASS Window interface: attribute originIsolated
-PASS Window interface: operation alert()
-PASS Window interface: operation alert(DOMString)
-PASS Window interface: operation confirm(optional DOMString)
-PASS Window interface: operation prompt(optional DOMString, optional DOMString)
-PASS Window interface: operation print()
-PASS Window interface: operation postMessage(any, USVString, optional sequence<object>)
-PASS Window interface: operation postMessage(any, optional WindowPostMessageOptions)
-PASS Window interface: operation captureEvents()
-PASS Window interface: operation releaseEvents()
-PASS Window interface: attribute external
-PASS Window interface: attribute onabort
-PASS Window interface: attribute onauxclick
-PASS Window interface: attribute onblur
-PASS Window interface: attribute oncancel
-PASS Window interface: attribute oncanplay
-PASS Window interface: attribute oncanplaythrough
-PASS Window interface: attribute onchange
-PASS Window interface: attribute onclick
-PASS Window interface: attribute onclose
-PASS Window interface: attribute oncontextmenu
-PASS Window interface: attribute oncuechange
-PASS Window interface: attribute ondblclick
-PASS Window interface: attribute ondrag
-PASS Window interface: attribute ondragend
-PASS Window interface: attribute ondragenter
-PASS Window interface: attribute ondragleave
-PASS Window interface: attribute ondragover
-PASS Window interface: attribute ondragstart
-PASS Window interface: attribute ondrop
-PASS Window interface: attribute ondurationchange
-PASS Window interface: attribute onemptied
-PASS Window interface: attribute onended
-PASS Window interface: attribute onerror
-PASS Window interface: attribute onfocus
-PASS Window interface: attribute onformdata
-PASS Window interface: attribute oninput
-PASS Window interface: attribute oninvalid
-PASS Window interface: attribute onkeydown
-PASS Window interface: attribute onkeypress
-PASS Window interface: attribute onkeyup
-PASS Window interface: attribute onload
-PASS Window interface: attribute onloadeddata
-PASS Window interface: attribute onloadedmetadata
-PASS Window interface: attribute onloadstart
-PASS Window interface: attribute onmousedown
-PASS Window interface: attribute onmouseenter
-PASS Window interface: attribute onmouseleave
-PASS Window interface: attribute onmousemove
-PASS Window interface: attribute onmouseout
-PASS Window interface: attribute onmouseover
-PASS Window interface: attribute onmouseup
-PASS Window interface: attribute onpause
-PASS Window interface: attribute onplay
-PASS Window interface: attribute onplaying
-PASS Window interface: attribute onprogress
-PASS Window interface: attribute onratechange
-PASS Window interface: attribute onreset
-PASS Window interface: attribute onresize
-PASS Window interface: attribute onscroll
-FAIL Window interface: attribute onsecuritypolicyviolation assert_own_property: The global object must have a property "onsecuritypolicyviolation" expected property "onsecuritypolicyviolation" missing
-PASS Window interface: attribute onseeked
-PASS Window interface: attribute onseeking
-PASS Window interface: attribute onselect
-FAIL Window interface: attribute onslotchange assert_own_property: The global object must have a property "onslotchange" expected property "onslotchange" missing
-PASS Window interface: attribute onstalled
-PASS Window interface: attribute onsubmit
-PASS Window interface: attribute onsuspend
-PASS Window interface: attribute ontimeupdate
-PASS Window interface: attribute ontoggle
-PASS Window interface: attribute onvolumechange
-PASS Window interface: attribute onwaiting
-PASS Window interface: attribute onwebkitanimationend
-PASS Window interface: attribute onwebkitanimationiteration
-PASS Window interface: attribute onwebkitanimationstart
-PASS Window interface: attribute onwebkittransitionend
-PASS Window interface: attribute onwheel
-PASS Window interface: attribute onafterprint
-PASS Window interface: attribute onbeforeprint
-PASS Window interface: attribute onbeforeunload
-PASS Window interface: attribute onhashchange
-PASS Window interface: attribute onlanguagechange
-PASS Window interface: attribute onmessage
-PASS Window interface: attribute onmessageerror
-PASS Window interface: attribute onoffline
-PASS Window interface: attribute ononline
-PASS Window interface: attribute onpagehide
-PASS Window interface: attribute onpageshow
-PASS Window interface: attribute onpopstate
-PASS Window interface: attribute onrejectionhandled
-PASS Window interface: attribute onstorage
-PASS Window interface: attribute onunhandledrejection
-PASS Window interface: attribute onunload
-PASS Window interface: attribute origin
-PASS Window interface: attribute isSecureContext
-PASS Window interface: attribute crossOriginIsolated
-PASS Window interface: operation btoa(DOMString)
-PASS Window interface: operation atob(DOMString)
-PASS Window interface: operation setTimeout(TimerHandler, optional long, any...)
-PASS Window interface: operation clearTimeout(optional long)
-PASS Window interface: operation setInterval(TimerHandler, optional long, any...)
-PASS Window interface: operation clearInterval(optional long)
-PASS Window interface: operation queueMicrotask(VoidFunction)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)
-PASS Window interface: operation requestAnimationFrame(FrameRequestCallback)
-PASS Window interface: operation cancelAnimationFrame(unsigned long)
-PASS Window interface: attribute sessionStorage
-PASS Window interface: attribute localStorage
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window must be primary interface of window
-PASS Stringification of window
-PASS Window interface: window must have own property "window"
-PASS Window interface: window must inherit property "self" with the proper type
-PASS Window interface: window must have own property "document"
-PASS Window interface: window must inherit property "name" with the proper type
-PASS Window interface: window must have own property "location"
-PASS Window interface: window must inherit property "history" with the proper type
-PASS Window interface: window must inherit property "customElements" with the proper type
-PASS Window interface: window must inherit property "locationbar" with the proper type
-PASS Window interface: window must inherit property "menubar" with the proper type
-PASS Window interface: window must inherit property "personalbar" with the proper type
-PASS Window interface: window must inherit property "scrollbars" with the proper type
-PASS Window interface: window must inherit property "statusbar" with the proper type
-PASS Window interface: window must inherit property "toolbar" with the proper type
-PASS Window interface: window must inherit property "status" with the proper type
-PASS Window interface: window must inherit property "close()" with the proper type
-PASS Window interface: window must inherit property "closed" with the proper type
-PASS Window interface: window must inherit property "stop()" with the proper type
-PASS Window interface: window must inherit property "focus()" with the proper type
-PASS Window interface: window must inherit property "blur()" with the proper type
-PASS Window interface: window must inherit property "frames" with the proper type
-PASS Window interface: window must inherit property "length" with the proper type
-PASS Window interface: window must have own property "top"
-PASS Window interface: window must inherit property "opener" with the proper type
-PASS Window interface: window must inherit property "parent" with the proper type
-PASS Window interface: window must inherit property "frameElement" with the proper type
-PASS Window interface: window must inherit property "open(optional USVString, optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling open(optional USVString, optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "navigator" with the proper type
-FAIL Window interface: window must inherit property "applicationCache" with the proper type assert_own_property: expected property "applicationCache" missing
-PASS Window interface: window must inherit property "originIsolated" with the proper type
-PASS Window interface: window must inherit property "alert()" with the proper type
-PASS Window interface: window must inherit property "alert(DOMString)" with the proper type
-PASS Window interface: calling alert(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "confirm(optional DOMString)" with the proper type
-PASS Window interface: calling confirm(optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "prompt(optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling prompt(optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "print()" with the proper type
-PASS Window interface: window must inherit property "postMessage(any, USVString, optional sequence<object>)" with the proper type
-PASS Window interface: calling postMessage(any, USVString, optional sequence<object>) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "postMessage(any, optional WindowPostMessageOptions)" with the proper type
-PASS Window interface: calling postMessage(any, optional WindowPostMessageOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "captureEvents()" with the proper type
-PASS Window interface: window must inherit property "releaseEvents()" with the proper type
-PASS Window interface: window must inherit property "external" with the proper type
-PASS Window interface: window must inherit property "onabort" with the proper type
-PASS Window interface: window must inherit property "onauxclick" with the proper type
-PASS Window interface: window must inherit property "onblur" with the proper type
-PASS Window interface: window must inherit property "oncancel" with the proper type
-PASS Window interface: window must inherit property "oncanplay" with the proper type
-PASS Window interface: window must inherit property "oncanplaythrough" with the proper type
-PASS Window interface: window must inherit property "onchange" with the proper type
-PASS Window interface: window must inherit property "onclick" with the proper type
-PASS Window interface: window must inherit property "onclose" with the proper type
-PASS Window interface: window must inherit property "oncontextmenu" with the proper type
-PASS Window interface: window must inherit property "oncuechange" with the proper type
-PASS Window interface: window must inherit property "ondblclick" with the proper type
-PASS Window interface: window must inherit property "ondrag" with the proper type
-PASS Window interface: window must inherit property "ondragend" with the proper type
-PASS Window interface: window must inherit property "ondragenter" with the proper type
-PASS Window interface: window must inherit property "ondragleave" with the proper type
-PASS Window interface: window must inherit property "ondragover" with the proper type
-PASS Window interface: window must inherit property "ondragstart" with the proper type
-PASS Window interface: window must inherit property "ondrop" with the proper type
-PASS Window interface: window must inherit property "ondurationchange" with the proper type
-PASS Window interface: window must inherit property "onemptied" with the proper type
-PASS Window interface: window must inherit property "onended" with the proper type
-PASS Window interface: window must inherit property "onerror" with the proper type
-PASS Window interface: window must inherit property "onfocus" with the proper type
-PASS Window interface: window must inherit property "onformdata" with the proper type
-PASS Window interface: window must inherit property "oninput" with the proper type
-PASS Window interface: window must inherit property "oninvalid" with the proper type
-PASS Window interface: window must inherit property "onkeydown" with the proper type
-PASS Window interface: window must inherit property "onkeypress" with the proper type
-PASS Window interface: window must inherit property "onkeyup" with the proper type
-PASS Window interface: window must inherit property "onload" with the proper type
-PASS Window interface: window must inherit property "onloadeddata" with the proper type
-PASS Window interface: window must inherit property "onloadedmetadata" with the proper type
-PASS Window interface: window must inherit property "onloadstart" with the proper type
-PASS Window interface: window must inherit property "onmousedown" with the proper type
-PASS Window interface: window must inherit property "onmouseenter" with the proper type
-PASS Window interface: window must inherit property "onmouseleave" with the proper type
-PASS Window interface: window must inherit property "onmousemove" with the proper type
-PASS Window interface: window must inherit property "onmouseout" with the proper type
-PASS Window interface: window must inherit property "onmouseover" with the proper type
-PASS Window interface: window must inherit property "onmouseup" with the proper type
-PASS Window interface: window must inherit property "onpause" with the proper type
-PASS Window interface: window must inherit property "onplay" with the proper type
-PASS Window interface: window must inherit property "onplaying" with the proper type
-PASS Window interface: window must inherit property "onprogress" with the proper type
-PASS Window interface: window must inherit property "onratechange" with the proper type
-PASS Window interface: window must inherit property "onreset" with the proper type
-PASS Window interface: window must inherit property "onresize" with the proper type
-PASS Window interface: window must inherit property "onscroll" with the proper type
-FAIL Window interface: window must inherit property "onsecuritypolicyviolation" with the proper type assert_own_property: expected property "onsecuritypolicyviolation" missing
-PASS Window interface: window must inherit property "onseeked" with the proper type
-PASS Window interface: window must inherit property "onseeking" with the proper type
-PASS Window interface: window must inherit property "onselect" with the proper type
-FAIL Window interface: window must inherit property "onslotchange" with the proper type assert_own_property: expected property "onslotchange" missing
-PASS Window interface: window must inherit property "onstalled" with the proper type
-PASS Window interface: window must inherit property "onsubmit" with the proper type
-PASS Window interface: window must inherit property "onsuspend" with the proper type
-PASS Window interface: window must inherit property "ontimeupdate" with the proper type
-PASS Window interface: window must inherit property "ontoggle" with the proper type
-PASS Window interface: window must inherit property "onvolumechange" with the proper type
-PASS Window interface: window must inherit property "onwaiting" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationend" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationiteration" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationstart" with the proper type
-PASS Window interface: window must inherit property "onwebkittransitionend" with the proper type
-PASS Window interface: window must inherit property "onwheel" with the proper type
-PASS Window interface: window must inherit property "onafterprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeunload" with the proper type
-PASS Window interface: window must inherit property "onhashchange" with the proper type
-PASS Window interface: window must inherit property "onlanguagechange" with the proper type
-PASS Window interface: window must inherit property "onmessage" with the proper type
-PASS Window interface: window must inherit property "onmessageerror" with the proper type
-PASS Window interface: window must inherit property "onoffline" with the proper type
-PASS Window interface: window must inherit property "ononline" with the proper type
-PASS Window interface: window must inherit property "onpagehide" with the proper type
-PASS Window interface: window must inherit property "onpageshow" with the proper type
-PASS Window interface: window must inherit property "onpopstate" with the proper type
-PASS Window interface: window must inherit property "onrejectionhandled" with the proper type
-PASS Window interface: window must inherit property "onstorage" with the proper type
-PASS Window interface: window must inherit property "onunhandledrejection" with the proper type
-PASS Window interface: window must inherit property "onunload" with the proper type
-PASS Window interface: window must inherit property "origin" with the proper type
-PASS Window interface: window must inherit property "isSecureContext" with the proper type
-PASS Window interface: window must inherit property "crossOriginIsolated" with the proper type
-PASS Window interface: window must inherit property "btoa(DOMString)" with the proper type
-PASS Window interface: calling btoa(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "atob(DOMString)" with the proper type
-PASS Window interface: calling atob(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setTimeout(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setTimeout(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearTimeout(optional long)" with the proper type
-PASS Window interface: calling clearTimeout(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setInterval(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setInterval(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearInterval(optional long)" with the proper type
-PASS Window interface: calling clearInterval(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "queueMicrotask(VoidFunction)" with the proper type
-PASS Window interface: calling queueMicrotask(VoidFunction) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "requestAnimationFrame(FrameRequestCallback)" with the proper type
-PASS Window interface: calling requestAnimationFrame(FrameRequestCallback) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "cancelAnimationFrame(unsigned long)" with the proper type
-PASS Window interface: calling cancelAnimationFrame(unsigned long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "sessionStorage" with the proper type
-PASS Window interface: window must inherit property "localStorage" with the proper type
-PASS Document interface: attribute domain
-PASS Document interface: attribute referrer
-PASS Document interface: attribute cookie
-PASS Document interface: attribute lastModified
-PASS Document interface: attribute readyState
-PASS Document interface: attribute title
-PASS Document interface: attribute dir
-PASS Document interface: attribute body
-PASS Document interface: attribute head
-PASS Document interface: attribute images
-PASS Document interface: attribute embeds
-PASS Document interface: attribute plugins
-PASS Document interface: attribute links
-PASS Document interface: attribute forms
-PASS Document interface: attribute scripts
-PASS Document interface: operation getElementsByName(DOMString)
-PASS Document interface: attribute currentScript
-PASS Document interface: operation open(optional DOMString, optional DOMString)
-PASS Document interface: operation open(USVString, DOMString, DOMString)
-PASS Document interface: operation close()
-PASS Document interface: operation write(DOMString...)
-PASS Document interface: operation writeln(DOMString...)
-PASS Document interface: attribute defaultView
-PASS Document interface: operation hasFocus()
-PASS Document interface: attribute designMode
-PASS Document interface: operation execCommand(DOMString, optional boolean, optional DOMString)
-PASS Document interface: operation queryCommandEnabled(DOMString)
-PASS Document interface: operation queryCommandIndeterm(DOMString)
-PASS Document interface: operation queryCommandState(DOMString)
-PASS Document interface: operation queryCommandSupported(DOMString)
-PASS Document interface: operation queryCommandValue(DOMString)
-PASS Document interface: attribute onreadystatechange
-PASS Document interface: attribute fgColor
-PASS Document interface: attribute linkColor
-PASS Document interface: attribute vlinkColor
-PASS Document interface: attribute alinkColor
-PASS Document interface: attribute bgColor
-PASS Document interface: attribute anchors
-PASS Document interface: attribute applets
-PASS Document interface: operation clear()
-PASS Document interface: operation captureEvents()
-PASS Document interface: operation releaseEvents()
-PASS Document interface: attribute all
-PASS Document interface: attribute onabort
-PASS Document interface: attribute onauxclick
-PASS Document interface: attribute onblur
-PASS Document interface: attribute oncancel
-PASS Document interface: attribute oncanplay
-PASS Document interface: attribute oncanplaythrough
-PASS Document interface: attribute onchange
-PASS Document interface: attribute onclick
-PASS Document interface: attribute onclose
-PASS Document interface: attribute oncontextmenu
-PASS Document interface: attribute oncuechange
-PASS Document interface: attribute ondblclick
-PASS Document interface: attribute ondrag
-PASS Document interface: attribute ondragend
-PASS Document interface: attribute ondragenter
-PASS Document interface: attribute ondragleave
-PASS Document interface: attribute ondragover
-PASS Document interface: attribute ondragstart
-PASS Document interface: attribute ondrop
-PASS Document interface: attribute ondurationchange
-PASS Document interface: attribute onemptied
-PASS Document interface: attribute onended
-PASS Document interface: attribute onerror
-PASS Document interface: attribute onfocus
-PASS Document interface: attribute onformdata
-PASS Document interface: attribute oninput
-PASS Document interface: attribute oninvalid
-PASS Document interface: attribute onkeydown
-PASS Document interface: attribute onkeypress
-PASS Document interface: attribute onkeyup
-PASS Document interface: attribute onload
-PASS Document interface: attribute onloadeddata
-PASS Document interface: attribute onloadedmetadata
-PASS Document interface: attribute onloadstart
-PASS Document interface: attribute onmousedown
-PASS Document interface: attribute onmouseenter
-PASS Document interface: attribute onmouseleave
-PASS Document interface: attribute onmousemove
-PASS Document interface: attribute onmouseout
-PASS Document interface: attribute onmouseover
-PASS Document interface: attribute onmouseup
-PASS Document interface: attribute onpause
-PASS Document interface: attribute onplay
-PASS Document interface: attribute onplaying
-PASS Document interface: attribute onprogress
-PASS Document interface: attribute onratechange
-PASS Document interface: attribute onreset
-PASS Document interface: attribute onresize
-PASS Document interface: attribute onscroll
-PASS Document interface: attribute onsecuritypolicyviolation
-PASS Document interface: attribute onseeked
-PASS Document interface: attribute onseeking
-PASS Document interface: attribute onselect
-FAIL Document interface: attribute onslotchange assert_true: The prototype object must have a property "onslotchange" expected true got false
-PASS Document interface: attribute onstalled
-PASS Document interface: attribute onsubmit
-PASS Document interface: attribute onsuspend
-PASS Document interface: attribute ontimeupdate
-PASS Document interface: attribute ontoggle
-PASS Document interface: attribute onvolumechange
-PASS Document interface: attribute onwaiting
-PASS Document interface: attribute onwebkitanimationend
-PASS Document interface: attribute onwebkitanimationiteration
-PASS Document interface: attribute onwebkitanimationstart
-PASS Document interface: attribute onwebkittransitionend
-PASS Document interface: attribute onwheel
-PASS Document interface: attribute oncopy
-PASS Document interface: attribute oncut
-PASS Document interface: attribute onpaste
-PASS Document interface: attribute activeElement
-PASS Document interface: iframe.contentDocument must have own property "location"
-PASS Document interface: iframe.contentDocument must inherit property "domain" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "referrer" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "cookie" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "lastModified" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "readyState" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "title" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "dir" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "body" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "head" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "images" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "embeds" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "plugins" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "links" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "forms" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "scripts" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "currentScript" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "close()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "defaultView" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "hasFocus()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "designMode" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "onreadystatechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "fgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "linkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "vlinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "alinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "bgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "anchors" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "applets" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "clear()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "captureEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "releaseEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "all" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onabort" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onauxclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onblur" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncancel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclose" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncontextmenu" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncuechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondblclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrag" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrop" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondurationchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onemptied" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onended" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onerror" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onfocus" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onformdata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninput" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninvalid" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeydown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeypress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeyup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onload" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadeddata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousedown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousemove" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseout" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpause" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplaying" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onprogress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onratechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onreset" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onresize" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onscroll" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeked" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeking" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onselect" with the proper type
-FAIL Document interface: iframe.contentDocument must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: iframe.contentDocument must inherit property "onstalled" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsubmit" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsuspend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontimeupdate" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontoggle" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onvolumechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwaiting" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwheel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncopy" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncut" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpaste" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "activeElement" with the proper type
-PASS Document interface: new Document() must have own property "location"
-PASS Document interface: new Document() must inherit property "domain" with the proper type
-PASS Document interface: new Document() must inherit property "referrer" with the proper type
-PASS Document interface: new Document() must inherit property "cookie" with the proper type
-PASS Document interface: new Document() must inherit property "lastModified" with the proper type
-PASS Document interface: new Document() must inherit property "readyState" with the proper type
-PASS Document interface: new Document() must inherit property "title" with the proper type
-PASS Document interface: new Document() must inherit property "dir" with the proper type
-PASS Document interface: new Document() must inherit property "body" with the proper type
-PASS Document interface: new Document() must inherit property "head" with the proper type
-PASS Document interface: new Document() must inherit property "images" with the proper type
-PASS Document interface: new Document() must inherit property "embeds" with the proper type
-PASS Document interface: new Document() must inherit property "plugins" with the proper type
-PASS Document interface: new Document() must inherit property "links" with the proper type
-PASS Document interface: new Document() must inherit property "forms" with the proper type
-PASS Document interface: new Document() must inherit property "scripts" with the proper type
-PASS Document interface: new Document() must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "currentScript" with the proper type
-PASS Document interface: new Document() must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "close()" with the proper type
-PASS Document interface: new Document() must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "defaultView" with the proper type
-PASS Document interface: new Document() must inherit property "hasFocus()" with the proper type
-PASS Document interface: new Document() must inherit property "designMode" with the proper type
-PASS Document interface: new Document() must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "onreadystatechange" with the proper type
-PASS Document interface: new Document() must inherit property "fgColor" with the proper type
-PASS Document interface: new Document() must inherit property "linkColor" with the proper type
-PASS Document interface: new Document() must inherit property "vlinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "alinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "bgColor" with the proper type
-PASS Document interface: new Document() must inherit property "anchors" with the proper type
-PASS Document interface: new Document() must inherit property "applets" with the proper type
-PASS Document interface: new Document() must inherit property "clear()" with the proper type
-PASS Document interface: new Document() must inherit property "captureEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "releaseEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "all" with the proper type
-PASS Document interface: new Document() must inherit property "onabort" with the proper type
-PASS Document interface: new Document() must inherit property "onauxclick" with the proper type
-PASS Document interface: new Document() must inherit property "onblur" with the proper type
-PASS Document interface: new Document() must inherit property "oncancel" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplay" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: new Document() must inherit property "onchange" with the proper type
-PASS Document interface: new Document() must inherit property "onclick" with the proper type
-PASS Document interface: new Document() must inherit property "onclose" with the proper type
-PASS Document interface: new Document() must inherit property "oncontextmenu" with the proper type
-PASS Document interface: new Document() must inherit property "oncuechange" with the proper type
-PASS Document interface: new Document() must inherit property "ondblclick" with the proper type
-PASS Document interface: new Document() must inherit property "ondrag" with the proper type
-PASS Document interface: new Document() must inherit property "ondragend" with the proper type
-PASS Document interface: new Document() must inherit property "ondragenter" with the proper type
-PASS Document interface: new Document() must inherit property "ondragleave" with the proper type
-PASS Document interface: new Document() must inherit property "ondragover" with the proper type
-PASS Document interface: new Document() must inherit property "ondragstart" with the proper type
-PASS Document interface: new Document() must inherit property "ondrop" with the proper type
-PASS Document interface: new Document() must inherit property "ondurationchange" with the proper type
-PASS Document interface: new Document() must inherit property "onemptied" with the proper type
-PASS Document interface: new Document() must inherit property "onended" with the proper type
-PASS Document interface: new Document() must inherit property "onerror" with the proper type
-PASS Document interface: new Document() must inherit property "onfocus" with the proper type
-PASS Document interface: new Document() must inherit property "onformdata" with the proper type
-PASS Document interface: new Document() must inherit property "oninput" with the proper type
-PASS Document interface: new Document() must inherit property "oninvalid" with the proper type
-PASS Document interface: new Document() must inherit property "onkeydown" with the proper type
-PASS Document interface: new Document() must inherit property "onkeypress" with the proper type
-PASS Document interface: new Document() must inherit property "onkeyup" with the proper type
-PASS Document interface: new Document() must inherit property "onload" with the proper type
-PASS Document interface: new Document() must inherit property "onloadeddata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadstart" with the proper type
-PASS Document interface: new Document() must inherit property "onmousedown" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseenter" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseleave" with the proper type
-PASS Document interface: new Document() must inherit property "onmousemove" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseout" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseover" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseup" with the proper type
-PASS Document interface: new Document() must inherit property "onpause" with the proper type
-PASS Document interface: new Document() must inherit property "onplay" with the proper type
-PASS Document interface: new Document() must inherit property "onplaying" with the proper type
-PASS Document interface: new Document() must inherit property "onprogress" with the proper type
-PASS Document interface: new Document() must inherit property "onratechange" with the proper type
-PASS Document interface: new Document() must inherit property "onreset" with the proper type
-PASS Document interface: new Document() must inherit property "onresize" with the proper type
-PASS Document interface: new Document() must inherit property "onscroll" with the proper type
-PASS Document interface: new Document() must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: new Document() must inherit property "onseeked" with the proper type
-PASS Document interface: new Document() must inherit property "onseeking" with the proper type
-PASS Document interface: new Document() must inherit property "onselect" with the proper type
-FAIL Document interface: new Document() must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: new Document() must inherit property "onstalled" with the proper type
-PASS Document interface: new Document() must inherit property "onsubmit" with the proper type
-PASS Document interface: new Document() must inherit property "onsuspend" with the proper type
-PASS Document interface: new Document() must inherit property "ontimeupdate" with the proper type
-PASS Document interface: new Document() must inherit property "ontoggle" with the proper type
-PASS Document interface: new Document() must inherit property "onvolumechange" with the proper type
-PASS Document interface: new Document() must inherit property "onwaiting" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: new Document() must inherit property "onwheel" with the proper type
-PASS Document interface: new Document() must inherit property "oncopy" with the proper type
-PASS Document interface: new Document() must inherit property "oncut" with the proper type
-PASS Document interface: new Document() must inherit property "onpaste" with the proper type
-PASS Document interface: new Document() must inherit property "activeElement" with the proper type
-PASS Document interface: documentWithHandlers must have own property "location"
-PASS Document interface: documentWithHandlers must inherit property "domain" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "referrer" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "cookie" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "lastModified" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "readyState" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "title" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "dir" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "body" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "head" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "images" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "embeds" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "plugins" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "links" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "forms" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "scripts" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "currentScript" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "close()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "defaultView" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "hasFocus()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "designMode" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "onreadystatechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "fgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "linkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "vlinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "alinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "bgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "anchors" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "applets" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "clear()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "captureEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "releaseEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "all" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onabort" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onauxclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onblur" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncancel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclose" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncontextmenu" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncuechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondblclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrag" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrop" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondurationchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onemptied" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onended" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onerror" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onfocus" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onformdata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninput" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninvalid" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeydown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeypress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeyup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onload" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadeddata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousedown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousemove" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseout" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpause" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplaying" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onprogress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onratechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onreset" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onresize" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onscroll" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeked" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeking" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onselect" with the proper type
-FAIL Document interface: documentWithHandlers must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" found on object expected in prototype chain
-PASS Document interface: documentWithHandlers must inherit property "onstalled" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsubmit" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsuspend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontimeupdate" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontoggle" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onvolumechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwaiting" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwheel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncopy" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncut" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpaste" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "activeElement" with the proper type
-Harness: the test ran to completion.
-
diff --git "a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" "b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
deleted file mode 100644
index 0c35a829..0000000
--- "a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
+++ /dev/null
@@ -1,967 +0,0 @@
-This is a testharness.js-based test.
-Found 963 tests; 954 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined
-PASS Partial interface mixin DocumentOrShadowRoot: member names are unique
-PASS Partial interface mixin NavigatorID: original interface mixin defined
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface HTMLAnchorElement: original interface defined
-PASS Partial interface HTMLAnchorElement: member names are unique
-PASS Partial interface HTMLAreaElement: original interface defined
-PASS Partial interface HTMLAreaElement: member names are unique
-PASS Partial interface HTMLBodyElement: original interface defined
-PASS Partial interface HTMLBodyElement: member names are unique
-PASS Partial interface HTMLBRElement: original interface defined
-PASS Partial interface HTMLBRElement: member names are unique
-PASS Partial interface HTMLTableCaptionElement: original interface defined
-PASS Partial interface HTMLTableCaptionElement: member names are unique
-PASS Partial interface HTMLTableColElement: original interface defined
-PASS Partial interface HTMLTableColElement: member names are unique
-PASS Partial interface HTMLDivElement: original interface defined
-PASS Partial interface HTMLDivElement: member names are unique
-PASS Partial interface HTMLDListElement: original interface defined
-PASS Partial interface HTMLDListElement: member names are unique
-PASS Partial interface HTMLEmbedElement: original interface defined
-PASS Partial interface HTMLEmbedElement: member names are unique
-PASS Partial interface HTMLHeadingElement: original interface defined
-PASS Partial interface HTMLHeadingElement: member names are unique
-PASS Partial interface HTMLHRElement: original interface defined
-PASS Partial interface HTMLHRElement: member names are unique
-PASS Partial interface HTMLHtmlElement: original interface defined
-PASS Partial interface HTMLHtmlElement: member names are unique
-PASS Partial interface HTMLIFrameElement: original interface defined
-PASS Partial interface HTMLIFrameElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface HTMLInputElement: original interface defined
-PASS Partial interface HTMLInputElement: member names are unique
-PASS Partial interface HTMLLegendElement: original interface defined
-PASS Partial interface HTMLLegendElement: member names are unique
-PASS Partial interface HTMLLIElement: original interface defined
-PASS Partial interface HTMLLIElement: member names are unique
-PASS Partial interface HTMLLinkElement: original interface defined
-PASS Partial interface HTMLLinkElement: member names are unique
-PASS Partial interface HTMLMenuElement: original interface defined
-PASS Partial interface HTMLMenuElement: member names are unique
-PASS Partial interface HTMLMetaElement: original interface defined
-PASS Partial interface HTMLMetaElement: member names are unique
-PASS Partial interface HTMLObjectElement: original interface defined
-PASS Partial interface HTMLObjectElement: member names are unique
-PASS Partial interface HTMLOListElement: original interface defined
-PASS Partial interface HTMLOListElement: member names are unique
-PASS Partial interface HTMLParagraphElement: original interface defined
-PASS Partial interface HTMLParagraphElement: member names are unique
-PASS Partial interface HTMLParamElement: original interface defined
-PASS Partial interface HTMLParamElement: member names are unique
-PASS Partial interface HTMLPreElement: original interface defined
-PASS Partial interface HTMLPreElement: member names are unique
-PASS Partial interface HTMLStyleElement: original interface defined
-PASS Partial interface HTMLStyleElement: member names are unique
-PASS Partial interface HTMLScriptElement: original interface defined
-PASS Partial interface HTMLScriptElement: member names are unique
-PASS Partial interface HTMLTableElement: original interface defined
-PASS Partial interface HTMLTableElement: member names are unique
-PASS Partial interface HTMLTableSectionElement: original interface defined
-PASS Partial interface HTMLTableSectionElement: member names are unique
-PASS Partial interface HTMLTableCellElement: original interface defined
-PASS Partial interface HTMLTableCellElement: member names are unique
-PASS Partial interface HTMLTableRowElement: original interface defined
-PASS Partial interface HTMLTableRowElement: member names are unique
-PASS Partial interface HTMLUListElement: original interface defined
-PASS Partial interface HTMLUListElement: member names are unique
-PASS Partial interface Document[2]: original interface defined
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes DocumentOrShadowRoot: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS HTMLLinkElement includes LinkStyle: member names are unique
-PASS HTMLStyleElement includes LinkStyle: member names are unique
-PASS HTMLBodyElement includes WindowEventHandlers: member names are unique
-PASS HTMLAnchorElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS HTMLAreaElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS CanvasRenderingContext2D includes CanvasState: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS CanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS CanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS CanvasRenderingContext2D includes CanvasUserInterface: member names are unique
-PASS CanvasRenderingContext2D includes CanvasText: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS Path2D includes CanvasPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasState: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasText: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS ElementInternals includes ARIAMixin: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS DedicatedWorkerGlobalScope includes AnimationFrameProvider: member names are unique
-PASS Worker includes AbstractWorker: member names are unique
-PASS SharedWorker includes AbstractWorker: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS HTMLFrameSetElement includes WindowEventHandlers: member names are unique
-PASS Element includes ARIAMixin: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS SVGElement includes GlobalEventHandlers: member names are unique
-PASS SVGElement includes DocumentAndElementEventHandlers: member names are unique
-PASS SVGElement includes SVGElementInstance: member names are unique
-PASS SVGElement includes HTMLOrSVGElement: member names are unique
-PASS SVGElement includes ElementCSSInlineStyle: member names are unique
-PASS SVGGraphicsElement includes SVGTests: member names are unique
-PASS SVGSVGElement includes SVGFitToViewBox: member names are unique
-PASS SVGSVGElement includes WindowEventHandlers: member names are unique
-PASS SVGImageElement includes SVGURIReference: member names are unique
-PASS SVGScriptElement includes SVGURIReference: member names are unique
-PASS SVGAElement includes SVGURIReference: member names are unique
-FAIL SVGAElement includes HTMLHyperlinkElementUtils: member names are unique assert_true: member href is unique expected true got false
-PASS DocumentFragment includes NonElementParentNode: member names are unique
-PASS DocumentFragment includes ParentNode: member names are unique
-PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique
-PASS Window interface: existence and properties of interface object
-PASS Window interface object length
-PASS Window interface object name
-PASS Window interface: existence and properties of interface prototype object
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window interface: existence and properties of interface prototype object's "constructor" property
-PASS Window interface: existence and properties of interface prototype object's @@unscopables property
-PASS Window interface: attribute self
-PASS Window interface: attribute name
-PASS Window interface: attribute history
-PASS Window interface: attribute customElements
-PASS Window interface: attribute locationbar
-PASS Window interface: attribute menubar
-PASS Window interface: attribute personalbar
-PASS Window interface: attribute scrollbars
-PASS Window interface: attribute statusbar
-PASS Window interface: attribute toolbar
-PASS Window interface: attribute status
-PASS Window interface: operation close()
-PASS Window interface: attribute closed
-PASS Window interface: operation stop()
-PASS Window interface: operation focus()
-PASS Window interface: operation blur()
-PASS Window interface: attribute frames
-PASS Window interface: attribute length
-PASS Window interface: attribute opener
-PASS Window interface: attribute parent
-PASS Window interface: attribute frameElement
-PASS Window interface: operation open(optional USVString, optional DOMString, optional DOMString)
-PASS Window interface: attribute navigator
-PASS Window interface: attribute originAgentCluster
-PASS Window interface: operation alert()
-PASS Window interface: operation alert(DOMString)
-PASS Window interface: operation confirm(optional DOMString)
-PASS Window interface: operation prompt(optional DOMString, optional DOMString)
-PASS Window interface: operation print()
-PASS Window interface: operation postMessage(any, USVString, optional sequence<object>)
-PASS Window interface: operation postMessage(any, optional WindowPostMessageOptions)
-PASS Window interface: operation captureEvents()
-PASS Window interface: operation releaseEvents()
-PASS Window interface: attribute external
-PASS Window interface: attribute onabort
-PASS Window interface: attribute onauxclick
-PASS Window interface: attribute onblur
-PASS Window interface: attribute oncancel
-PASS Window interface: attribute oncanplay
-PASS Window interface: attribute oncanplaythrough
-PASS Window interface: attribute onchange
-PASS Window interface: attribute onclick
-PASS Window interface: attribute onclose
-PASS Window interface: attribute oncontextmenu
-PASS Window interface: attribute oncuechange
-PASS Window interface: attribute ondblclick
-PASS Window interface: attribute ondrag
-PASS Window interface: attribute ondragend
-PASS Window interface: attribute ondragenter
-PASS Window interface: attribute ondragleave
-PASS Window interface: attribute ondragover
-PASS Window interface: attribute ondragstart
-PASS Window interface: attribute ondrop
-PASS Window interface: attribute ondurationchange
-PASS Window interface: attribute onemptied
-PASS Window interface: attribute onended
-PASS Window interface: attribute onerror
-PASS Window interface: attribute onfocus
-PASS Window interface: attribute onformdata
-PASS Window interface: attribute oninput
-PASS Window interface: attribute oninvalid
-PASS Window interface: attribute onkeydown
-PASS Window interface: attribute onkeypress
-PASS Window interface: attribute onkeyup
-PASS Window interface: attribute onload
-PASS Window interface: attribute onloadeddata
-PASS Window interface: attribute onloadedmetadata
-PASS Window interface: attribute onloadstart
-PASS Window interface: attribute onmousedown
-PASS Window interface: attribute onmouseenter
-PASS Window interface: attribute onmouseleave
-PASS Window interface: attribute onmousemove
-PASS Window interface: attribute onmouseout
-PASS Window interface: attribute onmouseover
-PASS Window interface: attribute onmouseup
-PASS Window interface: attribute onpause
-PASS Window interface: attribute onplay
-PASS Window interface: attribute onplaying
-PASS Window interface: attribute onprogress
-PASS Window interface: attribute onratechange
-PASS Window interface: attribute onreset
-PASS Window interface: attribute onresize
-PASS Window interface: attribute onscroll
-FAIL Window interface: attribute onsecuritypolicyviolation assert_own_property: The global object must have a property "onsecuritypolicyviolation" expected property "onsecuritypolicyviolation" missing
-PASS Window interface: attribute onseeked
-PASS Window interface: attribute onseeking
-PASS Window interface: attribute onselect
-FAIL Window interface: attribute onslotchange assert_own_property: The global object must have a property "onslotchange" expected property "onslotchange" missing
-PASS Window interface: attribute onstalled
-PASS Window interface: attribute onsubmit
-PASS Window interface: attribute onsuspend
-PASS Window interface: attribute ontimeupdate
-PASS Window interface: attribute ontoggle
-PASS Window interface: attribute onvolumechange
-PASS Window interface: attribute onwaiting
-PASS Window interface: attribute onwebkitanimationend
-PASS Window interface: attribute onwebkitanimationiteration
-PASS Window interface: attribute onwebkitanimationstart
-PASS Window interface: attribute onwebkittransitionend
-PASS Window interface: attribute onwheel
-PASS Window interface: attribute onafterprint
-PASS Window interface: attribute onbeforeprint
-PASS Window interface: attribute onbeforeunload
-PASS Window interface: attribute onhashchange
-PASS Window interface: attribute onlanguagechange
-PASS Window interface: attribute onmessage
-PASS Window interface: attribute onmessageerror
-PASS Window interface: attribute onoffline
-PASS Window interface: attribute ononline
-PASS Window interface: attribute onpagehide
-PASS Window interface: attribute onpageshow
-PASS Window interface: attribute onpopstate
-PASS Window interface: attribute onrejectionhandled
-PASS Window interface: attribute onstorage
-PASS Window interface: attribute onunhandledrejection
-PASS Window interface: attribute onunload
-PASS Window interface: attribute origin
-PASS Window interface: attribute isSecureContext
-PASS Window interface: attribute crossOriginIsolated
-PASS Window interface: operation btoa(DOMString)
-PASS Window interface: operation atob(DOMString)
-PASS Window interface: operation setTimeout(TimerHandler, optional long, any...)
-PASS Window interface: operation clearTimeout(optional long)
-PASS Window interface: operation setInterval(TimerHandler, optional long, any...)
-PASS Window interface: operation clearInterval(optional long)
-PASS Window interface: operation queueMicrotask(VoidFunction)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)
-PASS Window interface: operation requestAnimationFrame(FrameRequestCallback)
-PASS Window interface: operation cancelAnimationFrame(unsigned long)
-PASS Window interface: attribute sessionStorage
-PASS Window interface: attribute localStorage
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window must be primary interface of window
-PASS Stringification of window
-PASS Window interface: window must have own property "window"
-PASS Window interface: window must inherit property "self" with the proper type
-PASS Window interface: window must have own property "document"
-PASS Window interface: window must inherit property "name" with the proper type
-PASS Window interface: window must have own property "location"
-PASS Window interface: window must inherit property "history" with the proper type
-PASS Window interface: window must inherit property "customElements" with the proper type
-PASS Window interface: window must inherit property "locationbar" with the proper type
-PASS Window interface: window must inherit property "menubar" with the proper type
-PASS Window interface: window must inherit property "personalbar" with the proper type
-PASS Window interface: window must inherit property "scrollbars" with the proper type
-PASS Window interface: window must inherit property "statusbar" with the proper type
-PASS Window interface: window must inherit property "toolbar" with the proper type
-PASS Window interface: window must inherit property "status" with the proper type
-PASS Window interface: window must inherit property "close()" with the proper type
-PASS Window interface: window must inherit property "closed" with the proper type
-PASS Window interface: window must inherit property "stop()" with the proper type
-PASS Window interface: window must inherit property "focus()" with the proper type
-PASS Window interface: window must inherit property "blur()" with the proper type
-PASS Window interface: window must inherit property "frames" with the proper type
-PASS Window interface: window must inherit property "length" with the proper type
-PASS Window interface: window must have own property "top"
-PASS Window interface: window must inherit property "opener" with the proper type
-PASS Window interface: window must inherit property "parent" with the proper type
-PASS Window interface: window must inherit property "frameElement" with the proper type
-PASS Window interface: window must inherit property "open(optional USVString, optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling open(optional USVString, optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "navigator" with the proper type
-PASS Window interface: window must inherit property "originAgentCluster" with the proper type
-PASS Window interface: window must inherit property "alert()" with the proper type
-PASS Window interface: window must inherit property "alert(DOMString)" with the proper type
-PASS Window interface: calling alert(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "confirm(optional DOMString)" with the proper type
-PASS Window interface: calling confirm(optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "prompt(optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling prompt(optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "print()" with the proper type
-PASS Window interface: window must inherit property "postMessage(any, USVString, optional sequence<object>)" with the proper type
-PASS Window interface: calling postMessage(any, USVString, optional sequence<object>) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "postMessage(any, optional WindowPostMessageOptions)" with the proper type
-PASS Window interface: calling postMessage(any, optional WindowPostMessageOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "captureEvents()" with the proper type
-PASS Window interface: window must inherit property "releaseEvents()" with the proper type
-PASS Window interface: window must inherit property "external" with the proper type
-PASS Window interface: window must inherit property "onabort" with the proper type
-PASS Window interface: window must inherit property "onauxclick" with the proper type
-PASS Window interface: window must inherit property "onblur" with the proper type
-PASS Window interface: window must inherit property "oncancel" with the proper type
-PASS Window interface: window must inherit property "oncanplay" with the proper type
-PASS Window interface: window must inherit property "oncanplaythrough" with the proper type
-PASS Window interface: window must inherit property "onchange" with the proper type
-PASS Window interface: window must inherit property "onclick" with the proper type
-PASS Window interface: window must inherit property "onclose" with the proper type
-PASS Window interface: window must inherit property "oncontextmenu" with the proper type
-PASS Window interface: window must inherit property "oncuechange" with the proper type
-PASS Window interface: window must inherit property "ondblclick" with the proper type
-PASS Window interface: window must inherit property "ondrag" with the proper type
-PASS Window interface: window must inherit property "ondragend" with the proper type
-PASS Window interface: window must inherit property "ondragenter" with the proper type
-PASS Window interface: window must inherit property "ondragleave" with the proper type
-PASS Window interface: window must inherit property "ondragover" with the proper type
-PASS Window interface: window must inherit property "ondragstart" with the proper type
-PASS Window interface: window must inherit property "ondrop" with the proper type
-PASS Window interface: window must inherit property "ondurationchange" with the proper type
-PASS Window interface: window must inherit property "onemptied" with the proper type
-PASS Window interface: window must inherit property "onended" with the proper type
-PASS Window interface: window must inherit property "onerror" with the proper type
-PASS Window interface: window must inherit property "onfocus" with the proper type
-PASS Window interface: window must inherit property "onformdata" with the proper type
-PASS Window interface: window must inherit property "oninput" with the proper type
-PASS Window interface: window must inherit property "oninvalid" with the proper type
-PASS Window interface: window must inherit property "onkeydown" with the proper type
-PASS Window interface: window must inherit property "onkeypress" with the proper type
-PASS Window interface: window must inherit property "onkeyup" with the proper type
-PASS Window interface: window must inherit property "onload" with the proper type
-PASS Window interface: window must inherit property "onloadeddata" with the proper type
-PASS Window interface: window must inherit property "onloadedmetadata" with the proper type
-PASS Window interface: window must inherit property "onloadstart" with the proper type
-PASS Window interface: window must inherit property "onmousedown" with the proper type
-PASS Window interface: window must inherit property "onmouseenter" with the proper type
-PASS Window interface: window must inherit property "onmouseleave" with the proper type
-PASS Window interface: window must inherit property "onmousemove" with the proper type
-PASS Window interface: window must inherit property "onmouseout" with the proper type
-PASS Window interface: window must inherit property "onmouseover" with the proper type
-PASS Window interface: window must inherit property "onmouseup" with the proper type
-PASS Window interface: window must inherit property "onpause" with the proper type
-PASS Window interface: window must inherit property "onplay" with the proper type
-PASS Window interface: window must inherit property "onplaying" with the proper type
-PASS Window interface: window must inherit property "onprogress" with the proper type
-PASS Window interface: window must inherit property "onratechange" with the proper type
-PASS Window interface: window must inherit property "onreset" with the proper type
-PASS Window interface: window must inherit property "onresize" with the proper type
-PASS Window interface: window must inherit property "onscroll" with the proper type
-FAIL Window interface: window must inherit property "onsecuritypolicyviolation" with the proper type assert_own_property: expected property "onsecuritypolicyviolation" missing
-PASS Window interface: window must inherit property "onseeked" with the proper type
-PASS Window interface: window must inherit property "onseeking" with the proper type
-PASS Window interface: window must inherit property "onselect" with the proper type
-FAIL Window interface: window must inherit property "onslotchange" with the proper type assert_own_property: expected property "onslotchange" missing
-PASS Window interface: window must inherit property "onstalled" with the proper type
-PASS Window interface: window must inherit property "onsubmit" with the proper type
-PASS Window interface: window must inherit property "onsuspend" with the proper type
-PASS Window interface: window must inherit property "ontimeupdate" with the proper type
-PASS Window interface: window must inherit property "ontoggle" with the proper type
-PASS Window interface: window must inherit property "onvolumechange" with the proper type
-PASS Window interface: window must inherit property "onwaiting" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationend" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationiteration" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationstart" with the proper type
-PASS Window interface: window must inherit property "onwebkittransitionend" with the proper type
-PASS Window interface: window must inherit property "onwheel" with the proper type
-PASS Window interface: window must inherit property "onafterprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeunload" with the proper type
-PASS Window interface: window must inherit property "onhashchange" with the proper type
-PASS Window interface: window must inherit property "onlanguagechange" with the proper type
-PASS Window interface: window must inherit property "onmessage" with the proper type
-PASS Window interface: window must inherit property "onmessageerror" with the proper type
-PASS Window interface: window must inherit property "onoffline" with the proper type
-PASS Window interface: window must inherit property "ononline" with the proper type
-PASS Window interface: window must inherit property "onpagehide" with the proper type
-PASS Window interface: window must inherit property "onpageshow" with the proper type
-PASS Window interface: window must inherit property "onpopstate" with the proper type
-PASS Window interface: window must inherit property "onrejectionhandled" with the proper type
-PASS Window interface: window must inherit property "onstorage" with the proper type
-PASS Window interface: window must inherit property "onunhandledrejection" with the proper type
-PASS Window interface: window must inherit property "onunload" with the proper type
-PASS Window interface: window must inherit property "origin" with the proper type
-PASS Window interface: window must inherit property "isSecureContext" with the proper type
-PASS Window interface: window must inherit property "crossOriginIsolated" with the proper type
-PASS Window interface: window must inherit property "btoa(DOMString)" with the proper type
-PASS Window interface: calling btoa(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "atob(DOMString)" with the proper type
-PASS Window interface: calling atob(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setTimeout(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setTimeout(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearTimeout(optional long)" with the proper type
-PASS Window interface: calling clearTimeout(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setInterval(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setInterval(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearInterval(optional long)" with the proper type
-PASS Window interface: calling clearInterval(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "queueMicrotask(VoidFunction)" with the proper type
-PASS Window interface: calling queueMicrotask(VoidFunction) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "requestAnimationFrame(FrameRequestCallback)" with the proper type
-PASS Window interface: calling requestAnimationFrame(FrameRequestCallback) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "cancelAnimationFrame(unsigned long)" with the proper type
-PASS Window interface: calling cancelAnimationFrame(unsigned long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "sessionStorage" with the proper type
-PASS Window interface: window must inherit property "localStorage" with the proper type
-PASS Document interface: attribute domain
-PASS Document interface: attribute referrer
-PASS Document interface: attribute cookie
-PASS Document interface: attribute lastModified
-PASS Document interface: attribute readyState
-PASS Document interface: attribute title
-PASS Document interface: attribute dir
-PASS Document interface: attribute body
-PASS Document interface: attribute head
-PASS Document interface: attribute images
-PASS Document interface: attribute embeds
-PASS Document interface: attribute plugins
-PASS Document interface: attribute links
-PASS Document interface: attribute forms
-PASS Document interface: attribute scripts
-PASS Document interface: operation getElementsByName(DOMString)
-PASS Document interface: attribute currentScript
-PASS Document interface: operation open(optional DOMString, optional DOMString)
-PASS Document interface: operation open(USVString, DOMString, DOMString)
-PASS Document interface: operation close()
-PASS Document interface: operation write(DOMString...)
-PASS Document interface: operation writeln(DOMString...)
-PASS Document interface: attribute defaultView
-PASS Document interface: operation hasFocus()
-PASS Document interface: attribute designMode
-PASS Document interface: operation execCommand(DOMString, optional boolean, optional DOMString)
-PASS Document interface: operation queryCommandEnabled(DOMString)
-PASS Document interface: operation queryCommandIndeterm(DOMString)
-PASS Document interface: operation queryCommandState(DOMString)
-PASS Document interface: operation queryCommandSupported(DOMString)
-PASS Document interface: operation queryCommandValue(DOMString)
-PASS Document interface: attribute onreadystatechange
-PASS Document interface: attribute fgColor
-PASS Document interface: attribute linkColor
-PASS Document interface: attribute vlinkColor
-PASS Document interface: attribute alinkColor
-PASS Document interface: attribute bgColor
-PASS Document interface: attribute anchors
-PASS Document interface: attribute applets
-PASS Document interface: operation clear()
-PASS Document interface: operation captureEvents()
-PASS Document interface: operation releaseEvents()
-PASS Document interface: attribute all
-PASS Document interface: attribute onabort
-PASS Document interface: attribute onauxclick
-PASS Document interface: attribute onblur
-PASS Document interface: attribute oncancel
-PASS Document interface: attribute oncanplay
-PASS Document interface: attribute oncanplaythrough
-PASS Document interface: attribute onchange
-PASS Document interface: attribute onclick
-PASS Document interface: attribute onclose
-PASS Document interface: attribute oncontextmenu
-PASS Document interface: attribute oncuechange
-PASS Document interface: attribute ondblclick
-PASS Document interface: attribute ondrag
-PASS Document interface: attribute ondragend
-PASS Document interface: attribute ondragenter
-PASS Document interface: attribute ondragleave
-PASS Document interface: attribute ondragover
-PASS Document interface: attribute ondragstart
-PASS Document interface: attribute ondrop
-PASS Document interface: attribute ondurationchange
-PASS Document interface: attribute onemptied
-PASS Document interface: attribute onended
-PASS Document interface: attribute onerror
-PASS Document interface: attribute onfocus
-PASS Document interface: attribute onformdata
-PASS Document interface: attribute oninput
-PASS Document interface: attribute oninvalid
-PASS Document interface: attribute onkeydown
-PASS Document interface: attribute onkeypress
-PASS Document interface: attribute onkeyup
-PASS Document interface: attribute onload
-PASS Document interface: attribute onloadeddata
-PASS Document interface: attribute onloadedmetadata
-PASS Document interface: attribute onloadstart
-PASS Document interface: attribute onmousedown
-PASS Document interface: attribute onmouseenter
-PASS Document interface: attribute onmouseleave
-PASS Document interface: attribute onmousemove
-PASS Document interface: attribute onmouseout
-PASS Document interface: attribute onmouseover
-PASS Document interface: attribute onmouseup
-PASS Document interface: attribute onpause
-PASS Document interface: attribute onplay
-PASS Document interface: attribute onplaying
-PASS Document interface: attribute onprogress
-PASS Document interface: attribute onratechange
-PASS Document interface: attribute onreset
-PASS Document interface: attribute onresize
-PASS Document interface: attribute onscroll
-PASS Document interface: attribute onsecuritypolicyviolation
-PASS Document interface: attribute onseeked
-PASS Document interface: attribute onseeking
-PASS Document interface: attribute onselect
-FAIL Document interface: attribute onslotchange assert_true: The prototype object must have a property "onslotchange" expected true got false
-PASS Document interface: attribute onstalled
-PASS Document interface: attribute onsubmit
-PASS Document interface: attribute onsuspend
-PASS Document interface: attribute ontimeupdate
-PASS Document interface: attribute ontoggle
-PASS Document interface: attribute onvolumechange
-PASS Document interface: attribute onwaiting
-PASS Document interface: attribute onwebkitanimationend
-PASS Document interface: attribute onwebkitanimationiteration
-PASS Document interface: attribute onwebkitanimationstart
-PASS Document interface: attribute onwebkittransitionend
-PASS Document interface: attribute onwheel
-PASS Document interface: attribute oncopy
-PASS Document interface: attribute oncut
-PASS Document interface: attribute onpaste
-PASS Document interface: attribute activeElement
-PASS Document interface: iframe.contentDocument must have own property "location"
-PASS Document interface: iframe.contentDocument must inherit property "domain" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "referrer" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "cookie" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "lastModified" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "readyState" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "title" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "dir" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "body" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "head" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "images" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "embeds" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "plugins" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "links" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "forms" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "scripts" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "currentScript" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "close()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "defaultView" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "hasFocus()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "designMode" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "onreadystatechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "fgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "linkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "vlinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "alinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "bgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "anchors" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "applets" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "clear()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "captureEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "releaseEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "all" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onabort" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onauxclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onblur" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncancel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclose" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncontextmenu" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncuechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondblclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrag" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrop" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondurationchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onemptied" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onended" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onerror" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onfocus" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onformdata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninput" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninvalid" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeydown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeypress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeyup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onload" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadeddata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousedown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousemove" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseout" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpause" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplaying" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onprogress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onratechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onreset" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onresize" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onscroll" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeked" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeking" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onselect" with the proper type
-FAIL Document interface: iframe.contentDocument must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: iframe.contentDocument must inherit property "onstalled" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsubmit" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsuspend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontimeupdate" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontoggle" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onvolumechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwaiting" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwheel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncopy" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncut" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpaste" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "activeElement" with the proper type
-PASS Document interface: new Document() must have own property "location"
-PASS Document interface: new Document() must inherit property "domain" with the proper type
-PASS Document interface: new Document() must inherit property "referrer" with the proper type
-PASS Document interface: new Document() must inherit property "cookie" with the proper type
-PASS Document interface: new Document() must inherit property "lastModified" with the proper type
-PASS Document interface: new Document() must inherit property "readyState" with the proper type
-PASS Document interface: new Document() must inherit property "title" with the proper type
-PASS Document interface: new Document() must inherit property "dir" with the proper type
-PASS Document interface: new Document() must inherit property "body" with the proper type
-PASS Document interface: new Document() must inherit property "head" with the proper type
-PASS Document interface: new Document() must inherit property "images" with the proper type
-PASS Document interface: new Document() must inherit property "embeds" with the proper type
-PASS Document interface: new Document() must inherit property "plugins" with the proper type
-PASS Document interface: new Document() must inherit property "links" with the proper type
-PASS Document interface: new Document() must inherit property "forms" with the proper type
-PASS Document interface: new Document() must inherit property "scripts" with the proper type
-PASS Document interface: new Document() must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "currentScript" with the proper type
-PASS Document interface: new Document() must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "close()" with the proper type
-PASS Document interface: new Document() must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "defaultView" with the proper type
-PASS Document interface: new Document() must inherit property "hasFocus()" with the proper type
-PASS Document interface: new Document() must inherit property "designMode" with the proper type
-PASS Document interface: new Document() must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "onreadystatechange" with the proper type
-PASS Document interface: new Document() must inherit property "fgColor" with the proper type
-PASS Document interface: new Document() must inherit property "linkColor" with the proper type
-PASS Document interface: new Document() must inherit property "vlinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "alinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "bgColor" with the proper type
-PASS Document interface: new Document() must inherit property "anchors" with the proper type
-PASS Document interface: new Document() must inherit property "applets" with the proper type
-PASS Document interface: new Document() must inherit property "clear()" with the proper type
-PASS Document interface: new Document() must inherit property "captureEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "releaseEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "all" with the proper type
-PASS Document interface: new Document() must inherit property "onabort" with the proper type
-PASS Document interface: new Document() must inherit property "onauxclick" with the proper type
-PASS Document interface: new Document() must inherit property "onblur" with the proper type
-PASS Document interface: new Document() must inherit property "oncancel" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplay" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: new Document() must inherit property "onchange" with the proper type
-PASS Document interface: new Document() must inherit property "onclick" with the proper type
-PASS Document interface: new Document() must inherit property "onclose" with the proper type
-PASS Document interface: new Document() must inherit property "oncontextmenu" with the proper type
-PASS Document interface: new Document() must inherit property "oncuechange" with the proper type
-PASS Document interface: new Document() must inherit property "ondblclick" with the proper type
-PASS Document interface: new Document() must inherit property "ondrag" with the proper type
-PASS Document interface: new Document() must inherit property "ondragend" with the proper type
-PASS Document interface: new Document() must inherit property "ondragenter" with the proper type
-PASS Document interface: new Document() must inherit property "ondragleave" with the proper type
-PASS Document interface: new Document() must inherit property "ondragover" with the proper type
-PASS Document interface: new Document() must inherit property "ondragstart" with the proper type
-PASS Document interface: new Document() must inherit property "ondrop" with the proper type
-PASS Document interface: new Document() must inherit property "ondurationchange" with the proper type
-PASS Document interface: new Document() must inherit property "onemptied" with the proper type
-PASS Document interface: new Document() must inherit property "onended" with the proper type
-PASS Document interface: new Document() must inherit property "onerror" with the proper type
-PASS Document interface: new Document() must inherit property "onfocus" with the proper type
-PASS Document interface: new Document() must inherit property "onformdata" with the proper type
-PASS Document interface: new Document() must inherit property "oninput" with the proper type
-PASS Document interface: new Document() must inherit property "oninvalid" with the proper type
-PASS Document interface: new Document() must inherit property "onkeydown" with the proper type
-PASS Document interface: new Document() must inherit property "onkeypress" with the proper type
-PASS Document interface: new Document() must inherit property "onkeyup" with the proper type
-PASS Document interface: new Document() must inherit property "onload" with the proper type
-PASS Document interface: new Document() must inherit property "onloadeddata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadstart" with the proper type
-PASS Document interface: new Document() must inherit property "onmousedown" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseenter" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseleave" with the proper type
-PASS Document interface: new Document() must inherit property "onmousemove" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseout" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseover" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseup" with the proper type
-PASS Document interface: new Document() must inherit property "onpause" with the proper type
-PASS Document interface: new Document() must inherit property "onplay" with the proper type
-PASS Document interface: new Document() must inherit property "onplaying" with the proper type
-PASS Document interface: new Document() must inherit property "onprogress" with the proper type
-PASS Document interface: new Document() must inherit property "onratechange" with the proper type
-PASS Document interface: new Document() must inherit property "onreset" with the proper type
-PASS Document interface: new Document() must inherit property "onresize" with the proper type
-PASS Document interface: new Document() must inherit property "onscroll" with the proper type
-PASS Document interface: new Document() must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: new Document() must inherit property "onseeked" with the proper type
-PASS Document interface: new Document() must inherit property "onseeking" with the proper type
-PASS Document interface: new Document() must inherit property "onselect" with the proper type
-FAIL Document interface: new Document() must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: new Document() must inherit property "onstalled" with the proper type
-PASS Document interface: new Document() must inherit property "onsubmit" with the proper type
-PASS Document interface: new Document() must inherit property "onsuspend" with the proper type
-PASS Document interface: new Document() must inherit property "ontimeupdate" with the proper type
-PASS Document interface: new Document() must inherit property "ontoggle" with the proper type
-PASS Document interface: new Document() must inherit property "onvolumechange" with the proper type
-PASS Document interface: new Document() must inherit property "onwaiting" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: new Document() must inherit property "onwheel" with the proper type
-PASS Document interface: new Document() must inherit property "oncopy" with the proper type
-PASS Document interface: new Document() must inherit property "oncut" with the proper type
-PASS Document interface: new Document() must inherit property "onpaste" with the proper type
-PASS Document interface: new Document() must inherit property "activeElement" with the proper type
-PASS Document interface: documentWithHandlers must have own property "location"
-PASS Document interface: documentWithHandlers must inherit property "domain" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "referrer" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "cookie" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "lastModified" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "readyState" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "title" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "dir" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "body" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "head" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "images" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "embeds" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "plugins" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "links" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "forms" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "scripts" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "currentScript" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "close()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "defaultView" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "hasFocus()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "designMode" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "onreadystatechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "fgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "linkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "vlinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "alinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "bgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "anchors" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "applets" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "clear()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "captureEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "releaseEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "all" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onabort" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onauxclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onblur" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncancel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclose" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncontextmenu" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncuechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondblclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrag" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrop" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondurationchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onemptied" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onended" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onerror" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onfocus" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onformdata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninput" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninvalid" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeydown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeypress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeyup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onload" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadeddata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousedown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousemove" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseout" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpause" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplaying" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onprogress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onratechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onreset" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onresize" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onscroll" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeked" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeking" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onselect" with the proper type
-FAIL Document interface: documentWithHandlers must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" found on object expected in prototype chain
-PASS Document interface: documentWithHandlers must inherit property "onstalled" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsubmit" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsuspend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontimeupdate" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontoggle" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onvolumechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwaiting" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwheel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncopy" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncut" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpaste" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "activeElement" with the proper type
-Harness: the test ran to completion.
-
diff --git "a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" "b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
deleted file mode 100644
index ba85bbd..0000000
--- "a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
+++ /dev/null
@@ -1,967 +0,0 @@
-This is a testharness.js-based test.
-Found 963 tests; 952 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined
-PASS Partial interface mixin DocumentOrShadowRoot: member names are unique
-PASS Partial interface mixin NavigatorID: original interface mixin defined
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface HTMLAnchorElement: original interface defined
-PASS Partial interface HTMLAnchorElement: member names are unique
-PASS Partial interface HTMLAreaElement: original interface defined
-PASS Partial interface HTMLAreaElement: member names are unique
-PASS Partial interface HTMLBodyElement: original interface defined
-PASS Partial interface HTMLBodyElement: member names are unique
-PASS Partial interface HTMLBRElement: original interface defined
-PASS Partial interface HTMLBRElement: member names are unique
-PASS Partial interface HTMLTableCaptionElement: original interface defined
-PASS Partial interface HTMLTableCaptionElement: member names are unique
-PASS Partial interface HTMLTableColElement: original interface defined
-PASS Partial interface HTMLTableColElement: member names are unique
-PASS Partial interface HTMLDivElement: original interface defined
-PASS Partial interface HTMLDivElement: member names are unique
-PASS Partial interface HTMLDListElement: original interface defined
-PASS Partial interface HTMLDListElement: member names are unique
-PASS Partial interface HTMLEmbedElement: original interface defined
-PASS Partial interface HTMLEmbedElement: member names are unique
-PASS Partial interface HTMLHeadingElement: original interface defined
-PASS Partial interface HTMLHeadingElement: member names are unique
-PASS Partial interface HTMLHRElement: original interface defined
-PASS Partial interface HTMLHRElement: member names are unique
-PASS Partial interface HTMLHtmlElement: original interface defined
-PASS Partial interface HTMLHtmlElement: member names are unique
-PASS Partial interface HTMLIFrameElement: original interface defined
-PASS Partial interface HTMLIFrameElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface HTMLInputElement: original interface defined
-PASS Partial interface HTMLInputElement: member names are unique
-PASS Partial interface HTMLLegendElement: original interface defined
-PASS Partial interface HTMLLegendElement: member names are unique
-PASS Partial interface HTMLLIElement: original interface defined
-PASS Partial interface HTMLLIElement: member names are unique
-PASS Partial interface HTMLLinkElement: original interface defined
-PASS Partial interface HTMLLinkElement: member names are unique
-PASS Partial interface HTMLMenuElement: original interface defined
-PASS Partial interface HTMLMenuElement: member names are unique
-PASS Partial interface HTMLMetaElement: original interface defined
-PASS Partial interface HTMLMetaElement: member names are unique
-PASS Partial interface HTMLObjectElement: original interface defined
-PASS Partial interface HTMLObjectElement: member names are unique
-PASS Partial interface HTMLOListElement: original interface defined
-PASS Partial interface HTMLOListElement: member names are unique
-PASS Partial interface HTMLParagraphElement: original interface defined
-PASS Partial interface HTMLParagraphElement: member names are unique
-PASS Partial interface HTMLParamElement: original interface defined
-PASS Partial interface HTMLParamElement: member names are unique
-PASS Partial interface HTMLPreElement: original interface defined
-PASS Partial interface HTMLPreElement: member names are unique
-PASS Partial interface HTMLStyleElement: original interface defined
-PASS Partial interface HTMLStyleElement: member names are unique
-PASS Partial interface HTMLScriptElement: original interface defined
-PASS Partial interface HTMLScriptElement: member names are unique
-PASS Partial interface HTMLTableElement: original interface defined
-PASS Partial interface HTMLTableElement: member names are unique
-PASS Partial interface HTMLTableSectionElement: original interface defined
-PASS Partial interface HTMLTableSectionElement: member names are unique
-PASS Partial interface HTMLTableCellElement: original interface defined
-PASS Partial interface HTMLTableCellElement: member names are unique
-PASS Partial interface HTMLTableRowElement: original interface defined
-PASS Partial interface HTMLTableRowElement: member names are unique
-PASS Partial interface HTMLUListElement: original interface defined
-PASS Partial interface HTMLUListElement: member names are unique
-PASS Partial interface Document[2]: original interface defined
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface mixin DocumentOrShadowRoot[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes DocumentOrShadowRoot: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS HTMLLinkElement includes LinkStyle: member names are unique
-PASS HTMLStyleElement includes LinkStyle: member names are unique
-PASS HTMLBodyElement includes WindowEventHandlers: member names are unique
-PASS HTMLAnchorElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS HTMLAreaElement includes HTMLHyperlinkElementUtils: member names are unique
-PASS CanvasRenderingContext2D includes CanvasState: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS CanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS CanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS CanvasRenderingContext2D includes CanvasUserInterface: member names are unique
-PASS CanvasRenderingContext2D includes CanvasText: member names are unique
-PASS CanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS CanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS CanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS Path2D includes CanvasPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasState: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTransform: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasCompositing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFillStrokeStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasShadowStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasFilters: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasRect: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawPath: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasText: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasDrawImage: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasImageData: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles: member names are unique
-PASS OffscreenCanvasRenderingContext2D includes CanvasPath: member names are unique
-PASS ElementInternals includes ARIAMixin: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS DedicatedWorkerGlobalScope includes AnimationFrameProvider: member names are unique
-PASS Worker includes AbstractWorker: member names are unique
-PASS SharedWorker includes AbstractWorker: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS HTMLFrameSetElement includes WindowEventHandlers: member names are unique
-PASS Element includes ARIAMixin: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS SVGElement includes GlobalEventHandlers: member names are unique
-PASS SVGElement includes DocumentAndElementEventHandlers: member names are unique
-PASS SVGElement includes SVGElementInstance: member names are unique
-PASS SVGElement includes HTMLOrSVGElement: member names are unique
-PASS SVGElement includes ElementCSSInlineStyle: member names are unique
-PASS SVGGraphicsElement includes SVGTests: member names are unique
-PASS SVGSVGElement includes SVGFitToViewBox: member names are unique
-PASS SVGSVGElement includes WindowEventHandlers: member names are unique
-PASS SVGImageElement includes SVGURIReference: member names are unique
-PASS SVGScriptElement includes SVGURIReference: member names are unique
-PASS SVGAElement includes SVGURIReference: member names are unique
-FAIL SVGAElement includes HTMLHyperlinkElementUtils: member names are unique assert_true: member href is unique expected true got false
-PASS DocumentFragment includes NonElementParentNode: member names are unique
-PASS DocumentFragment includes ParentNode: member names are unique
-PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique
-PASS Window interface: existence and properties of interface object
-PASS Window interface object length
-PASS Window interface object name
-PASS Window interface: existence and properties of interface prototype object
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window interface: existence and properties of interface prototype object's "constructor" property
-PASS Window interface: existence and properties of interface prototype object's @@unscopables property
-PASS Window interface: attribute self
-PASS Window interface: attribute name
-PASS Window interface: attribute history
-PASS Window interface: attribute customElements
-PASS Window interface: attribute locationbar
-PASS Window interface: attribute menubar
-PASS Window interface: attribute personalbar
-PASS Window interface: attribute scrollbars
-PASS Window interface: attribute statusbar
-PASS Window interface: attribute toolbar
-PASS Window interface: attribute status
-PASS Window interface: operation close()
-PASS Window interface: attribute closed
-PASS Window interface: operation stop()
-PASS Window interface: operation focus()
-PASS Window interface: operation blur()
-PASS Window interface: attribute frames
-PASS Window interface: attribute length
-PASS Window interface: attribute opener
-PASS Window interface: attribute parent
-PASS Window interface: attribute frameElement
-PASS Window interface: operation open(optional USVString, optional DOMString, optional DOMString)
-PASS Window interface: attribute navigator
-FAIL Window interface: attribute originIsolated assert_own_property: The global object must have a property "originIsolated" expected property "originIsolated" missing
-PASS Window interface: operation alert()
-PASS Window interface: operation alert(DOMString)
-PASS Window interface: operation confirm(optional DOMString)
-PASS Window interface: operation prompt(optional DOMString, optional DOMString)
-PASS Window interface: operation print()
-PASS Window interface: operation postMessage(any, USVString, optional sequence<object>)
-PASS Window interface: operation postMessage(any, optional WindowPostMessageOptions)
-PASS Window interface: operation captureEvents()
-PASS Window interface: operation releaseEvents()
-PASS Window interface: attribute external
-PASS Window interface: attribute onabort
-PASS Window interface: attribute onauxclick
-PASS Window interface: attribute onblur
-PASS Window interface: attribute oncancel
-PASS Window interface: attribute oncanplay
-PASS Window interface: attribute oncanplaythrough
-PASS Window interface: attribute onchange
-PASS Window interface: attribute onclick
-PASS Window interface: attribute onclose
-PASS Window interface: attribute oncontextmenu
-PASS Window interface: attribute oncuechange
-PASS Window interface: attribute ondblclick
-PASS Window interface: attribute ondrag
-PASS Window interface: attribute ondragend
-PASS Window interface: attribute ondragenter
-PASS Window interface: attribute ondragleave
-PASS Window interface: attribute ondragover
-PASS Window interface: attribute ondragstart
-PASS Window interface: attribute ondrop
-PASS Window interface: attribute ondurationchange
-PASS Window interface: attribute onemptied
-PASS Window interface: attribute onended
-PASS Window interface: attribute onerror
-PASS Window interface: attribute onfocus
-PASS Window interface: attribute onformdata
-PASS Window interface: attribute oninput
-PASS Window interface: attribute oninvalid
-PASS Window interface: attribute onkeydown
-PASS Window interface: attribute onkeypress
-PASS Window interface: attribute onkeyup
-PASS Window interface: attribute onload
-PASS Window interface: attribute onloadeddata
-PASS Window interface: attribute onloadedmetadata
-PASS Window interface: attribute onloadstart
-PASS Window interface: attribute onmousedown
-PASS Window interface: attribute onmouseenter
-PASS Window interface: attribute onmouseleave
-PASS Window interface: attribute onmousemove
-PASS Window interface: attribute onmouseout
-PASS Window interface: attribute onmouseover
-PASS Window interface: attribute onmouseup
-PASS Window interface: attribute onpause
-PASS Window interface: attribute onplay
-PASS Window interface: attribute onplaying
-PASS Window interface: attribute onprogress
-PASS Window interface: attribute onratechange
-PASS Window interface: attribute onreset
-PASS Window interface: attribute onresize
-PASS Window interface: attribute onscroll
-FAIL Window interface: attribute onsecuritypolicyviolation assert_own_property: The global object must have a property "onsecuritypolicyviolation" expected property "onsecuritypolicyviolation" missing
-PASS Window interface: attribute onseeked
-PASS Window interface: attribute onseeking
-PASS Window interface: attribute onselect
-FAIL Window interface: attribute onslotchange assert_own_property: The global object must have a property "onslotchange" expected property "onslotchange" missing
-PASS Window interface: attribute onstalled
-PASS Window interface: attribute onsubmit
-PASS Window interface: attribute onsuspend
-PASS Window interface: attribute ontimeupdate
-PASS Window interface: attribute ontoggle
-PASS Window interface: attribute onvolumechange
-PASS Window interface: attribute onwaiting
-PASS Window interface: attribute onwebkitanimationend
-PASS Window interface: attribute onwebkitanimationiteration
-PASS Window interface: attribute onwebkitanimationstart
-PASS Window interface: attribute onwebkittransitionend
-PASS Window interface: attribute onwheel
-PASS Window interface: attribute onafterprint
-PASS Window interface: attribute onbeforeprint
-PASS Window interface: attribute onbeforeunload
-PASS Window interface: attribute onhashchange
-PASS Window interface: attribute onlanguagechange
-PASS Window interface: attribute onmessage
-PASS Window interface: attribute onmessageerror
-PASS Window interface: attribute onoffline
-PASS Window interface: attribute ononline
-PASS Window interface: attribute onpagehide
-PASS Window interface: attribute onpageshow
-PASS Window interface: attribute onpopstate
-PASS Window interface: attribute onrejectionhandled
-PASS Window interface: attribute onstorage
-PASS Window interface: attribute onunhandledrejection
-PASS Window interface: attribute onunload
-PASS Window interface: attribute origin
-PASS Window interface: attribute isSecureContext
-PASS Window interface: attribute crossOriginIsolated
-PASS Window interface: operation btoa(DOMString)
-PASS Window interface: operation atob(DOMString)
-PASS Window interface: operation setTimeout(TimerHandler, optional long, any...)
-PASS Window interface: operation clearTimeout(optional long)
-PASS Window interface: operation setInterval(TimerHandler, optional long, any...)
-PASS Window interface: operation clearInterval(optional long)
-PASS Window interface: operation queueMicrotask(VoidFunction)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)
-PASS Window interface: operation createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)
-PASS Window interface: operation requestAnimationFrame(FrameRequestCallback)
-PASS Window interface: operation cancelAnimationFrame(unsigned long)
-PASS Window interface: attribute sessionStorage
-PASS Window interface: attribute localStorage
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS Window must be primary interface of window
-PASS Stringification of window
-PASS Window interface: window must have own property "window"
-PASS Window interface: window must inherit property "self" with the proper type
-PASS Window interface: window must have own property "document"
-PASS Window interface: window must inherit property "name" with the proper type
-PASS Window interface: window must have own property "location"
-PASS Window interface: window must inherit property "history" with the proper type
-PASS Window interface: window must inherit property "customElements" with the proper type
-PASS Window interface: window must inherit property "locationbar" with the proper type
-PASS Window interface: window must inherit property "menubar" with the proper type
-PASS Window interface: window must inherit property "personalbar" with the proper type
-PASS Window interface: window must inherit property "scrollbars" with the proper type
-PASS Window interface: window must inherit property "statusbar" with the proper type
-PASS Window interface: window must inherit property "toolbar" with the proper type
-PASS Window interface: window must inherit property "status" with the proper type
-PASS Window interface: window must inherit property "close()" with the proper type
-PASS Window interface: window must inherit property "closed" with the proper type
-PASS Window interface: window must inherit property "stop()" with the proper type
-PASS Window interface: window must inherit property "focus()" with the proper type
-PASS Window interface: window must inherit property "blur()" with the proper type
-PASS Window interface: window must inherit property "frames" with the proper type
-PASS Window interface: window must inherit property "length" with the proper type
-PASS Window interface: window must have own property "top"
-PASS Window interface: window must inherit property "opener" with the proper type
-PASS Window interface: window must inherit property "parent" with the proper type
-PASS Window interface: window must inherit property "frameElement" with the proper type
-PASS Window interface: window must inherit property "open(optional USVString, optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling open(optional USVString, optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "navigator" with the proper type
-FAIL Window interface: window must inherit property "originIsolated" with the proper type assert_own_property: expected property "originIsolated" missing
-PASS Window interface: window must inherit property "alert()" with the proper type
-PASS Window interface: window must inherit property "alert(DOMString)" with the proper type
-PASS Window interface: calling alert(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "confirm(optional DOMString)" with the proper type
-PASS Window interface: calling confirm(optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "prompt(optional DOMString, optional DOMString)" with the proper type
-PASS Window interface: calling prompt(optional DOMString, optional DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "print()" with the proper type
-PASS Window interface: window must inherit property "postMessage(any, USVString, optional sequence<object>)" with the proper type
-PASS Window interface: calling postMessage(any, USVString, optional sequence<object>) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "postMessage(any, optional WindowPostMessageOptions)" with the proper type
-PASS Window interface: calling postMessage(any, optional WindowPostMessageOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "captureEvents()" with the proper type
-PASS Window interface: window must inherit property "releaseEvents()" with the proper type
-PASS Window interface: window must inherit property "external" with the proper type
-PASS Window interface: window must inherit property "onabort" with the proper type
-PASS Window interface: window must inherit property "onauxclick" with the proper type
-PASS Window interface: window must inherit property "onblur" with the proper type
-PASS Window interface: window must inherit property "oncancel" with the proper type
-PASS Window interface: window must inherit property "oncanplay" with the proper type
-PASS Window interface: window must inherit property "oncanplaythrough" with the proper type
-PASS Window interface: window must inherit property "onchange" with the proper type
-PASS Window interface: window must inherit property "onclick" with the proper type
-PASS Window interface: window must inherit property "onclose" with the proper type
-PASS Window interface: window must inherit property "oncontextmenu" with the proper type
-PASS Window interface: window must inherit property "oncuechange" with the proper type
-PASS Window interface: window must inherit property "ondblclick" with the proper type
-PASS Window interface: window must inherit property "ondrag" with the proper type
-PASS Window interface: window must inherit property "ondragend" with the proper type
-PASS Window interface: window must inherit property "ondragenter" with the proper type
-PASS Window interface: window must inherit property "ondragleave" with the proper type
-PASS Window interface: window must inherit property "ondragover" with the proper type
-PASS Window interface: window must inherit property "ondragstart" with the proper type
-PASS Window interface: window must inherit property "ondrop" with the proper type
-PASS Window interface: window must inherit property "ondurationchange" with the proper type
-PASS Window interface: window must inherit property "onemptied" with the proper type
-PASS Window interface: window must inherit property "onended" with the proper type
-PASS Window interface: window must inherit property "onerror" with the proper type
-PASS Window interface: window must inherit property "onfocus" with the proper type
-PASS Window interface: window must inherit property "onformdata" with the proper type
-PASS Window interface: window must inherit property "oninput" with the proper type
-PASS Window interface: window must inherit property "oninvalid" with the proper type
-PASS Window interface: window must inherit property "onkeydown" with the proper type
-PASS Window interface: window must inherit property "onkeypress" with the proper type
-PASS Window interface: window must inherit property "onkeyup" with the proper type
-PASS Window interface: window must inherit property "onload" with the proper type
-PASS Window interface: window must inherit property "onloadeddata" with the proper type
-PASS Window interface: window must inherit property "onloadedmetadata" with the proper type
-PASS Window interface: window must inherit property "onloadstart" with the proper type
-PASS Window interface: window must inherit property "onmousedown" with the proper type
-PASS Window interface: window must inherit property "onmouseenter" with the proper type
-PASS Window interface: window must inherit property "onmouseleave" with the proper type
-PASS Window interface: window must inherit property "onmousemove" with the proper type
-PASS Window interface: window must inherit property "onmouseout" with the proper type
-PASS Window interface: window must inherit property "onmouseover" with the proper type
-PASS Window interface: window must inherit property "onmouseup" with the proper type
-PASS Window interface: window must inherit property "onpause" with the proper type
-PASS Window interface: window must inherit property "onplay" with the proper type
-PASS Window interface: window must inherit property "onplaying" with the proper type
-PASS Window interface: window must inherit property "onprogress" with the proper type
-PASS Window interface: window must inherit property "onratechange" with the proper type
-PASS Window interface: window must inherit property "onreset" with the proper type
-PASS Window interface: window must inherit property "onresize" with the proper type
-PASS Window interface: window must inherit property "onscroll" with the proper type
-FAIL Window interface: window must inherit property "onsecuritypolicyviolation" with the proper type assert_own_property: expected property "onsecuritypolicyviolation" missing
-PASS Window interface: window must inherit property "onseeked" with the proper type
-PASS Window interface: window must inherit property "onseeking" with the proper type
-PASS Window interface: window must inherit property "onselect" with the proper type
-FAIL Window interface: window must inherit property "onslotchange" with the proper type assert_own_property: expected property "onslotchange" missing
-PASS Window interface: window must inherit property "onstalled" with the proper type
-PASS Window interface: window must inherit property "onsubmit" with the proper type
-PASS Window interface: window must inherit property "onsuspend" with the proper type
-PASS Window interface: window must inherit property "ontimeupdate" with the proper type
-PASS Window interface: window must inherit property "ontoggle" with the proper type
-PASS Window interface: window must inherit property "onvolumechange" with the proper type
-PASS Window interface: window must inherit property "onwaiting" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationend" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationiteration" with the proper type
-PASS Window interface: window must inherit property "onwebkitanimationstart" with the proper type
-PASS Window interface: window must inherit property "onwebkittransitionend" with the proper type
-PASS Window interface: window must inherit property "onwheel" with the proper type
-PASS Window interface: window must inherit property "onafterprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeprint" with the proper type
-PASS Window interface: window must inherit property "onbeforeunload" with the proper type
-PASS Window interface: window must inherit property "onhashchange" with the proper type
-PASS Window interface: window must inherit property "onlanguagechange" with the proper type
-PASS Window interface: window must inherit property "onmessage" with the proper type
-PASS Window interface: window must inherit property "onmessageerror" with the proper type
-PASS Window interface: window must inherit property "onoffline" with the proper type
-PASS Window interface: window must inherit property "ononline" with the proper type
-PASS Window interface: window must inherit property "onpagehide" with the proper type
-PASS Window interface: window must inherit property "onpageshow" with the proper type
-PASS Window interface: window must inherit property "onpopstate" with the proper type
-PASS Window interface: window must inherit property "onrejectionhandled" with the proper type
-PASS Window interface: window must inherit property "onstorage" with the proper type
-PASS Window interface: window must inherit property "onunhandledrejection" with the proper type
-PASS Window interface: window must inherit property "onunload" with the proper type
-PASS Window interface: window must inherit property "origin" with the proper type
-PASS Window interface: window must inherit property "isSecureContext" with the proper type
-PASS Window interface: window must inherit property "crossOriginIsolated" with the proper type
-PASS Window interface: window must inherit property "btoa(DOMString)" with the proper type
-PASS Window interface: calling btoa(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "atob(DOMString)" with the proper type
-PASS Window interface: calling atob(DOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setTimeout(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setTimeout(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearTimeout(optional long)" with the proper type
-PASS Window interface: calling clearTimeout(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "setInterval(TimerHandler, optional long, any...)" with the proper type
-PASS Window interface: calling setInterval(TimerHandler, optional long, any...) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "clearInterval(optional long)" with the proper type
-PASS Window interface: calling clearInterval(optional long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "queueMicrotask(VoidFunction)" with the proper type
-PASS Window interface: calling queueMicrotask(VoidFunction) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)" with the proper type
-PASS Window interface: calling createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "requestAnimationFrame(FrameRequestCallback)" with the proper type
-PASS Window interface: calling requestAnimationFrame(FrameRequestCallback) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "cancelAnimationFrame(unsigned long)" with the proper type
-PASS Window interface: calling cancelAnimationFrame(unsigned long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "sessionStorage" with the proper type
-PASS Window interface: window must inherit property "localStorage" with the proper type
-PASS Document interface: attribute domain
-PASS Document interface: attribute referrer
-PASS Document interface: attribute cookie
-PASS Document interface: attribute lastModified
-PASS Document interface: attribute readyState
-PASS Document interface: attribute title
-PASS Document interface: attribute dir
-PASS Document interface: attribute body
-PASS Document interface: attribute head
-PASS Document interface: attribute images
-PASS Document interface: attribute embeds
-PASS Document interface: attribute plugins
-PASS Document interface: attribute links
-PASS Document interface: attribute forms
-PASS Document interface: attribute scripts
-PASS Document interface: operation getElementsByName(DOMString)
-PASS Document interface: attribute currentScript
-PASS Document interface: operation open(optional DOMString, optional DOMString)
-PASS Document interface: operation open(USVString, DOMString, DOMString)
-PASS Document interface: operation close()
-PASS Document interface: operation write(DOMString...)
-PASS Document interface: operation writeln(DOMString...)
-PASS Document interface: attribute defaultView
-PASS Document interface: operation hasFocus()
-PASS Document interface: attribute designMode
-PASS Document interface: operation execCommand(DOMString, optional boolean, optional DOMString)
-PASS Document interface: operation queryCommandEnabled(DOMString)
-PASS Document interface: operation queryCommandIndeterm(DOMString)
-PASS Document interface: operation queryCommandState(DOMString)
-PASS Document interface: operation queryCommandSupported(DOMString)
-PASS Document interface: operation queryCommandValue(DOMString)
-PASS Document interface: attribute onreadystatechange
-PASS Document interface: attribute fgColor
-PASS Document interface: attribute linkColor
-PASS Document interface: attribute vlinkColor
-PASS Document interface: attribute alinkColor
-PASS Document interface: attribute bgColor
-PASS Document interface: attribute anchors
-PASS Document interface: attribute applets
-PASS Document interface: operation clear()
-PASS Document interface: operation captureEvents()
-PASS Document interface: operation releaseEvents()
-PASS Document interface: attribute all
-PASS Document interface: attribute onabort
-PASS Document interface: attribute onauxclick
-PASS Document interface: attribute onblur
-PASS Document interface: attribute oncancel
-PASS Document interface: attribute oncanplay
-PASS Document interface: attribute oncanplaythrough
-PASS Document interface: attribute onchange
-PASS Document interface: attribute onclick
-PASS Document interface: attribute onclose
-PASS Document interface: attribute oncontextmenu
-PASS Document interface: attribute oncuechange
-PASS Document interface: attribute ondblclick
-PASS Document interface: attribute ondrag
-PASS Document interface: attribute ondragend
-PASS Document interface: attribute ondragenter
-PASS Document interface: attribute ondragleave
-PASS Document interface: attribute ondragover
-PASS Document interface: attribute ondragstart
-PASS Document interface: attribute ondrop
-PASS Document interface: attribute ondurationchange
-PASS Document interface: attribute onemptied
-PASS Document interface: attribute onended
-PASS Document interface: attribute onerror
-PASS Document interface: attribute onfocus
-PASS Document interface: attribute onformdata
-PASS Document interface: attribute oninput
-PASS Document interface: attribute oninvalid
-PASS Document interface: attribute onkeydown
-PASS Document interface: attribute onkeypress
-PASS Document interface: attribute onkeyup
-PASS Document interface: attribute onload
-PASS Document interface: attribute onloadeddata
-PASS Document interface: attribute onloadedmetadata
-PASS Document interface: attribute onloadstart
-PASS Document interface: attribute onmousedown
-PASS Document interface: attribute onmouseenter
-PASS Document interface: attribute onmouseleave
-PASS Document interface: attribute onmousemove
-PASS Document interface: attribute onmouseout
-PASS Document interface: attribute onmouseover
-PASS Document interface: attribute onmouseup
-PASS Document interface: attribute onpause
-PASS Document interface: attribute onplay
-PASS Document interface: attribute onplaying
-PASS Document interface: attribute onprogress
-PASS Document interface: attribute onratechange
-PASS Document interface: attribute onreset
-PASS Document interface: attribute onresize
-PASS Document interface: attribute onscroll
-PASS Document interface: attribute onsecuritypolicyviolation
-PASS Document interface: attribute onseeked
-PASS Document interface: attribute onseeking
-PASS Document interface: attribute onselect
-FAIL Document interface: attribute onslotchange assert_true: The prototype object must have a property "onslotchange" expected true got false
-PASS Document interface: attribute onstalled
-PASS Document interface: attribute onsubmit
-PASS Document interface: attribute onsuspend
-PASS Document interface: attribute ontimeupdate
-PASS Document interface: attribute ontoggle
-PASS Document interface: attribute onvolumechange
-PASS Document interface: attribute onwaiting
-PASS Document interface: attribute onwebkitanimationend
-PASS Document interface: attribute onwebkitanimationiteration
-PASS Document interface: attribute onwebkitanimationstart
-PASS Document interface: attribute onwebkittransitionend
-PASS Document interface: attribute onwheel
-PASS Document interface: attribute oncopy
-PASS Document interface: attribute oncut
-PASS Document interface: attribute onpaste
-PASS Document interface: attribute activeElement
-PASS Document interface: iframe.contentDocument must have own property "location"
-PASS Document interface: iframe.contentDocument must inherit property "domain" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "referrer" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "cookie" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "lastModified" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "readyState" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "title" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "dir" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "body" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "head" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "images" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "embeds" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "plugins" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "links" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "forms" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "scripts" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "currentScript" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "close()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "defaultView" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "hasFocus()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "designMode" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on iframe.contentDocument with too few arguments must throw TypeError
-PASS Document interface: iframe.contentDocument must inherit property "onreadystatechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "fgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "linkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "vlinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "alinkColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "bgColor" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "anchors" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "applets" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "clear()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "captureEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "releaseEvents()" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "all" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onabort" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onauxclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onblur" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncancel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onclose" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncontextmenu" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncuechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondblclick" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrag" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondragstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondrop" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ondurationchange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onemptied" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onended" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onerror" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onfocus" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onformdata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninput" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oninvalid" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeydown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeypress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onkeyup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onload" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadeddata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onloadstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousedown" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseenter" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseleave" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmousemove" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseout" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseover" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onmouseup" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpause" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplay" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onplaying" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onprogress" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onratechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onreset" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onresize" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onscroll" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeked" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onseeking" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onselect" with the proper type
-FAIL Document interface: iframe.contentDocument must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: iframe.contentDocument must inherit property "onstalled" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsubmit" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onsuspend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontimeupdate" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "ontoggle" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onvolumechange" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwaiting" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onwheel" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncopy" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "oncut" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "onpaste" with the proper type
-PASS Document interface: iframe.contentDocument must inherit property "activeElement" with the proper type
-PASS Document interface: new Document() must have own property "location"
-PASS Document interface: new Document() must inherit property "domain" with the proper type
-PASS Document interface: new Document() must inherit property "referrer" with the proper type
-PASS Document interface: new Document() must inherit property "cookie" with the proper type
-PASS Document interface: new Document() must inherit property "lastModified" with the proper type
-PASS Document interface: new Document() must inherit property "readyState" with the proper type
-PASS Document interface: new Document() must inherit property "title" with the proper type
-PASS Document interface: new Document() must inherit property "dir" with the proper type
-PASS Document interface: new Document() must inherit property "body" with the proper type
-PASS Document interface: new Document() must inherit property "head" with the proper type
-PASS Document interface: new Document() must inherit property "images" with the proper type
-PASS Document interface: new Document() must inherit property "embeds" with the proper type
-PASS Document interface: new Document() must inherit property "plugins" with the proper type
-PASS Document interface: new Document() must inherit property "links" with the proper type
-PASS Document interface: new Document() must inherit property "forms" with the proper type
-PASS Document interface: new Document() must inherit property "scripts" with the proper type
-PASS Document interface: new Document() must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "currentScript" with the proper type
-PASS Document interface: new Document() must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "close()" with the proper type
-PASS Document interface: new Document() must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "defaultView" with the proper type
-PASS Document interface: new Document() must inherit property "hasFocus()" with the proper type
-PASS Document interface: new Document() must inherit property "designMode" with the proper type
-PASS Document interface: new Document() must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on new Document() with too few arguments must throw TypeError
-PASS Document interface: new Document() must inherit property "onreadystatechange" with the proper type
-PASS Document interface: new Document() must inherit property "fgColor" with the proper type
-PASS Document interface: new Document() must inherit property "linkColor" with the proper type
-PASS Document interface: new Document() must inherit property "vlinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "alinkColor" with the proper type
-PASS Document interface: new Document() must inherit property "bgColor" with the proper type
-PASS Document interface: new Document() must inherit property "anchors" with the proper type
-PASS Document interface: new Document() must inherit property "applets" with the proper type
-PASS Document interface: new Document() must inherit property "clear()" with the proper type
-PASS Document interface: new Document() must inherit property "captureEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "releaseEvents()" with the proper type
-PASS Document interface: new Document() must inherit property "all" with the proper type
-PASS Document interface: new Document() must inherit property "onabort" with the proper type
-PASS Document interface: new Document() must inherit property "onauxclick" with the proper type
-PASS Document interface: new Document() must inherit property "onblur" with the proper type
-PASS Document interface: new Document() must inherit property "oncancel" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplay" with the proper type
-PASS Document interface: new Document() must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: new Document() must inherit property "onchange" with the proper type
-PASS Document interface: new Document() must inherit property "onclick" with the proper type
-PASS Document interface: new Document() must inherit property "onclose" with the proper type
-PASS Document interface: new Document() must inherit property "oncontextmenu" with the proper type
-PASS Document interface: new Document() must inherit property "oncuechange" with the proper type
-PASS Document interface: new Document() must inherit property "ondblclick" with the proper type
-PASS Document interface: new Document() must inherit property "ondrag" with the proper type
-PASS Document interface: new Document() must inherit property "ondragend" with the proper type
-PASS Document interface: new Document() must inherit property "ondragenter" with the proper type
-PASS Document interface: new Document() must inherit property "ondragleave" with the proper type
-PASS Document interface: new Document() must inherit property "ondragover" with the proper type
-PASS Document interface: new Document() must inherit property "ondragstart" with the proper type
-PASS Document interface: new Document() must inherit property "ondrop" with the proper type
-PASS Document interface: new Document() must inherit property "ondurationchange" with the proper type
-PASS Document interface: new Document() must inherit property "onemptied" with the proper type
-PASS Document interface: new Document() must inherit property "onended" with the proper type
-PASS Document interface: new Document() must inherit property "onerror" with the proper type
-PASS Document interface: new Document() must inherit property "onfocus" with the proper type
-PASS Document interface: new Document() must inherit property "onformdata" with the proper type
-PASS Document interface: new Document() must inherit property "oninput" with the proper type
-PASS Document interface: new Document() must inherit property "oninvalid" with the proper type
-PASS Document interface: new Document() must inherit property "onkeydown" with the proper type
-PASS Document interface: new Document() must inherit property "onkeypress" with the proper type
-PASS Document interface: new Document() must inherit property "onkeyup" with the proper type
-PASS Document interface: new Document() must inherit property "onload" with the proper type
-PASS Document interface: new Document() must inherit property "onloadeddata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: new Document() must inherit property "onloadstart" with the proper type
-PASS Document interface: new Document() must inherit property "onmousedown" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseenter" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseleave" with the proper type
-PASS Document interface: new Document() must inherit property "onmousemove" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseout" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseover" with the proper type
-PASS Document interface: new Document() must inherit property "onmouseup" with the proper type
-PASS Document interface: new Document() must inherit property "onpause" with the proper type
-PASS Document interface: new Document() must inherit property "onplay" with the proper type
-PASS Document interface: new Document() must inherit property "onplaying" with the proper type
-PASS Document interface: new Document() must inherit property "onprogress" with the proper type
-PASS Document interface: new Document() must inherit property "onratechange" with the proper type
-PASS Document interface: new Document() must inherit property "onreset" with the proper type
-PASS Document interface: new Document() must inherit property "onresize" with the proper type
-PASS Document interface: new Document() must inherit property "onscroll" with the proper type
-PASS Document interface: new Document() must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: new Document() must inherit property "onseeked" with the proper type
-PASS Document interface: new Document() must inherit property "onseeking" with the proper type
-PASS Document interface: new Document() must inherit property "onselect" with the proper type
-FAIL Document interface: new Document() must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" not found in prototype chain
-PASS Document interface: new Document() must inherit property "onstalled" with the proper type
-PASS Document interface: new Document() must inherit property "onsubmit" with the proper type
-PASS Document interface: new Document() must inherit property "onsuspend" with the proper type
-PASS Document interface: new Document() must inherit property "ontimeupdate" with the proper type
-PASS Document interface: new Document() must inherit property "ontoggle" with the proper type
-PASS Document interface: new Document() must inherit property "onvolumechange" with the proper type
-PASS Document interface: new Document() must inherit property "onwaiting" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: new Document() must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: new Document() must inherit property "onwheel" with the proper type
-PASS Document interface: new Document() must inherit property "oncopy" with the proper type
-PASS Document interface: new Document() must inherit property "oncut" with the proper type
-PASS Document interface: new Document() must inherit property "onpaste" with the proper type
-PASS Document interface: new Document() must inherit property "activeElement" with the proper type
-PASS Document interface: documentWithHandlers must have own property "location"
-PASS Document interface: documentWithHandlers must inherit property "domain" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "referrer" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "cookie" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "lastModified" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "readyState" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "title" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "dir" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "body" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "head" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "images" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "embeds" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "plugins" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "links" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "forms" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "scripts" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "getElementsByName(DOMString)" with the proper type
-PASS Document interface: calling getElementsByName(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "currentScript" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "open(optional DOMString, optional DOMString)" with the proper type
-PASS Document interface: calling open(optional DOMString, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "open(USVString, DOMString, DOMString)" with the proper type
-PASS Document interface: calling open(USVString, DOMString, DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "close()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "write(DOMString...)" with the proper type
-PASS Document interface: calling write(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "writeln(DOMString...)" with the proper type
-PASS Document interface: calling writeln(DOMString...) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "defaultView" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "hasFocus()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "designMode" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type
-PASS Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandEnabled(DOMString)" with the proper type
-PASS Document interface: calling queryCommandEnabled(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandIndeterm(DOMString)" with the proper type
-PASS Document interface: calling queryCommandIndeterm(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandState(DOMString)" with the proper type
-PASS Document interface: calling queryCommandState(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandSupported(DOMString)" with the proper type
-PASS Document interface: calling queryCommandSupported(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "queryCommandValue(DOMString)" with the proper type
-PASS Document interface: calling queryCommandValue(DOMString) on documentWithHandlers with too few arguments must throw TypeError
-PASS Document interface: documentWithHandlers must inherit property "onreadystatechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "fgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "linkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "vlinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "alinkColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "bgColor" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "anchors" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "applets" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "clear()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "captureEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "releaseEvents()" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "all" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onabort" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onauxclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onblur" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncancel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncanplaythrough" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onclose" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncontextmenu" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncuechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondblclick" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrag" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondragstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondrop" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ondurationchange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onemptied" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onended" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onerror" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onfocus" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onformdata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninput" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oninvalid" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeydown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeypress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onkeyup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onload" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadeddata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadedmetadata" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onloadstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousedown" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseenter" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseleave" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmousemove" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseout" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseover" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onmouseup" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpause" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplay" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onplaying" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onprogress" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onratechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onreset" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onresize" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onscroll" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsecuritypolicyviolation" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeked" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onseeking" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onselect" with the proper type
-FAIL Document interface: documentWithHandlers must inherit property "onslotchange" with the proper type assert_inherits: property "onslotchange" found on object expected in prototype chain
-PASS Document interface: documentWithHandlers must inherit property "onstalled" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsubmit" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onsuspend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontimeupdate" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "ontoggle" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onvolumechange" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwaiting" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationiteration" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkitanimationstart" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwebkittransitionend" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onwheel" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncopy" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "oncut" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "onpaste" with the proper type
-PASS Document interface: documentWithHandlers must inherit property "activeElement" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/liburlpattern/DIR_METADATA b/third_party/liburlpattern/DIR_METADATA
index cf242ba..10e3ecd 100644
--- a/third_party/liburlpattern/DIR_METADATA
+++ b/third_party/liburlpattern/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail:  {
-  component:  "Blink>ServiceWorker"
+  component:  "Blink>URLPattern"
 }
 team_email:  "worker-dev@chromium.org"
diff --git a/third_party/liburlpattern/OWNERS b/third_party/liburlpattern/OWNERS
index ff6df55..dbc214d2 100644
--- a/third_party/liburlpattern/OWNERS
+++ b/third_party/liburlpattern/OWNERS
@@ -1,6 +1 @@
-# primary
-wanderview@chromium.org
-
-# secondary
-shimazu@chromium.org
-jbroman@chromium.org
+file://third_party/blink/renderer/modules/url_pattern/OWNERS
diff --git a/third_party/liburlpattern/README.chromium b/third_party/liburlpattern/README.chromium
index c284757..25629bf6 100644
--- a/third_party/liburlpattern/README.chromium
+++ b/third_party/liburlpattern/README.chromium
@@ -16,7 +16,9 @@
 all files here.
 
 Local Modifications:
+third_party/liburlpattern/DIR_METADATA
 third_party/liburlpattern/BUILD.gn
+third_party/liburlpattern/OWNERS
 third_party/liburlpattern/options.h
 third_party/liburlpattern/parse.cc
 third_party/liburlpattern/parse.h
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ebd131f..41bc465 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -44742,6 +44742,7 @@
   <int value="418769094" label="MixedContentSiteSetting:enabled"/>
   <int value="420160748" label="CornerShortcuts:enabled"/>
   <int value="422307097" label="PhysicalWeb:disabled"/>
+  <int value="422670720" label="ContextualSearchLongpressPanelHelp:disabled"/>
   <int value="423615350" label="enable-tab-audio-muting"/>
   <int value="423855924" label="enable-tab-switcher-theme-colors"/>
   <int value="425072496" label="GridLayoutForNtpShortcuts:enabled"/>
@@ -45478,6 +45479,7 @@
   <int value="1139363314" label="disable-supervised-user-blacklist"/>
   <int value="1139756271" label="WebOTPCrossDevice:enabled"/>
   <int value="1140541604" label="WinrtGeolocationImplementation:enabled"/>
+  <int value="1141918949" label="ContextualSearchLongpressPanelHelp:enabled"/>
   <int value="1142515376" label="enable-nacl"/>
   <int value="1142788238" label="FontCacheScaling:disabled"/>
   <int value="1142970266"
@@ -55411,7 +55413,7 @@
   <int value="600" label="Preferred Search Engine"/>
   <int value="601" label="Assistant: On/Off"/>
   <int value="602" label="Assistant: Related Info"/>
-  <int value="603" label="Assistant: Quick Answers"/>
+  <int value="603" label="Assistant: Quick Answers (Deprecated)"/>
   <int value="604" label="Assistant: Ok Google"/>
   <int value="605" label="Assistant: Notifications"/>
   <int value="606" label="Assistant: Voice Input"/>
@@ -66128,6 +66130,34 @@
   <int value="4" label="Phishing classifier was destructed"/>
 </enum>
 
+<enum name="SBThreatType">
+  <int value="0" label="Unused"/>
+  <int value="1" label="Safe"/>
+  <int value="2" label="URL phishing"/>
+  <int value="3" label="URL malware"/>
+  <int value="4" label="URL unwanted"/>
+  <int value="5" label="URL binary malware"/>
+  <int value="6" label="URL client side phishing"/>
+  <int value="7" label="Extension"/>
+  <int value="8" label="URL client side malware"/>
+  <int value="9" label="Blacklisted resource"/>
+  <int value="10" label="API abuse"/>
+  <int value="11" label="Subresource filter"/>
+  <int value="12" label="CSD whitelist"/>
+  <int value="13" label="URL password protection phishing"/>
+  <int value="14" label="Saved password reuse"/>
+  <int value="15" label="Signed in sync password reuse"/>
+  <int value="16" label="Signed in non sync password reuse"/>
+  <int value="17" label="Blocked ad redirect"/>
+  <int value="18" label="Ad sample"/>
+  <int value="19" label="Blocked ad popup"/>
+  <int value="20" label="Suspicious site"/>
+  <int value="21" label="Enterprise password reuse"/>
+  <int value="22" label="Billing"/>
+  <int value="23" label="Apk download"/>
+  <int value="24" label="High confidence allowlist"/>
+</enum>
+
 <enum name="ScanAppEntryPoint">
 <!-- This must be kept current with ScanAppEntryPoint in
      chromeos/components/scanning/scanning_uma.h.
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
index 6658b32..d6f811e 100644
--- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -743,6 +743,16 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.Fonts.FontFamilyMatchAttempts.System" units="attempts"
+    expires_after="2021-12-20">
+  <owner>caraitto@chromium.org</owner>
+  <owner>privacy-sandbox-dev@chromium.org</owner>
+  <summary>
+    Number of system font family match attempts made, from page load to page
+    unload. Recorded on page unload.
+  </summary>
+</histogram>
+
 <histogram name="Blink.Fonts.ShapeCache" units="units"
     expires_after="2021-10-15">
   <owner>drott@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/content/histograms.xml b/tools/metrics/histograms/histograms_xml/content/histograms.xml
index a4cb3c80..03f25aa8 100644
--- a/tools/metrics/histograms/histograms_xml/content/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/content/histograms.xml
@@ -879,6 +879,22 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.Network.Duration.{NetworkEvent}"
+    units="ms" expires_after="M90">
+  <owner>sczs@chromium.org</owner>
+  <owner>harringtond@chromium.org</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>The amount of time a {NetworkEvent} network event took.</summary>
+  <token key="NetworkEvent">
+    <variant name="ActionUploadFailure"/>
+    <variant name="ActionUploadSuccess"/>
+    <variant name="ArticlesFetchFailure"/>
+    <variant name="ArticlesFetchSuccess"/>
+    <variant name="MoreArticlesFetchFailure"/>
+    <variant name="MoreArticlesFetchSuccess"/>
+  </token>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.Network.RequestSizeKB.Compressed"
     units="KB" expires_after="M90">
   <owner>carlosk@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
index 8367c4a9..552aa75f 100644
--- a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
@@ -861,6 +861,19 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.RT.GetCache.FallbackThreatType"
+    enum="SBThreatType" expires_after="2021-12-16">
+  <owner>xinghuilu@chromium.org</owner>
+  <owner>chrome-safebrowsing-alerts@google.com</owner>
+  <summary>
+    Logs the threat type of cached verdicts. If the threat type is not safe, it
+    means the cache is a false positive. False positive verdicts are safe
+    verdicts in cache manager but turns out to be dangerous in the Safe Browsing
+    database. Logged each time a URL is checked by real time lookup and the
+    response is safe from the cache manager.
+  </summary>
+</histogram>
+
 <histogram name="SafeBrowsing.RT.GetCache.Time" units="ms"
     expires_after="2021-04-25">
   <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/perf/benchmarks/tab_search.py b/tools/perf/benchmarks/tab_search.py
index 3f1c782..bde24e4 100644
--- a/tools/perf/benchmarks/tab_search.py
+++ b/tools/perf/benchmarks/tab_search.py
@@ -55,7 +55,7 @@
     options.config.chrome_trace_config.EnableUMAHistograms(
         *TAB_SEARCH_BENCHMARK_UMA)
     # Add more buffer since we are opening a lot of tabs.
-    options.config.chrome_trace_config.SetTraceBufferSizeInKb(300 * 1024)
+    options.config.chrome_trace_config.SetTraceBufferSizeInKb(600 * 1024)
     options.SetTimelineBasedMetrics(['webuiMetric', 'umaMetric'])
     return options
 
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index 4e9865ce..5e16cd0 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -350,7 +350,6 @@
 
 _WIN_10_BENCHMARK_CONFIGS = PerfSuite(OFFICIAL_BENCHMARK_CONFIGS).Remove([
     'blink_perf.display_locking',
-    'tab_search',
     'v8.runtime_stats.top_25',
 ])
 _WIN_10_EXECUTABLE_CONFIGS = frozenset([
@@ -363,7 +362,6 @@
 _WIN_10_LOW_END_BENCHMARK_CONFIGS = PerfSuite(
     OFFICIAL_BENCHMARK_CONFIGS).Remove([
         'blink_perf.display_locking',
-        'tab_search',
     ])
 _WIN_10_LOW_END_HP_CANDIDATE_BENCHMARK_CONFIGS = PerfSuite([
     _GetBenchmarkConfig('v8.browsing_desktop'),
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 6f186ab..3a106dd 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -9,8 +9,8 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/mac/0da7da798b33eb8624ed09f0b50d83cbec80e0cb/trace_processor_shell"
         },
         "linux": {
-            "hash": "87f82b12cf8882caa16f359c2c6389ec795fe2d8",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/0da7da798b33eb8624ed09f0b50d83cbec80e0cb/trace_processor_shell"
+            "hash": "aa33412242fe4b18678f566dfe34abdf5e889fa9",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/cc9b7694ce3d8fbcc20b3492313923c7d392ac54/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/win-10-perf_map.json b/tools/perf/core/shard_maps/win-10-perf_map.json
index 551f0cd..236bd483 100644
--- a/tools/perf/core/shard_maps/win-10-perf_map.json
+++ b/tools/perf/core/shard_maps/win-10-perf_map.json
@@ -362,6 +362,9 @@
     },
     "25": {
         "benchmarks": {
+            "tab_search": {
+                "abridged": false
+            },
             "v8.browsing_desktop-future": {
                 "begin": 5,
                 "abridged": false
diff --git a/tools/perf/core/shard_maps/win-10_laptop_low_end-perf_map.json b/tools/perf/core/shard_maps/win-10_laptop_low_end-perf_map.json
index 7822a1d..19bf541 100644
--- a/tools/perf/core/shard_maps/win-10_laptop_low_end-perf_map.json
+++ b/tools/perf/core/shard_maps/win-10_laptop_low_end-perf_map.json
@@ -336,6 +336,9 @@
     },
     "25": {
         "benchmarks": {
+            "tab_search": {
+                "abridged": false
+            },
             "v8.runtime_stats.top_25": {
                 "begin": 92,
                 "abridged": false
diff --git a/tools/perf/page_sets/system_health/story_tags.py b/tools/perf/page_sets/system_health/story_tags.py
index 38501071..3b2f327 100644
--- a/tools/perf/page_sets/system_health/story_tags.py
+++ b/tools/perf/page_sets/system_health/story_tags.py
@@ -62,6 +62,7 @@
 YEAR_2018 = Tag('2018', 'Story was created or updated in 2018.')
 YEAR_2019 = Tag('2019', 'Story was created or updated in 2019.')
 YEAR_2020 = Tag('2020', 'Story was created or updated in 2020.')
+YEAR_2021 = Tag('2021', 'Story was created or updated in 2021.')
 
 
 def _ExtractAllTags():
diff --git a/ui/accessibility/platform/inspect/ax_tree_formatter.h b/ui/accessibility/platform/inspect/ax_tree_formatter.h
index 4d1ab3a..f8f6dbde 100644
--- a/ui/accessibility/platform/inspect/ax_tree_formatter.h
+++ b/ui/accessibility/platform/inspect/ax_tree_formatter.h
@@ -5,6 +5,8 @@
 #ifndef UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_TREE_FORMATTER_H_
 #define UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_TREE_FORMATTER_H_
 
+#include <memory>
+#include <string>
 #include <vector>
 
 #include "ui/accessibility/platform/inspect/ax_inspect.h"
diff --git a/ui/gfx/icon_util.cc b/ui/gfx/icon_util.cc
index 504d2093..b9702dde 100644
--- a/ui/gfx/icon_util.cc
+++ b/ui/gfx/icon_util.cc
@@ -98,7 +98,7 @@
 // |bitmaps| must be an empty vector, and not NULL.
 // Returns true on success, false on failure. This fails if any image in
 // |image_family| is not a 32-bit ARGB image, or is otherwise invalid.
-bool ConvertImageFamilyToBitmaps(
+void ConvertImageFamilyToBitmaps(
     const gfx::ImageFamily& image_family,
     std::vector<SkBitmap>* bitmaps,
     scoped_refptr<base::RefCountedMemory>* png_bytes) {
@@ -117,8 +117,7 @@
 
     SkBitmap bitmap = image.AsBitmap();
     CHECK_EQ(bitmap.colorType(), kN32_SkColorType);
-    if (bitmap.isNull())
-      return false;
+    CHECK(!bitmap.isNull());
 
     // Special case: Icons exactly 256x256 are stored in PNG format.
     if (image.Width() == IconUtil::kLargeIconSize &&
@@ -128,8 +127,6 @@
       bitmaps->push_back(bitmap);
     }
   }
-
-  return true;
 }
 
 }  // namespace
@@ -461,8 +458,7 @@
 
   std::vector<SkBitmap> bitmaps;
   scoped_refptr<base::RefCountedMemory> png_bytes;
-  if (!ConvertImageFamilyToBitmaps(resized_image_family, &bitmaps, &png_bytes))
-    return false;
+  ConvertImageFamilyToBitmaps(resized_image_family, &bitmaps, &png_bytes);
 
   // Guaranteed true because BuildResizedImageFamily will provide at least one
   // image < 256x256.
diff --git a/ui/gfx/icon_util_unittest.cc b/ui/gfx/icon_util_unittest.cc
index 0130a45..21c228e 100644
--- a/ui/gfx/icon_util_unittest.cc
+++ b/ui/gfx/icon_util_unittest.cc
@@ -207,14 +207,8 @@
   base::FilePath invalid_icon_filename =
       temp_directory_.GetPath().AppendASCII("<>?.ico");
 
-  // Null bitmap.
-  SkBitmap bitmap;
-  image_family.Add(gfx::Image::CreateFrom1xBitmap(bitmap));
-  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
-                                                       valid_icon_filename));
-  EXPECT_FALSE(base::PathExists(valid_icon_filename));
-
   // Invalid file name.
+  SkBitmap bitmap;
   image_family.clear();
   bitmap.allocN32Pixels(1, 1);
   image_family.Add(gfx::Image::CreateFrom1xBitmap(bitmap));
diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc
index 06ad22f..6d2748d 100644
--- a/ui/gfx/image/image_skia.cc
+++ b/ui/gfx/image/image_skia.cc
@@ -75,10 +75,13 @@
 
 // A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a
 // refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's
-// information. Using a |base::SequenceChecker| on a
-// |base::RefCountedThreadSafe| subclass may sound strange but is necessary to
-// turn the 'thread-non-safe modifiable ImageSkiaStorage' into the 'thread-safe
-// read-only ImageSkiaStorage'.
+// information.
+// The ImageSkia, and this class, are designed to be thread-safe in their const
+// methods, but also are bound to a single sequence for mutating methods.
+// NOTE: The FindRepresentation() method const and thread-safe *iff* it is
+// called with `fetch_new_image` set to true. Otherwise it may mutate the
+// class, which is not thread-safe. Internally, mutation is bound to a single
+// sequence with a `base::SequenceChecker`.
 class ImageSkiaStorage : public base::RefCountedThreadSafe<ImageSkiaStorage> {
  public:
   ImageSkiaStorage(std::unique_ptr<ImageSkiaSource> source,
@@ -122,7 +125,7 @@
   //   one and rescale the image.
   // Right now only Windows uses 2 and other platforms use 1 by default.
   // TODO(mukai, oshima): abandon 1 code path and use 2 for every platforms.
-  std::vector<ImageSkiaRep>::iterator FindRepresentation(
+  std::vector<const ImageSkiaRep>::iterator FindRepresentation(
       float scale,
       bool fetch_new_image) const;
 
@@ -131,9 +134,12 @@
 
   virtual ~ImageSkiaStorage();
 
-  // Vector of bitmaps and their associated scale.
+  // Each entry in here has a different scale and is returned when looking for
+  // an ImageSkiaRep of that scale.
   std::vector<gfx::ImageSkiaRep> image_reps_;
 
+  // If no ImageSkiaRep exists in `image_reps_` for a given scale, the `source_`
+  // is queried to produce an ImageSkiaRep at that scale.
   std::unique_ptr<ImageSkiaSource> source_;
 
   // Size of the image in DIP.
@@ -141,7 +147,9 @@
 
   bool read_only_;
 
-  base::SequenceChecker sequence_checker_;
+  // This isn't using SEQUENCE_CHECKER() macros because we use the sequence
+  // checker outside of DCHECKs to make branching decisions.
+  base::SequenceChecker sequence_checker_;  // nocheck
 
   DISALLOW_COPY_AND_ASSIGN(ImageSkiaStorage);
 };
@@ -203,16 +211,13 @@
   return source_ && source_->HasRepresentationAtAllScales();
 }
 
-std::vector<ImageSkiaRep>::iterator ImageSkiaStorage::FindRepresentation(
+std::vector<const ImageSkiaRep>::iterator ImageSkiaStorage::FindRepresentation(
     float scale,
     bool fetch_new_image) const {
-  ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this);
-
-  auto closest_iter = non_const->image_reps().end();
-  auto exact_iter = non_const->image_reps().end();
+  auto closest_iter = image_reps_.end();
+  auto exact_iter = image_reps_.end();
   float smallest_diff = std::numeric_limits<float>::max();
-  for (auto it = non_const->image_reps().begin(); it < image_reps_.end();
-       ++it) {
+  for (auto it = image_reps_.begin(); it < image_reps_.end(); ++it) {
     if (it->scale() == scale) {
       // found exact match
       fetch_new_image = false;
@@ -228,10 +233,15 @@
     }
   }
 
-  if (fetch_new_image && source_.get()) {
+  if (fetch_new_image && source_) {
     DCHECK(sequence_checker_.CalledOnValidSequence())
         << "An ImageSkia with the source must be accessed by the same "
            "sequence.";
+    // This method is const and thread-safe, unless `fetch_new_image` is true,
+    // in which case the method is no longer considered const and we ensure
+    // that it is used in this way on a single sequence at a time with the above
+    // `sequence_checker_`.
+    auto* mutable_this = const_cast<ImageSkiaStorage*>(this);
 
     ImageSkiaRep image;
     float resource_scale = scale;
@@ -256,17 +266,12 @@
                      [&image](const ImageSkiaRep& rep) {
                        return rep.scale() == image.scale();
                      }) == image_reps_.end()) {
-      non_const->image_reps().push_back(image);
+      mutable_this->image_reps_.push_back(image);
     }
 
-    // If the result image's scale isn't same as the expected scale, create a
-    // null ImageSkiaRep with the |scale| so that the next lookup will fall back
-    // to the closest scale.
-    if (image.is_null() || image.scale() != scale) {
-      non_const->image_reps().push_back(ImageSkiaRep(SkBitmap(), scale));
-    }
-
-    // image_reps_ must have the exact much now, so find again.
+    // image_reps_ should have the exact much now, or we will fallback
+    // to the new closest value. We pass false to prevent the generation step
+    // from running again and repeating the recursion.
     return FindRepresentation(scale, false);
   }
   return exact_iter != image_reps_.end() ? exact_iter : closest_iter;
@@ -299,6 +304,7 @@
 }
 
 ImageSkia::ImageSkia(const ImageSkiaRep& image_rep) {
+  DCHECK(!image_rep.is_null());
   Init(image_rep);
   // No other thread has reference to this, so it's safe to detach the sequence.
   DetachStorageFromSequence();
@@ -335,7 +341,18 @@
 }
 
 // static
+ImageSkia ImageSkia::CreateFromBitmap(const SkBitmap& bitmap, float scale) {
+  // An uninitialized/empty/null bitmap makes a null ImageSkia.
+  if (bitmap.drawsNothing())
+    return ImageSkia();
+  return ImageSkia(ImageSkiaRep(bitmap, scale));
+}
+
+// static
 ImageSkia ImageSkia::CreateFrom1xBitmap(const SkBitmap& bitmap) {
+  // An uninitialized/empty/null bitmap makes a null ImageSkia.
+  if (bitmap.drawsNothing())
+    return ImageSkia();
   return ImageSkia(ImageSkiaRep(bitmap, 0.0f));
 }
 
@@ -367,7 +384,6 @@
 
 void ImageSkia::AddRepresentation(const ImageSkiaRep& image_rep) {
   DCHECK(!image_rep.is_null());
-
   // TODO(oshima): This method should be called |SetRepresentation|
   // and replace the existing rep if there is already one with the
   // same scale so that we can guarantee that a ImageSkia instance contains only
@@ -496,10 +512,7 @@
 }
 
 void ImageSkia::Init(const ImageSkiaRep& image_rep) {
-  if (image_rep.GetBitmap().drawsNothing()) {
-    storage_.reset();
-    return;
-  }
+  DCHECK(!image_rep.is_null());
   storage_ = new internal::ImageSkiaStorage(
       NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight()));
   storage_->image_reps().push_back(image_rep);
diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h
index 94e36e8b..156c8283 100644
--- a/ui/gfx/image/image_skia.h
+++ b/ui/gfx/image/image_skia.h
@@ -73,9 +73,21 @@
   // Returns the maximum scale supported by this platform.
   static float GetMaxSupportedScale();
 
-  // Creates an image from the passed in bitmap.
-  // DIP width and height are based on scale factor of 1x.
-  // Adds ref to passed in bitmap.
+  // Creates an image from the passed in bitmap, which is designed for display
+  // at the device scale factor given in `scale`. The DIP width and height will
+  // be based on that scale factor. A scale factor of 0 is equivalent to
+  // calling CreateFrom1xBitmap(), which indicates the bitmap is not scaled.
+  // The `bitmap`, if present, will be made immutable. If the `bitmap` is
+  // uninitialized, empty, or null then the returned ImageSkia will be
+  // default-constructed and empty.
+  // WARNING: If the device scale factory differs from the scale given here,
+  // the resulting image will be pixelated when displayed.
+  static ImageSkia CreateFromBitmap(const SkBitmap& bitmap, float scale);
+
+  // Creates an image from the passed in bitmap. The DIP width and height will
+  // be based on scale factor of 1x. The `bitmap`, if present, will be made
+  // immutable. If the bitmap is uninitialized, empty, or null then the
+  // returned ImageSkia will be default-constructed and empty.
   // WARNING: The resulting image will be pixelated when painted on a high
   // density display.
   static ImageSkia CreateFrom1xBitmap(const SkBitmap& bitmap);
diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc
index 60a3eba..9b02af5c 100644
--- a/ui/gfx/image/image_skia_operations.cc
+++ b/ui/gfx/image/image_skia_operations.cc
@@ -69,7 +69,12 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep first_rep = first_.GetRepresentation(scale);
+    if (first_rep.is_null())
+      return first_rep;
     ImageSkiaRep second_rep = second_.GetRepresentation(scale);
+    if (second_rep.is_null())
+      return second_rep;
+
     if (first_rep.pixel_size() != second_rep.pixel_size()) {
       DCHECK_NE(first_rep.scale(), second_rep.scale());
       if (first_rep.scale() == second_rep.scale()) {
@@ -167,6 +172,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep image_rep = image_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
+
     SkBitmap alpha;
     alpha.allocN32Pixels(image_rep.pixel_width(),
                          image_rep.pixel_height());
@@ -220,6 +228,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep source_rep = source_.GetRepresentation(scale);
+    if (source_rep.is_null())
+      return source_rep;
+
     gfx::Rect bounds = DIPToPixelBounds(gfx::Rect(src_x_, src_y_, dst_w_,
                                                   dst_h_), source_rep.scale());
     return ImageSkiaRep(SkBitmapOperations::CreateTiledBitmap(
@@ -251,6 +262,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep image_rep = image_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
+
     return gfx::ImageSkiaRep(SkBitmapOperations::CreateHSLShiftedBitmap(
                                  image_rep.GetBitmap(), hsl_shift_),
                              image_rep.scale());
@@ -280,7 +294,12 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep image_rep = image_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
     ImageSkiaRep mask_rep = mask_.GetRepresentation(scale);
+    if (mask_rep.is_null())
+      return image_rep;
+
     if (image_rep.scale() != mask_rep.scale()) {
       image_rep = image_.GetRepresentation(1.0f);
       mask_rep = mask_.GetRepresentation(1.0f);
@@ -314,6 +333,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep image_rep = image_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
+
     SkIRect subset_bounds_in_pixel = RectToSkIRect(
         DIPToPixelBounds(subset_bounds_, image_rep.scale()));
     SkBitmap dst;
@@ -346,6 +368,8 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     const ImageSkiaRep& image_rep = source_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
     if (image_rep.GetWidth() == target_dip_size_.width() &&
         image_rep.GetHeight() == target_dip_size_.height())
       return image_rep;
@@ -376,6 +400,8 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     const ImageSkiaRep& image_rep = source_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
 
     ShadowValues shadows_in_pixel;
     for (size_t i = 0; i < shadows_in_dip_.size(); ++i)
@@ -442,6 +468,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     const ImageSkiaRep& image_rep = source_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
+
     const SkBitmap rotated_bitmap =
         SkBitmapOperations::Rotate(image_rep.GetBitmap(), rotation_);
     return ImageSkiaRep(rotated_bitmap, image_rep.scale());
@@ -487,6 +516,9 @@
   // gfx::ImageSkiaSource overrides:
   ImageSkiaRep GetImageForScale(float scale) override {
     ImageSkiaRep image_rep = image_.GetRepresentation(scale);
+    if (image_rep.is_null())
+      return image_rep;
+
     return ImageSkiaRep(
         SkBitmapOperations::CreateColorMask(image_rep.GetBitmap(), color_),
         image_rep.scale());
diff --git a/ui/gfx/image/image_skia_rep_default.cc b/ui/gfx/image/image_skia_rep_default.cc
index a8cbaf36..49a9f76 100644
--- a/ui/gfx/image/image_skia_rep_default.cc
+++ b/ui/gfx/image/image_skia_rep_default.cc
@@ -4,7 +4,7 @@
 
 #include "ui/gfx/image/image_skia_rep_default.h"
 
-#include "base/check.h"
+#include "base/check_op.h"
 #include "base/notreached.h"
 #include "cc/paint/display_item_list.h"
 #include "cc/paint/record_paint_canvas.h"
@@ -33,10 +33,8 @@
       pixel_size_(gfx::Size(src.width(), src.height())),
       bitmap_(src),
       scale_(scale) {
-  // If the bitmap has been initialized then it must be in N32 format.
-  if (!(bitmap_.isNull() && bitmap_.colorType() == kUnknown_SkColorType &&
-        bitmap_.alphaType() == kUnknown_SkAlphaType))
-    CHECK_EQ(bitmap_.colorType(), kN32_SkColorType);
+  CHECK_EQ(bitmap_.colorType(), kN32_SkColorType);
+  DCHECK(!bitmap_.drawsNothing());
   bitmap_.setImmutable();
   paint_image_ = cc::PaintImage::CreateFromBitmap(src);
 }
@@ -47,7 +45,9 @@
     : paint_record_(std::move(paint_record)),
       type_(ImageRepType::kImageTypeDrawable),
       pixel_size_(pixel_size),
-      scale_(scale) {}
+      scale_(scale) {
+  DCHECK(!pixel_size.IsEmpty());
+}
 
 ImageSkiaRep::ImageSkiaRep(const ImageSkiaRep& other)
     : paint_image_(other.paint_image_),
diff --git a/ui/gfx/image/image_skia_rep_default.h b/ui/gfx/image/image_skia_rep_default.h
index 28064f4..651ff76 100644
--- a/ui/gfx/image/image_skia_rep_default.h
+++ b/ui/gfx/image/image_skia_rep_default.h
@@ -28,17 +28,21 @@
   // Creates a bitmap with kARGB_8888_Config config with given |size| in DIP.
   // This allocates pixels in the bitmap. It is guaranteed that the data in the
   // bitmap are initialized but the actual values are undefined.
-  // Specifying 0 scale means the image is for unscaled image. (unscaled()
-  // returns truen, and scale() returns 1.0f;)
+  // Specifying 0 scale means the image is for unscaled image (unscaled()
+  // returns true, and scale() returns 1.0f).
   ImageSkiaRep(const gfx::Size& size, float scale);
 
-  // Creates a bitmap with given scale.
-  // Adds ref to |src|.
+  // Creates an ImageSkiaRep that holds the `src` bitmap, which is created for
+  // display at the given device scale factor. Takes ownership of a reference to
+  // the SkBitmap's backing store. The `src` bitmap may not be uninitialized,
+  // null or empty; in that case the default constructor should be used
+  // instead.
   ImageSkiaRep(const SkBitmap& src, float scale);
 
   // Creates an image rep backed by a paint record of given size and scale. This
-  // is used when the image representation is sourced from a drawable sunch as
-  // CanvasImageSource.
+  // is used when the image representation is sourced from a drawable such as
+  // CanvasImageSource. The `size` must not be empty; in that case the default
+  // constructor should be used instead.
   ImageSkiaRep(sk_sp<cc::PaintRecord> paint_record,
                const gfx::Size& size,
                float scale);
diff --git a/ui/gfx/image/image_skia_rep_ios.cc b/ui/gfx/image/image_skia_rep_ios.cc
index c28b5ed..5fb5925c 100644
--- a/ui/gfx/image/image_skia_rep_ios.cc
+++ b/ui/gfx/image/image_skia_rep_ios.cc
@@ -4,6 +4,7 @@
 
 #include "ui/gfx/image/image_skia_rep_ios.h"
 
+#include "base/check_op.h"
 #include "ui/gfx/color_palette.h"
 
 namespace gfx {
@@ -22,6 +23,8 @@
     : pixel_size_(gfx::Size(src.width(), src.height())),
       bitmap_(src),
       scale_(scale) {
+  CHECK_EQ(src.colorType(), kN32_SkColorType);
+  DCHECK(!bitmap_.drawsNothing());
   bitmap_.setImmutable();
 }
 
diff --git a/ui/gfx/image/mojom/BUILD.gn b/ui/gfx/image/mojom/BUILD.gn
index d4536428..dd07e3cbc 100644
--- a/ui/gfx/image/mojom/BUILD.gn
+++ b/ui/gfx/image/mojom/BUILD.gn
@@ -20,7 +20,6 @@
         {
           mojom = "gfx.mojom.ImageSkiaRep"
           cpp = "::gfx::ImageSkiaRep"
-          nullable_is_same_type = true
         },
       ]
       traits_headers = [ "image_skia_mojom_traits.h" ]
@@ -61,6 +60,7 @@
     "//base",
     "//base/test:test_support",
     "//mojo/public/cpp/bindings",
+    "//mojo/public/cpp/test_support:test_utils",
     "//testing/gtest",
     "//ui/gfx:test_support",
   ]
diff --git a/ui/gfx/image/mojom/image.mojom b/ui/gfx/image/mojom/image.mojom
index fe61257b..e875200 100644
--- a/ui/gfx/image/mojom/image.mojom
+++ b/ui/gfx/image/mojom/image.mojom
@@ -8,7 +8,10 @@
 
 [Stable]
 struct ImageSkiaRep {
-  // Transport of the bitmap in this representation.
+  // Transport of the bitmap in this representation. The type here is
+  // BitmapWithArbitraryBpp because this structure is marked Stable, however
+  // only N32-format bitmaps are allowed, similar to the skia.mojom.BitmapN32
+  // type.
   skia.mojom.BitmapWithArbitraryBpp bitmap;
 
   // Corresponding scale of the bitmap or 0 if unscaled.
diff --git a/ui/gfx/image/mojom/image_skia_mojom_traits.cc b/ui/gfx/image/mojom/image_skia_mojom_traits.cc
index c45c063..cda3a62 100644
--- a/ui/gfx/image/mojom/image_skia_mojom_traits.cc
+++ b/ui/gfx/image/mojom/image_skia_mojom_traits.cc
@@ -11,11 +11,20 @@
 namespace mojo {
 
 // static
+SkBitmap
+StructTraits<gfx::mojom::ImageSkiaRepDataView, gfx::ImageSkiaRep>::bitmap(
+    const gfx::ImageSkiaRep& input) {
+  SkBitmap bitmap = input.GetBitmap();
+  DCHECK(!bitmap.drawsNothing());
+  CHECK_EQ(bitmap.colorType(), kN32_SkColorType);
+  return bitmap;
+}
+
+// static
 float StructTraits<gfx::mojom::ImageSkiaRepDataView, gfx::ImageSkiaRep>::scale(
     const gfx::ImageSkiaRep& input) {
   const float scale = input.unscaled() ? 0.0f : input.scale();
   DCHECK_GE(scale, 0.0f);
-
   return scale;
 }
 
@@ -30,6 +39,14 @@
   SkBitmap bitmap;
   if (!data.ReadBitmap(&bitmap))
     return false;
+  // Null/uninitialized bitmaps are not allowed, and an ImageSkiaRep is never
+  // empty-sized either.
+  if (bitmap.drawsNothing())
+    return false;
+  // Similar to BitmapN32, ImageSkiaReps are expected to have an N32 bitmap
+  // type.
+  if (bitmap.colorType() != kN32_SkColorType)
+    return false;
 
   *out = gfx::ImageSkiaRep(bitmap, data.scale());
   return true;
diff --git a/ui/gfx/image/mojom/image_skia_mojom_traits.h b/ui/gfx/image/mojom/image_skia_mojom_traits.h
index d648a39..eb35165 100644
--- a/ui/gfx/image/mojom/image_skia_mojom_traits.h
+++ b/ui/gfx/image/mojom/image_skia_mojom_traits.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "base/check_op.h"
 #include "skia/public/mojom/bitmap_skbitmap_mojom_traits.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/image/image_skia.h"
@@ -19,14 +20,9 @@
 
 template <>
 struct StructTraits<gfx::mojom::ImageSkiaRepDataView, gfx::ImageSkiaRep> {
-  static SkBitmap bitmap(const gfx::ImageSkiaRep& input) {
-    return input.GetBitmap();
-  }
+  static SkBitmap bitmap(const gfx::ImageSkiaRep& input);
   static float scale(const gfx::ImageSkiaRep& input);
 
-  static bool IsNull(const gfx::ImageSkiaRep& input) { return input.is_null(); }
-  static void SetToNull(gfx::ImageSkiaRep* out) { *out = gfx::ImageSkiaRep(); }
-
   static bool Read(gfx::mojom::ImageSkiaRepDataView data,
                    gfx::ImageSkiaRep* out);
 };
diff --git a/ui/gfx/image/mojom/image_traits_unittest.cc b/ui/gfx/image/mojom/image_traits_unittest.cc
index ce090b7..2e4e5e71 100644
--- a/ui/gfx/image/mojom/image_traits_unittest.cc
+++ b/ui/gfx/image/mojom/image_traits_unittest.cc
@@ -9,14 +9,15 @@
 #include "base/test/task_environment.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/test_support/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/image/image_skia_source.h"
 #include "ui/gfx/image/image_unittest_util.h"
+#include "ui/gfx/image/mojom/image.mojom.h"
 #include "ui/gfx/image/mojom/image_skia_mojom_traits.h"
-#include "ui/gfx/image/mojom/image_traits_test_service.mojom.h"
 
 namespace gfx {
 
@@ -25,8 +26,7 @@
 // A test ImageSkiaSource that creates an ImageSkiaRep for any scale.
 class TestImageSkiaSource : public ImageSkiaSource {
  public:
-  explicit TestImageSkiaSource(const gfx::Size& dip_size)
-      : dip_size_(dip_size) {}
+  explicit TestImageSkiaSource(const Size& dip_size) : dip_size_(dip_size) {}
   ~TestImageSkiaSource() override = default;
 
   // ImageSkiaSource:
@@ -35,156 +35,132 @@
   }
 
  private:
-  const gfx::Size dip_size_;
+  const Size dip_size_;
 
   DISALLOW_COPY_AND_ASSIGN(TestImageSkiaSource);
 };
 
-// Revisit this after Deserialize(Serialize()) API works with handles.
-class ImageTraitsTest : public testing::Test,
-                        public mojom::ImageTraitsTestService {
- public:
-  ImageTraitsTest() = default;
-
-  // testing::Test:
-  void SetUp() override {
-    receivers_.Add(this, service_.BindNewPipeAndPassReceiver());
-  }
-
-  mojo::Remote<mojom::ImageTraitsTestService>& service() { return service_; }
-
- private:
-  // mojom::ImageTraitsTestService:
-  void EchoImageSkiaRep(const ImageSkiaRep& in,
-                        EchoImageSkiaRepCallback callback) override {
-    std::move(callback).Run(in);
-  }
-  void EchoImageSkia(const ImageSkia& in,
-                     EchoImageSkiaCallback callback) override {
-    std::move(callback).Run(in);
-  }
-
-  base::test::TaskEnvironment task_environment_;
-  mojo::ReceiverSet<ImageTraitsTestService> receivers_;
-  mojo::Remote<mojom::ImageTraitsTestService> service_;
-
-  DISALLOW_COPY_AND_ASSIGN(ImageTraitsTest);
-};
+// A helper to construct a skia.mojom.BitmapN32 without using StructTraits
+// to bypass checks on the sending/serialization side.
+mojo::StructPtr<mojom::ImageSkiaRep> ConstructImageSkiaRep(
+    const SkBitmap& bitmap,
+    float scale) {
+  auto mojom_rep = mojom::ImageSkiaRep::New();
+  mojom_rep->bitmap = bitmap;
+  mojom_rep->scale = scale;
+  return mojom_rep;
+}
 
 }  // namespace
 
-TEST_F(ImageTraitsTest, NullImageSkiaRep) {
-  ImageSkiaRep null_rep;
-  ASSERT_TRUE(null_rep.is_null());
-
-  ImageSkiaRep output(gfx::Size(1, 1), 1.0f);
-  ASSERT_FALSE(output.is_null());
-  service()->EchoImageSkiaRep(null_rep, &output);
-  EXPECT_TRUE(output.is_null());
+TEST(ImageTraitsTest, VerifyMojomConstruction) {
+  SkBitmap bitmap;
+  bitmap.allocN32Pixels(1, 1);
+  mojo::StructPtr<mojom::ImageSkiaRep> input = ConstructImageSkiaRep(bitmap, 1);
+  ImageSkiaRep output;
+  EXPECT_TRUE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkiaRep>(input, output));
 }
 
-TEST_F(ImageTraitsTest, EmptyImageSkiaRep) {
+TEST(ImageTraitsTest, BadColorTypeImageSkiaRep_Deserialize) {
+  SkBitmap a8_bitmap;
+  a8_bitmap.allocPixels(SkImageInfo::MakeA8(1, 1));
+
+  mojo::StructPtr<mojom::ImageSkiaRep> input =
+      ConstructImageSkiaRep(a8_bitmap, 1);
+  ImageSkiaRep output;
+  EXPECT_FALSE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkiaRep>(input, output));
+}
+
+TEST(ImageTraitsTest, EmptyImageSkiaRep_Deserialize) {
   SkBitmap empty_bitmap;
   empty_bitmap.allocN32Pixels(0, 0);
   // Empty SkBitmap is not null.
   EXPECT_FALSE(empty_bitmap.isNull());
   EXPECT_TRUE(empty_bitmap.drawsNothing());
 
-  ImageSkiaRep empty_rep(empty_bitmap, 1.0f);
-  // ImageSkiaRep with empty bitmap is not null.
-  ASSERT_FALSE(empty_rep.is_null());
-
-  ImageSkiaRep output(gfx::Size(1, 1), 1.0f);
-  ASSERT_FALSE(output.is_null());
-  service()->EchoImageSkiaRep(empty_rep, &output);
-  EXPECT_TRUE(empty_rep.GetBitmap().drawsNothing());
-  EXPECT_TRUE(test::AreBitmapsEqual(empty_rep.GetBitmap(), output.GetBitmap()));
+  mojo::StructPtr<mojom::ImageSkiaRep> input =
+      ConstructImageSkiaRep(empty_bitmap, 1);
+  ImageSkiaRep output;
+  EXPECT_FALSE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkiaRep>(input, output));
 }
 
-TEST_F(ImageTraitsTest, ImageSkiaRep) {
-  ImageSkiaRep image_rep(gfx::Size(2, 4), 2.0f);
+TEST(ImageTraitsTest, ValidImageSkiaRep) {
+  ImageSkiaRep image_rep(Size(2, 4), 2.0f);
 
   ImageSkiaRep output;
-  service()->EchoImageSkiaRep(image_rep, &output);
+  ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::ImageSkiaRep>(
+      image_rep, output));
 
   EXPECT_FALSE(output.is_null());
   EXPECT_EQ(image_rep.scale(), output.scale());
   EXPECT_TRUE(test::AreBitmapsEqual(image_rep.GetBitmap(), output.GetBitmap()));
 }
 
-TEST_F(ImageTraitsTest, UnscaledImageSkiaRep) {
-  ImageSkiaRep image_rep(gfx::Size(2, 4), 0.0f);
+TEST(ImageTraitsTest, UnscaledImageSkiaRep) {
+  ImageSkiaRep image_rep(Size(2, 4), 0.0f);
   ASSERT_TRUE(image_rep.unscaled());
 
-  ImageSkiaRep output(gfx::Size(1, 1), 1.0f);
-  EXPECT_FALSE(output.unscaled());
-  service()->EchoImageSkiaRep(image_rep, &output);
+  ImageSkiaRep output;
+  ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::ImageSkiaRep>(
+      image_rep, output));
   EXPECT_TRUE(output.unscaled());
   EXPECT_TRUE(test::AreBitmapsEqual(image_rep.GetBitmap(), output.GetBitmap()));
 }
 
-TEST_F(ImageTraitsTest, NullImageSkia) {
+TEST(ImageTraitsTest, NullImageSkia) {
   ImageSkia null_image;
   ASSERT_TRUE(null_image.isNull());
 
-  ImageSkia output(ImageSkiaRep(gfx::Size(1, 1), 1.0f));
+  ImageSkia output(ImageSkiaRep(Size(1, 1), 1.0f));
   ASSERT_FALSE(output.isNull());
-  service()->EchoImageSkia(null_image, &output);
+  ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::ImageSkia>(null_image,
+                                                                    output));
   EXPECT_TRUE(output.isNull());
 }
 
-TEST_F(ImageTraitsTest, ImageSkiaRepsAreCreatedAsNeeded) {
-  const gfx::Size kSize(1, 2);
+TEST(ImageTraitsTest, ImageSkiaRepsAreCreatedAsNeeded) {
+  const Size kSize(1, 2);
   ImageSkia image(std::make_unique<TestImageSkiaSource>(kSize), kSize);
   EXPECT_FALSE(image.isNull());
   EXPECT_TRUE(image.image_reps().empty());
 
   ImageSkia output;
   EXPECT_TRUE(output.isNull());
-  service()->EchoImageSkia(image, &output);
+  ASSERT_TRUE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkia>(image, output));
   EXPECT_FALSE(image.image_reps().empty());
   EXPECT_FALSE(output.isNull());
 }
 
-TEST_F(ImageTraitsTest, ImageSkia) {
-  const gfx::Size kSize(1, 2);
+TEST(ImageTraitsTest, ImageSkia) {
+  const Size kSize(1, 2);
   ImageSkia image(std::make_unique<TestImageSkiaSource>(kSize), kSize);
   image.GetRepresentation(1.0f);
   image.GetRepresentation(2.0f);
 
   ImageSkia output;
-  service()->EchoImageSkia(image, &output);
+  ASSERT_TRUE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkia>(image, output));
 
   EXPECT_TRUE(test::AreImagesEqual(Image(output), Image(image)));
 }
 
-TEST_F(ImageTraitsTest, EmptyRepPreserved) {
-  const gfx::Size kSize(1, 2);
-  ImageSkia image(std::make_unique<TestImageSkiaSource>(kSize), kSize);
-  image.GetRepresentation(1.0f);
-
-  SkBitmap empty_bitmap;
-  empty_bitmap.allocN32Pixels(0, 0);
-  image.AddRepresentation(ImageSkiaRep(empty_bitmap, 2.0f));
-
-  ImageSkia output;
-  service()->EchoImageSkia(image, &output);
-
-  EXPECT_TRUE(test::AreImagesEqual(Image(output), Image(image)));
-}
-
-TEST_F(ImageTraitsTest, ImageSkiaWithOperations) {
-  const gfx::Size kSize(32, 32);
+TEST(ImageTraitsTest, ImageSkiaWithOperations) {
+  const Size kSize(32, 32);
   ImageSkia image(std::make_unique<TestImageSkiaSource>(kSize), kSize);
 
-  const gfx::Size kNewSize(16, 16);
+  const Size kNewSize(16, 16);
   ImageSkia resized = ImageSkiaOperations::CreateResizedImage(
       image, skia::ImageOperations::RESIZE_BEST, kNewSize);
   resized.GetRepresentation(1.0f);
   resized.GetRepresentation(2.0f);
 
   ImageSkia output;
-  service()->EchoImageSkia(resized, &output);
+  ASSERT_TRUE(
+      mojo::test::SerializeAndDeserialize<mojom::ImageSkia>(resized, output));
 
   EXPECT_TRUE(test::AreImagesEqual(Image(output), Image(resized)));
 }
diff --git a/ui/gfx/nine_image_painter_unittest.cc b/ui/gfx/nine_image_painter_unittest.cc
index 1cf8506..9897d00 100644
--- a/ui/gfx/nine_image_painter_unittest.cc
+++ b/ui/gfx/nine_image_painter_unittest.cc
@@ -72,7 +72,7 @@
 
   float image_scale = 2.f;
 
-  gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
   gfx::Insets insets(10, 10, 10, 10);
   gfx::NineImagePainter painter(image, insets);
 
@@ -104,7 +104,7 @@
   src.eraseColor(SK_ColorGREEN);
   src.erase(SK_ColorRED, SkIRect::MakeXYWH(2, 2, 2, 2));
 
-  gfx::ImageSkia image(gfx::ImageSkiaRep(src, 0.0f));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(src);
   gfx::Insets insets(2, 2, 2, 2);
   gfx::NineImagePainter painter(image, insets);
 
@@ -136,7 +136,7 @@
   src.eraseColor(SK_ColorRED);
   src.eraseArea(SkIRect::MakeXYWH(1, 1, 8, 8), SK_ColorGREEN);
 
-  gfx::ImageSkia image(gfx::ImageSkiaRep(src, 0.0f));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(src);
   gfx::Insets insets(1, 1, 1, 1);
   gfx::NineImagePainter painter(image, insets);
 
@@ -168,7 +168,7 @@
 
   float image_scale = 2.f;
 
-  gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
   gfx::Insets insets(10, 10, 10, 10);
   gfx::NineImagePainter painter(image, insets);
 
@@ -199,7 +199,7 @@
 
   float image_scale = 2.f;
 
-  gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
   gfx::Insets insets(10, 10, 10, 10);
   gfx::NineImagePainter painter(image, insets);
 
diff --git a/ui/login/BUILD.gn b/ui/login/BUILD.gn
index 3d66b87..6acddfc8 100644
--- a/ui/login/BUILD.gn
+++ b/ui/login/BUILD.gn
@@ -6,3 +6,6 @@
 
 js_library("display_manager_types") {
 }
+
+js_library("login_ui_tools") {
+}
diff --git a/ui/login/login_ui_tools.js b/ui/login/login_ui_tools.js
index d66d64b..66ed268 100644
--- a/ui/login/login_ui_tools.js
+++ b/ui/login/login_ui_tools.js
@@ -10,18 +10,19 @@
   return {
     /**
      * Computes max-height for an element so that it doesn't overlap shelf.
-     * @param {element} DOM element
-     * @param {wholeWindow} Whether the element can go outside outer-container.
+     * @param {Element} element DOM element
+     * @param {boolean} wholeWindow Whether the element can go outside
+     *                  outer-container.
      */
     getMaxHeightBeforeShelfOverlapping : function(element, wholeWindow) {
       var maxAllowedHeight =
           $('outer-container').offsetHeight -
           element.getBoundingClientRect().top -
-          parseInt(window.getComputedStyle(element).marginTop) -
-          parseInt(window.getComputedStyle(element).marginBottom);
+          parseInt(window.getComputedStyle(element).marginTop, 10) -
+          parseInt(window.getComputedStyle(element).marginBottom, 10);
       if (wholeWindow) {
         maxAllowedHeight +=
-           parseInt(window.getComputedStyle($('outer-container')).bottom);
+           parseInt(window.getComputedStyle($('outer-container')).bottom, 10);
       }
       return maxAllowedHeight;
     },
@@ -29,15 +30,29 @@
     /**
      * Computes max-width for an element so that it does fit the
      * outer-container.
-     * @param {element} DOM element
+     * @param {Element} element DOM element
      */
     getMaxWidthToFit : function(element) {
       var maxAllowedWidth =
           $('outer-container').offsetWidth -
           element.getBoundingClientRect().left -
-          parseInt(window.getComputedStyle(element).marginLeft) -
-          parseInt(window.getComputedStyle(element).marginRight);
+          parseInt(window.getComputedStyle(element).marginLeft, 10) -
+          parseInt(window.getComputedStyle(element).marginRight, 10);
       return maxAllowedWidth;
     },
+
+    /**
+     * Listens to key events on input element.
+     * @param {Element} element DOM element
+     * @param {Object} callback
+     */
+    addSubmitListener : function(element, callback) {
+      element.addEventListener('keydown', (function(callback, e) {
+        if (e.keyCode != 13)
+          return;
+        callback();
+      }).bind(undefined, callback));
+    },
   }
+
 });
diff --git a/ui/views/button_drag_utils.cc b/ui/views/button_drag_utils.cc
index ca50afc..23997ee 100644
--- a/ui/views/button_drag_utils.cc
+++ b/ui/views/button_drag_utils.cc
@@ -91,7 +91,7 @@
                         widget.GetCompositor()->is_pixel_canvas())
           .context(),
       size));
-  gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, raster_scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(bitmap, raster_scale);
   data->provider().SetDragImage(image, press_point);
 }
 
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 205ace72..15d30255 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -1506,7 +1506,8 @@
   float raster_scale = ScaleFactorForDragFromWidget(source->GetWidget());
   gfx::Canvas canvas(item->size(), raster_scale, false /* opaque */);
   item->PaintButton(&canvas, MenuItemView::PaintButtonMode::kForDrag);
-  gfx::ImageSkia image(gfx::ImageSkiaRep(canvas.GetBitmap(), raster_scale));
+  gfx::ImageSkia image =
+      gfx::ImageSkia::CreateFromBitmap(canvas.GetBitmap(), raster_scale);
 
   std::unique_ptr<OSExchangeData> data(std::make_unique<OSExchangeData>());
   item->GetDelegate()->WriteDragData(item, data.get());
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index 111f903f..1c79aa2 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -1328,7 +1328,7 @@
           .context(),
       label.size()));
   constexpr gfx::Vector2d kOffset(-15, 0);
-  gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, raster_scale));
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(bitmap, raster_scale);
   data->provider().SetDragImage(image, kOffset);
   if (controller_)
     controller_->OnWriteDragData(data);
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
index 2e14f41d..66a36e9 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -71,7 +71,8 @@
       :host ::slotted([slot=title]) {
         color: var(--cr-primary-text-color);
         flex: 1;
-        font-size: calc(15 / 13 * 100%);
+        font-family: var(--cr-dialog-font-family, inherit);
+        font-size: var(--cr-dialog-title-font-size, calc(15 / 13 * 100%));
         line-height: 1;
         padding-bottom: var(--cr-dialog-title-slot-padding-bottom, 16px);
         padding-inline-end:  var(--cr-dialog-title-slot-padding-end, 20px);