diff --git a/DEPS b/DEPS
index 0dcbf8ce..de53126 100644
--- a/DEPS
+++ b/DEPS
@@ -78,7 +78,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '9a1d0f9307ce99a8831f97da87cf7bbd98576731',
+  'v8_revision': '95d3c08c1c9a278603b40e99de6a7efaf73ea1b3',
   # 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.
@@ -86,7 +86,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '58ba6bf5ecedaadbbe4d469545dca5017cf53034',
+  'angle_revision': '9b88991c7211fdc9144c793b66f429ee01fce032',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
diff --git a/chrome/VERSION b/chrome/VERSION
index 24ee40d..13e16b7 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=65
 MINOR=0
-BUILD=3289
+BUILD=3290
 PATCH=0
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/md_extensions_strings.grdp
index 0e51dd7..04733c8 100644
--- a/chrome/app/md_extensions_strings.grdp
+++ b/chrome/app/md_extensions_strings.grdp
@@ -40,6 +40,9 @@
   <message name="IDS_MD_EXTENSIONS_ITEM_INSPECT_VIEWS_EXTRA" desc="The text to indicate there are additional inspectable views that aren't listed.">
     <ph name="NUMBER_OF_VIEWS">$1<ex>2</ex></ph> more...
   </message>
+  <message name="IDS_MD_EXTENSIONS_ITEM_NO_ACTIVE_VIEWS" desc="Placeholder text when the extension Inspect Views list is empty.">
+    No active views
+  </message>
   <message name="IDS_MD_EXTENSIONS_ITEM_ALLOW_INCOGNITO" desc="The text next to the checkbox to enable an extension in incognito mode.">
     Allow in incognito
   </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index a5925c2..7dde218 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2306,6 +2306,12 @@
      flag_descriptions::kOfflinePagesPrefetchingUIName,
      flag_descriptions::kOfflinePagesPrefetchingUIDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(offline_pages::kOfflinePagesPrefetchingUIFeature)},
+    {"offline-pages-limitless-prefetching",
+     flag_descriptions::kOfflinePagesLimitlessPrefetchingName,
+     flag_descriptions::kOfflinePagesLimitlessPrefetchingDescription,
+     kOsAndroid,
+     FEATURE_VALUE_TYPE(
+         offline_pages::kOfflinePagesLimitlessPrefetchingFeature)},
     {"background-loader-for-downloads",
      flag_descriptions::kBackgroundLoaderForDownloadsName,
      flag_descriptions::kBackgroundLoaderForDownloadsDescription, kOsAndroid,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 8a750c7..18597687 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2013,6 +2013,13 @@
     "V2 features include attributing pages to the app that initiated the "
     "custom tabs, and being able to query for pages by page attribution.";
 
+const char kOfflinePagesLimitlessPrefetchingName[] =
+    "Removes resource usage limits for the prefetching of offline pages.";
+const char kOfflinePagesLimitlessPrefetchingDescription[] =
+    "Allows the prefetching of suggested offline pages to ignore resource "
+    "usage limits. This allows it to completely ignore data usage limitations "
+    "and allows downloads to happen with any kind of connection.";
+
 const char kOfflinePagesLoadSignalCollectingName[] =
     "Enables collecting load timing data for offline page snapshots.";
 const char kOfflinePagesLoadSignalCollectingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 524022a..e0898576 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1236,6 +1236,9 @@
 extern const char kOfflinePagesCtV2Name[];
 extern const char kOfflinePagesCtV2Description[];
 
+extern const char kOfflinePagesLimitlessPrefetchingName[];
+extern const char kOfflinePagesLimitlessPrefetchingDescription[];
+
 extern const char kOfflinePagesLoadSignalCollectingName[];
 extern const char kOfflinePagesLoadSignalCollectingDescription[];
 
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html
index 76676e4..f9a0809 100644
--- a/chrome/browser/resources/md_extensions/detail_view.html
+++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -270,11 +270,13 @@
           <div class="section-content">[[data.id]]</div>
         </div>
         <template is="dom-if" if="[[inDevMode]]">
-          <div class="section block" id="inspectable-views"
-              hidden="[[!data.views.length]]">
+          <div class="section block" id="inspectable-views">
             <div class="section-title">$i18n{itemInspectViews}</div>
             <div class="section-content">
               <ul id="inspect-views">
+                <li hidden="[[data.views.length]]">
+                  $i18n{noActiveViews}
+                </li>
                 <template is="dom-repeat" items="[[data.views]]">
                   <li>
                     <a is="action-link" class="inspectable-view"
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index 23024d0..801c460a 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -574,10 +574,10 @@
         whenPrintDone.then(boundHideDialog, boundHideDialog);
       } else if (!destination.isLocal) {
         // Cloud print resolves when print data is returned to submit to cloud
-        // print, or if setings are invalid.
+        // print, or if print ticket cannot be read, no PDF data is found, or
+        // PDF is oversized.
         whenPrintDone.then(
-            this.onPrintToCloud_.bind(this),
-            this.onSettingsInvalid_.bind(this));
+            this.onPrintToCloud_.bind(this), this.onPrintFailed_.bind(this));
       } else if (destination.isPrivet || destination.isExtension) {
         // Privet and extension resolve when printing is complete or if there
         // is an error printing.
@@ -1126,13 +1126,13 @@
     },
 
     /**
-     * Called when printing to a privet or extension printer fails.
+     * Called when printing to a privet, cloud, or extension printer fails.
      * @param {*} httpError The HTTP error code, or -1 or a string describing
      *     the error, if not an HTTP error.
      * @private
      */
     onPrintFailed_: function(httpError) {
-      console.error('Privet printing failed with error code ' + httpError);
+      console.error('Printing failed with error code ' + httpError);
       this.printHeader_.setErrorMessage(
           loadTimeData.getString('couldNotPrint'));
     },
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index 115feef..a9f5389 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -172,6 +172,8 @@
   // a simple placeholder for now.
   source->AddLocalizedString("itemInspectViewsExtra",
                              IDS_MD_EXTENSIONS_ITEM_INSPECT_VIEWS_EXTRA);
+  source->AddLocalizedString("noActiveViews",
+                             IDS_MD_EXTENSIONS_ITEM_NO_ACTIVE_VIEWS);
   source->AddLocalizedString("itemAllowIncognito",
                              IDS_MD_EXTENSIONS_ITEM_ALLOW_INCOGNITO);
   source->AddLocalizedString("itemDescriptionLabel",
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index d5cd5f67..d9d9cbdb 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -88,6 +88,11 @@
 
 namespace {
 
+// Max size for PDFs sent to Cloud Print. Server side limit is currently 80MB
+// but PDF will double in size when sent to JS. See crbug.com/793506 and
+// crbug.com/372240.
+constexpr size_t kMaxCloudPrintPdfDataSizeInBytes = 80 * 1024 * 1024 / 2;
+
 // This enum is used to back an UMA histogram, and should therefore be treated
 // as append only.
 enum UserActionBuckets {
@@ -1083,6 +1088,11 @@
   std::string base64_data;
   base::Base64Encode(raw_data, &base64_data);
 
+  if (base64_data.size() >= kMaxCloudPrintPdfDataSizeInBytes) {
+    RejectJavascriptCallback(base::Value(callback_id),
+                             base::Value("OVERSIZED_PDF"));
+    return;
+  }
   ResolveJavascriptCallback(base::Value(callback_id), base::Value(base64_data));
 }
 
diff --git a/components/offline_pages/core/offline_page_feature.cc b/components/offline_pages/core/offline_page_feature.cc
index 5c59bef..076cbcc1 100644
--- a/components/offline_pages/core/offline_page_feature.cc
+++ b/components/offline_pages/core/offline_page_feature.cc
@@ -57,6 +57,9 @@
 const base::Feature kOfflinePagesPrefetchingUIFeature{
     "OfflinePagesPrefetchingUI", base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kOfflinePagesLimitlessPrefetchingFeature{
+    "OfflinePagesLimitlessPrefetching", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const char kPrefetchingOfflinePagesExperimentsOption[] = "exp";
 
 bool IsOfflineBookmarksEnabled() {
@@ -93,6 +96,11 @@
          base::FeatureList::IsEnabled(kOfflinePagesPrefetchingUIFeature);
 }
 
+bool IsLimitlessPrefetchingEnabled() {
+  return IsPrefetchingOfflinePagesEnabled() &&
+         base::FeatureList::IsEnabled(kOfflinePagesLimitlessPrefetchingFeature);
+}
+
 bool IsOfflinePagesLoadSignalCollectingEnabled() {
   return base::FeatureList::IsEnabled(kOfflinePagesLoadSignalCollectingFeature);
 }
diff --git a/components/offline_pages/core/offline_page_feature.h b/components/offline_pages/core/offline_page_feature.h
index f29cd06..db5d287 100644
--- a/components/offline_pages/core/offline_page_feature.h
+++ b/components/offline_pages/core/offline_page_feature.h
@@ -22,6 +22,7 @@
 extern const base::Feature kOfflinePagesRenovationsFeature;
 extern const base::Feature kOfflinePagesResourceBasedSnapshotFeature;
 extern const base::Feature kOfflinePagesPrefetchingUIFeature;
+extern const base::Feature kOfflinePagesLimitlessPrefetchingFeature;
 
 // The parameter name used to find the experiment tag for prefetching offline
 // pages.
@@ -52,6 +53,10 @@
 // Returns true if we should show UI for prefetched pages.
 bool IsOfflinePagesPrefetchingUIEnabled();
 
+// Returns true if prefetching offline pages should ignore its normal resource
+// usage limits.
+bool IsLimitlessPrefetchingEnabled();
+
 // Returns true if we enable load timing signals to be collected.
 bool IsOfflinePagesLoadSignalCollectingEnabled();
 
diff --git a/components/offline_pages/core/offline_page_feature_unittest.cc b/components/offline_pages/core/offline_page_feature_unittest.cc
index 355befc..c51d5ba 100644
--- a/components/offline_pages/core/offline_page_feature_unittest.cc
+++ b/components/offline_pages/core/offline_page_feature_unittest.cc
@@ -14,7 +14,7 @@
   // Enabled by default.
   EXPECT_TRUE(offline_pages::IsOfflineBookmarksEnabled());
 
-  // Check if feature is correctly disabled by command-line flag.
+  // Check if helper method works correctly when the features is disabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndDisableFeature(kOfflineBookmarksFeature);
   EXPECT_FALSE(offline_pages::IsOfflineBookmarksEnabled());
@@ -24,27 +24,27 @@
   // Enabled by default.
   EXPECT_TRUE(offline_pages::IsOffliningRecentPagesEnabled());
 
-  // Check if feature is correctly disabled by command-line flag.
+  // Check if helper method works correctly when the features is disabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndDisableFeature(kOffliningRecentPagesFeature);
   EXPECT_FALSE(offline_pages::IsOffliningRecentPagesEnabled());
 }
 
 TEST(OfflinePageFeatureTest, OfflinePagesSharing) {
-  // This feature is disabled by default.
+  // Disabled by default.
   EXPECT_FALSE(offline_pages::IsOfflinePagesSharingEnabled());
 
-  // Check if feature is correctly disabled by command-line flag.
+  // Check if helper method works correctly when the features is disabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(kOfflinePagesSharingFeature);
   EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled());
 }
 
 TEST(OfflinePageFeatureTest, OfflinePagesSvelteConcurrentLoading) {
-  // This feature is disabled by default.
+  // Disabled by default.
   EXPECT_FALSE(offline_pages::IsOfflinePagesSvelteConcurrentLoadingEnabled());
 
-  // Check if feature is correctly enabled by command-line flag.
+  // Check if helper method works correctly when the features is enabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
       kOfflinePagesSvelteConcurrentLoadingFeature);
@@ -52,14 +52,64 @@
 }
 
 TEST(OfflinePageFeatureTest, OfflinePagesLoadSignalCollecting) {
-  // This feature is disabled by default.
+  // Disabled by default.
   EXPECT_FALSE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled());
 
-  // Check if feature is correctly enabled by command-line flag.
+  // Check if helper method works correctly when the features is enabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
       kOfflinePagesLoadSignalCollectingFeature);
   EXPECT_TRUE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled());
 }
 
+TEST(OfflinePageFeatureTest, OfflinePagesPrefetching) {
+  // Disabled by default.
+  EXPECT_FALSE(offline_pages::IsPrefetchingOfflinePagesEnabled());
+
+  // Check if helper method works correctly when the features is enabled.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kPrefetchingOfflinePagesFeature);
+  EXPECT_TRUE(offline_pages::IsPrefetchingOfflinePagesEnabled());
+}
+
+TEST(OfflinePageFeatureTest, OfflinePagesPrefetchingUI) {
+  // Disabled by default.
+  EXPECT_FALSE(offline_pages::IsOfflinePagesPrefetchingUIEnabled());
+
+  // This feature is enabled by default but depends on the core prefetching
+  // feature.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kPrefetchingOfflinePagesFeature);
+  EXPECT_TRUE(offline_pages::IsOfflinePagesPrefetchingUIEnabled());
+}
+
+TEST(OfflinePageFeatureTest, OfflinePagesLimitlessPrefetching) {
+  // Disabled by default.
+  EXPECT_FALSE(offline_pages::IsLimitlessPrefetchingEnabled());
+
+  // This feature depends on the core prefetching feature.
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeature(kPrefetchingOfflinePagesFeature);
+    EXPECT_FALSE(offline_pages::IsLimitlessPrefetchingEnabled());
+  }
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeature(
+        kOfflinePagesLimitlessPrefetchingFeature);
+    EXPECT_FALSE(offline_pages::IsLimitlessPrefetchingEnabled());
+  }
+
+  // Check if helper method works correctly when all required features are
+  // enabled.
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitWithFeatures(
+        {kPrefetchingOfflinePagesFeature,
+         kOfflinePagesLimitlessPrefetchingFeature},
+        {});
+    EXPECT_TRUE(offline_pages::IsLimitlessPrefetchingEnabled());
+  }
+}
+
 }  // namespace offline_pages
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc
index a2ae45df..101bc198 100644
--- a/content/browser/loader/cross_site_document_blocking_browsertest.cc
+++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -8,6 +8,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/resource_type.h"
 #include "content/public/test/browser_test_utils.h"
@@ -295,6 +297,36 @@
   // process is still alive.
 }
 
+class CrossSiteDocumentBlockingKillSwitchTest
+    : public CrossSiteDocumentBlockingTest {
+ public:
+  CrossSiteDocumentBlockingKillSwitchTest() {
+    // Simulate flipping the kill switch.
+    scoped_feature_list_.InitAndDisableFeature(
+        features::kCrossSiteDocumentBlockingIfIsolating);
+  }
+
+  ~CrossSiteDocumentBlockingKillSwitchTest() override {}
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingKillSwitchTest);
+};
+
+// After the kill switch is flipped, there should be no document blocking.
+IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingKillSwitchTest,
+                       NoBlockingWithKillSwitch) {
+  // Load a page that issues illegal cross-site document requests to bar.com.
+  GURL foo_url("http://foo.com/cross_site_document_request.html");
+  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+
+  bool was_blocked;
+  ASSERT_TRUE(ExecuteScriptAndExtractBool(
+      shell(), "sendRequest(\"valid.html\");", &was_blocked));
+  EXPECT_FALSE(was_blocked);
+}
+
 // Without any Site Isolation (in the base test class), there should be no
 // document blocking.
 IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingBaseTest,
diff --git a/content/browser/loader/cross_site_document_resource_handler.cc b/content/browser/loader/cross_site_document_resource_handler.cc
index aa2400e..27202563 100644
--- a/content/browser/loader/cross_site_document_resource_handler.cc
+++ b/content/browser/loader/cross_site_document_resource_handler.cc
@@ -326,10 +326,18 @@
   // TODO(creis): This check can go away once the logic here is made fully
   // backward compatible and we can enforce it always, regardless of Site
   // Isolation policy.
-  if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
-      !ChildProcessSecurityPolicyImpl::GetInstance()->IsIsolatedOrigin(
-          url::Origin::Create(url))) {
-    return false;
+  switch (SiteIsolationPolicy::IsCrossSiteDocumentBlockingEnabled()) {
+    case SiteIsolationPolicy::XSDB_ENABLED_UNCONDITIONALLY:
+      break;
+    case SiteIsolationPolicy::XSDB_ENABLED_IF_ISOLATED:
+      if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
+          !ChildProcessSecurityPolicyImpl::GetInstance()->IsIsolatedOrigin(
+              url::Origin::Create(url))) {
+        return false;
+      }
+      break;
+    case SiteIsolationPolicy::XSDB_DISABLED:
+      return false;
   }
 
   // Look up MIME type.  If it doesn't claim to be a blockable type (i.e., HTML,
diff --git a/content/common/site_isolation_policy.cc b/content/common/site_isolation_policy.cc
index 773000b..54a0acc 100644
--- a/content/common/site_isolation_policy.cc
+++ b/content/common/site_isolation_policy.cc
@@ -25,6 +25,21 @@
 }
 
 // static
+SiteIsolationPolicy::CrossSiteDocumentBlockingEnabledState
+SiteIsolationPolicy::IsCrossSiteDocumentBlockingEnabled() {
+  if (base::FeatureList::IsEnabled(
+          ::features::kCrossSiteDocumentBlockingAlways))
+    return XSDB_ENABLED_UNCONDITIONALLY;
+
+  if (base::FeatureList::IsEnabled(
+          ::features::kCrossSiteDocumentBlockingIfIsolating)) {
+    return XSDB_ENABLED_IF_ISOLATED;
+  }
+
+  return XSDB_DISABLED;
+}
+
+// static
 bool SiteIsolationPolicy::IsTopDocumentIsolationEnabled() {
   // --site-per-process trumps --top-document-isolation.
   if (UseDedicatedProcessesForAllSites())
diff --git a/content/common/site_isolation_policy.h b/content/common/site_isolation_policy.h
index 44afe7d..f8746ca8 100644
--- a/content/common/site_isolation_policy.h
+++ b/content/common/site_isolation_policy.h
@@ -27,6 +27,15 @@
   // Returns true if every site should be placed in a dedicated process.
   static bool UseDedicatedProcessesForAllSites();
 
+  // Returns whether cross-site document responses can be blocked.
+  enum CrossSiteDocumentBlockingEnabledState {
+    XSDB_ENABLED_UNCONDITIONALLY,
+    XSDB_ENABLED_IF_ISOLATED,
+    XSDB_DISABLED,
+  };
+  static CrossSiteDocumentBlockingEnabledState
+  IsCrossSiteDocumentBlockingEnabled();
+
   // Returns true if third-party subframes of a page should be kept in a
   // different process from the main frame.
   static bool IsTopDocumentIsolationEnabled();
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 01c869c..168d4706 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -92,6 +92,16 @@
 const base::Feature kCompositorTouchAction{"CompositorTouchAction",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables blocking cross-site document responses (not paying attention to
+// whether a site isolation mode is also enabled).
+const base::Feature kCrossSiteDocumentBlockingAlways{
+    "CrossSiteDocumentBlockingAlways", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enables blocking cross-site document responses if one of site isolation modes
+// is (e.g. site-per-process or isolate-origins) is enabled.
+const base::Feature kCrossSiteDocumentBlockingIfIsolating{
+    "CrossSiteDocumentBlockingIfIsolating", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Enables exposing back/forward mouse buttons to the renderer and the web.
 const base::Feature kExtendedMouseButtons{"ExtendedMouseButtons",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 8da6cae..7a8cc78 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -32,6 +32,8 @@
 CONTENT_EXPORT extern const base::Feature kCompositeOpaqueScrollers;
 CONTENT_EXPORT extern const base::Feature kCompositorImageAnimation;
 CONTENT_EXPORT extern const base::Feature kCompositorTouchAction;
+CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingAlways;
+CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingIfIsolating;
 CONTENT_EXPORT extern const base::Feature kExtendedMouseButtons;
 CONTENT_EXPORT extern const base::Feature kExpensiveBackgroundTimerThrottling;
 CONTENT_EXPORT extern const base::Feature kFeaturePolicy;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
index 526ff58..b12b9702 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -290,8 +290,11 @@
   [self setUpToolbarStackView];
   [self setUpLocationBarContainerView];
   [self.view addSubview:self.leadingStackView];
-  [self.view addSubview:self.locationBarContainer];
   [self.view addSubview:self.trailingStackView];
+  // Since the |_locationBarContainer| will expand and cover the stackViews, its
+  // important to add it after them so the |_locationBarContainer| has a higher
+  // Z order.
+  [self.view addSubview:self.locationBarContainer];
   [self.view addSubview:self.shadowView];
   [self.view addSubview:self.progressBar];
   [self setConstraints];
diff --git a/media/media_options.gni b/media/media_options.gni
index 9b2be437..f1d54b01 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -81,9 +81,7 @@
   enable_webrtc = !is_cast_audio_only && !is_fuchsia
 
   # Enable HLS with SAMPLE-AES decryption.
-  # Enabled by default on the cast desktop implementation to allow unit tests of
-  # MP2TS parsing support.
-  enable_hls_sample_aes = proprietary_codecs && is_cast_desktop_build
+  enable_hls_sample_aes = proprietary_codecs && is_chromecast
 
   # If true, use cast CMA backend instead of default chromium media pipeline.
   is_cast_using_cma_backend = is_cast_audio_only || !is_android
diff --git a/media/mojo/services/watch_time_recorder.cc b/media/mojo/services/watch_time_recorder.cc
index d99faab..17aee39 100644
--- a/media/mojo/services/watch_time_recorder.cc
+++ b/media/mojo/services/watch_time_recorder.cc
@@ -237,12 +237,15 @@
     }
   }
 
+  // Ensure values are cleared in case the reporter is reused.
+  pipeline_status_ = PIPELINE_OK;
   underflow_count_ = 0;
   watch_time_info_.clear();
 }
 
 void WatchTimeRecorder::OnError(PipelineStatus status) {
   pipeline_status_ = status;
+  needs_ukm_report_ = true;
 }
 
 void WatchTimeRecorder::UpdateUnderflowCount(int32_t count) {
@@ -262,6 +265,23 @@
   if (!ukm_recorder)
     return;
 
+  // Ensure we have an "All" watch time entry or we haven't issued an up to date
+  // UKM report; otherwise skip reporting.
+  if (!needs_ukm_report_ &&
+      !std::any_of(
+          aggregate_watch_time_info_.begin(), aggregate_watch_time_info_.end(),
+          [](const std::pair<WatchTimeKey, base::TimeDelta>& kv) {
+            return kv.first == WatchTimeKey::kAudioAll ||
+                   kv.first == WatchTimeKey::kAudioBackgroundAll ||
+                   kv.first == WatchTimeKey::kAudioVideoAll ||
+                   kv.first == WatchTimeKey::kAudioVideoBackgroundAll ||
+                   kv.first == WatchTimeKey::kVideoAll ||
+                   kv.first == WatchTimeKey::kVideoBackgroundAll;
+          })) {
+    return;
+  }
+
+  needs_ukm_report_ = false;
   const int32_t source_id = ukm_recorder->GetNewSourceID();
 
   // TODO(crbug.com/787209): Stop getting origin from the renderer.
diff --git a/media/mojo/services/watch_time_recorder.h b/media/mojo/services/watch_time_recorder.h
index a652c80..7d247a5d 100644
--- a/media/mojo/services/watch_time_recorder.h
+++ b/media/mojo/services/watch_time_recorder.h
@@ -71,6 +71,10 @@
   int underflow_count_ = 0;
   PipelineStatus pipeline_status_ = PIPELINE_OK;
 
+  // False if all data has been reported to UKM. Set to false by important
+  // property updates; e.g., OnError().
+  bool needs_ukm_report_ = true;
+
   DISALLOW_COPY_AND_ASSIGN(WatchTimeRecorder);
 };
 
diff --git a/media/mojo/services/watch_time_recorder_unittest.cc b/media/mojo/services/watch_time_recorder_unittest.cc
index 13c2e8b..af7498aa 100644
--- a/media/mojo/services/watch_time_recorder_unittest.cc
+++ b/media/mojo/services/watch_time_recorder_unittest.cc
@@ -335,7 +335,7 @@
     wtr_->RecordWatchTime(key, kWatchTime);
 
   // Trigger finalization of everything.
-  wtr_->FinalizeWatchTime({});
+  wtr_.reset();
   base::RunLoop().RunUntilIdle();
 
   // No standard watch time should be recorded because it falls below the
@@ -357,13 +357,69 @@
 #define EXPECT_NO_UKM(name) \
   EXPECT_FALSE(test_recorder_->EntryHasMetric(entry, name))
 
+TEST_F(WatchTimeRecorderTest, TestFinalizeNoDuplication) {
+  mojom::PlaybackPropertiesPtr properties = mojom::PlaybackProperties::New(
+      kCodecAAC, kCodecH264, true, true, false, false, false, false,
+      gfx::Size(800, 600), url::Origin::Create(GURL(kTestOrigin)), true);
+  provider_->AcquireWatchTimeRecorder(properties.Clone(),
+                                      mojo::MakeRequest(&wtr_));
+
+  // Verify that UKM is reported along with the watch time.
+  constexpr base::TimeDelta kWatchTime = base::TimeDelta::FromSeconds(4);
+  wtr_->RecordWatchTime(WatchTimeKey::kAudioVideoAll, kWatchTime);
+  wtr_->FinalizeWatchTime({});
+  base::RunLoop().RunUntilIdle();
+
+  const auto& entries = test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  for (const auto* entry : entries) {
+    test_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestOrigin));
+
+    EXPECT_UKM(UkmEntry::kIsBackgroundName, properties->is_background);
+    EXPECT_UKM(UkmEntry::kAudioCodecName, properties->audio_codec);
+    EXPECT_UKM(UkmEntry::kVideoCodecName, properties->video_codec);
+    EXPECT_UKM(UkmEntry::kHasAudioName, properties->has_audio);
+    EXPECT_UKM(UkmEntry::kHasVideoName, properties->has_video);
+    EXPECT_UKM(UkmEntry::kIsEMEName, properties->is_eme);
+    EXPECT_UKM(UkmEntry::kIsMSEName, properties->is_mse);
+    EXPECT_UKM(UkmEntry::kLastPipelineStatusName, PIPELINE_OK);
+    EXPECT_UKM(UkmEntry::kRebuffersCountName, 0);
+    EXPECT_UKM(UkmEntry::kVideoNaturalWidthName,
+               properties->natural_size.width());
+    EXPECT_UKM(UkmEntry::kVideoNaturalHeightName,
+               properties->natural_size.height());
+    EXPECT_UKM(UkmEntry::kWatchTimeName, kWatchTime.InMilliseconds());
+
+    EXPECT_NO_UKM(UkmEntry::kMeanTimeBetweenRebuffersName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_ACName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_BatteryName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_NativeControlsOnName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_NativeControlsOffName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayFullscreenName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayInlineName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayPictureInPictureName);
+  }
+
+  // Ensure no second UKM report is generated now that we've already reported
+  // along with the WatchTime above.
+  ResetMetricRecorders();
+  wtr_.reset();
+  base::RunLoop().RunUntilIdle();
+  const auto& empty_entries =
+      test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
+  EXPECT_EQ(0u, empty_entries.size());
+}
+
 TEST_F(WatchTimeRecorderTest, FinalizeWithoutWatchTime) {
   mojom::PlaybackPropertiesPtr properties = mojom::PlaybackProperties::New(
       kCodecAAC, kCodecH264, true, true, false, false, false, false,
       gfx::Size(800, 600), url::Origin::Create(GURL(kTestOrigin)), true);
   provider_->AcquireWatchTimeRecorder(properties.Clone(),
                                       mojo::MakeRequest(&wtr_));
-  wtr_.reset();
+
+  // Finalize everything. Since no metrics have been recorded yet, this will
+  // generate a UKM entry.
+  wtr_->FinalizeWatchTime({});
   base::RunLoop().RunUntilIdle();
 
   // No watch time should have been recorded even though a finalize event will
@@ -403,6 +459,58 @@
     EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayInlineName);
     EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayPictureInPictureName);
   }
+
+  // Finalize a second time should do nothing.
+  ResetMetricRecorders();
+  wtr_->FinalizeWatchTime({});
+  base::RunLoop().RunUntilIdle();
+  const auto& empty_entries =
+      test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
+  EXPECT_EQ(0u, empty_entries.size());
+
+  // OnError() plus another finalize should generate a new UKM report.
+  ResetMetricRecorders();
+  wtr_->OnError(PIPELINE_ERROR_DECODE);
+  wtr_->FinalizeWatchTime({});
+  base::RunLoop().RunUntilIdle();
+  const auto& entries2 = test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
+  EXPECT_EQ(1u, entries2.size());
+  for (const auto* entry : entries2) {
+    test_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestOrigin));
+
+    EXPECT_UKM(UkmEntry::kIsBackgroundName, properties->is_background);
+    EXPECT_UKM(UkmEntry::kAudioCodecName, properties->audio_codec);
+    EXPECT_UKM(UkmEntry::kVideoCodecName, properties->video_codec);
+    EXPECT_UKM(UkmEntry::kHasAudioName, properties->has_audio);
+    EXPECT_UKM(UkmEntry::kHasVideoName, properties->has_video);
+    EXPECT_UKM(UkmEntry::kIsEMEName, properties->is_eme);
+    EXPECT_UKM(UkmEntry::kIsMSEName, properties->is_mse);
+    EXPECT_UKM(UkmEntry::kLastPipelineStatusName, PIPELINE_ERROR_DECODE);
+    EXPECT_UKM(UkmEntry::kRebuffersCountName, 0);
+    EXPECT_UKM(UkmEntry::kVideoNaturalWidthName,
+               properties->natural_size.width());
+    EXPECT_UKM(UkmEntry::kVideoNaturalHeightName,
+               properties->natural_size.height());
+
+    EXPECT_NO_UKM(UkmEntry::kMeanTimeBetweenRebuffersName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTimeName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_ACName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_BatteryName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_NativeControlsOnName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_NativeControlsOffName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayFullscreenName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayInlineName);
+    EXPECT_NO_UKM(UkmEntry::kWatchTime_DisplayPictureInPictureName);
+  }
+
+  // Ensure no second UKM report is generated now that we've already reported
+  // along with the WatchTime above.
+  ResetMetricRecorders();
+  wtr_.reset();
+  base::RunLoop().RunUntilIdle();
+  const auto& empty_entries2 =
+      test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
+  EXPECT_EQ(0u, empty_entries2.size());
 }
 
 TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideo) {
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
index 0245cbe54..0ac30498 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -1,5 +1,4 @@
 crbug.com/417782 compositing/iframes/become-composited-nested-iframes.html [ Failure ]
-crbug.com/417782 compositing/layer-creation/iframe-background-attachment-fixed.html [ Failure ]
 crbug.com/417782 compositing/squashing/squash-above-fixed-1.html [ Failure ]
 crbug.com/417782 compositing/squashing/squash-above-fixed-3.html [ Failure ]
 crbug.com/417782 compositing/visibility/visibility-image-layers-dynamic.html [ Failure ]
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
index c90e69bec..ae6e19c 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -63,6 +63,7 @@
 #include "core/exported/WebRemoteFrameImpl.h"
 #include "core/exported/WebViewImpl.h"
 #include "core/frame/BrowserControls.h"
+#include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameTestHelpers.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/LocalFrameView.h"
@@ -9198,6 +9199,28 @@
   EXPECT_FALSE(new_frame->last_child_);
 }
 
+TEST_P(WebFrameSwapTest, EventsOnDisconnectedSubDocumentSkipped) {
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
+  WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
+  EXPECT_TRUE(target_frame);
+  SwapAndVerifySubframeConsistency("local->remote", target_frame, remote_frame);
+
+  WebLocalFrameImpl* local_child =
+      FrameTestHelpers::CreateLocalChild(*remote_frame, "local-inside-remote");
+
+  Document* main_document =
+      WebView()->MainFrameImpl()->GetFrame()->GetDocument();
+  Document* child_document = local_child->GetFrame()->GetDocument();
+  EventHandlerRegistry& event_registry =
+      main_document->GetPage()->GetEventHandlerRegistry();
+
+  // Add the non-connected, but local, child document as having an event.
+  event_registry.DidAddEventHandler(
+      *child_document, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+  // Passes if this does not crash or DCHECK.
+  main_document->View()->UpdateAllLifecyclePhases();
+}
+
 TEST_P(WebFrameSwapTest, SwapParentShouldDetachChildren) {
   WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
index fe29bc1..ca51bc20 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -5630,7 +5630,7 @@
   return reasons;
 }
 
-String LocalFrameView::MainThreadScrollingReasonsAsText() const {
+String LocalFrameView::MainThreadScrollingReasonsAsText() {
   if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
     DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
 
@@ -5647,12 +5647,14 @@
   }
 
   DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kCompositingClean);
-  if (LayerForScrolling() && LayerForScrolling()->PlatformLayer()) {
-    String result(
-        MainThreadScrollingReason::mainThreadScrollingReasonsAsText(
-            LayerForScrolling()->PlatformLayer()->MainThreadScrollingReasons())
-            .c_str());
-    return result;
+  if (GraphicsLayer* layer_for_scrolling =
+          LayoutViewportScrollableArea()->LayerForScrolling()) {
+    if (WebLayer* platform_layer = layer_for_scrolling->PlatformLayer()) {
+      String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText(
+                        platform_layer->MainThreadScrollingReasons())
+                        .c_str());
+      return result;
+    }
   }
 
   String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText(
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h
index a75b2472..e102c0f5 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -870,7 +870,7 @@
   // scrolled on main thread as its ancestor B.
   void UpdateSubFrameScrollOnMainReason(const Frame&,
                                         MainThreadScrollingReasons);
-  String MainThreadScrollingReasonsAsText() const;
+  String MainThreadScrollingReasonsAsText();
   // Main thread scrolling reasons including reasons from ancestors.
   MainThreadScrollingReasons GetMainThreadScrollingReasons() const;
   // Main thread scrolling reasons for this object only. For all reasons,
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 706b248..e44abc1 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -1099,8 +1099,16 @@
       continue;
 
     if (node->IsDocumentNode() && node != document) {
-      AccumulateDocumentTouchEventTargetRects(
-          rects, event_class, ToDocument(node), supported_fast_actions);
+      Document* child_document = ToDocument(node);
+      // Ignore events which apply to
+      // a different LocalFrameRoot, as they have their own lifecycle.
+      // Any events that apply to them will get processed accordingly.
+      if (child_document->GetFrame() &&
+          &child_document->GetFrame()->LocalFrameRoot() ==
+              &document->GetFrame()->LocalFrameRoot()) {
+        AccumulateDocumentTouchEventTargetRects(
+            rects, event_class, child_document, supported_fast_actions);
+      }
     } else if (LayoutObject* layout_object = node->GetLayoutObject()) {
       // If the set also contains one of our ancestor nodes then processing
       // this node would be redundant.
@@ -1143,7 +1151,7 @@
   TRACE_EVENT0("input", "ScrollingCoordinator::computeTouchEventTargetRects");
 
   Document* document = page_->DeprecatedLocalMainFrame()->GetDocument();
-  if (!document || !document->View())
+  if (!document || !document->View() || !document->GetFrame())
     return;
 
   AccumulateDocumentTouchEventTargetRects(
diff --git a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
index 21d6be7c..2f1e824 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
@@ -197,12 +197,10 @@
   static void ConstructDeletedValue(blink::DecoderCacheKey& slot, bool) {
     slot = blink::DecoderCacheEntry::MakeCacheKey(
         nullptr, SkISize::Make(-1, -1),
-        static_cast<blink::ImageDecoder::AlphaOption>(-1));
+        static_cast<blink::ImageDecoder::AlphaOption>(0));
   }
   static bool IsDeletedValue(const blink::DecoderCacheKey& value) {
-    return !value.gen_ && value.size_ == SkISize::Make(-1, -1) &&
-           value.alpha_option_ ==
-               static_cast<blink::ImageDecoder::AlphaOption>(-1);
+    return value.size_ == SkISize::Make(-1, -1);
   }
 };
 
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index b17e65b1..ce795c0e 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -24874,6 +24874,7 @@
   <int value="-1190174011" label="enable-hdr"/>
   <int value="-1184904651" label="enable-npapi"/>
   <int value="-1184480269" label="LsdPermissionPrompt:enabled"/>
+  <int value="-1183009666" label="OfflinePagesLimitlessPrefetching:disabled"/>
   <int value="-1177802205" label="enable-hosted-app-quit-notification"/>
   <int value="-1176748003"
       label="FramebustingNeedsSameOriginOrUserGesture:disabled"/>
@@ -25823,6 +25824,7 @@
   <int value="1407625309"
       label="disable-minimize-on-second-launcher-item-click"/>
   <int value="1408331660" label="enhanced-bookmarks-experiment"/>
+  <int value="1409437197" label="OfflinePagesLimitlessPrefetching:enabled"/>
   <int value="1410697724" label="mediadrm-enable-non-compositing"/>
   <int value="1416592483" label="ash-enable-mirrored-screen"/>
   <int value="1418054870" label="SpecialLocale:enabled"/>
diff --git a/ui/gfx/OWNERS b/ui/gfx/OWNERS
index ec4cedb..cf44bc1 100644
--- a/ui/gfx/OWNERS
+++ b/ui/gfx/OWNERS
@@ -18,7 +18,8 @@
 per-file transform*=vollick@chromium.org
 per-file interpolated_transform*=vollick@chromium.org
 
-# GPU memory buffer interface.
+# GPU memory buffer and GpuFence interfaces.
+per-file gpu_fence*=reveman@chromium.org
 per-file gpu_memory_buffer*=reveman@chromium.org
 per-file buffer_format*=reveman@chromium.org
 per-file *buffer_types.*=reveman@chromium.org