diff --git a/DEPS b/DEPS
index 6a3a448..da5d5eb 100644
--- a/DEPS
+++ b/DEPS
@@ -303,15 +303,15 @@
   # 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': 'f0987bd082ac9bc3d5ed6257c9ecfad18d9b0467',
+  'skia_revision': 'd0f09ad481f7d8afd73259b1f46ad0dc8d8a1e6b',
   # 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': '3970923e265f3f8a2420cefd55ee1bdabe44e6a4',
+  'v8_revision': 'fccd7efb786d611b5d6d2903e6900c562aaa7dd4',
   # 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': 'e3600abb810666033b35b8e98043869fb1c10603',
+  'angle_revision': '82c95b3012573f46a99f7f32d2a93c3671c0e8b9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -394,7 +394,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': '5fad45b99a7ca290b0e36ca81f0074589ee2ef9b',
+  'devtools_frontend_revision': 'd7571848c16a0ff89d4964c838dc44e0ce915049',
   # 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.
@@ -418,7 +418,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '667f56eab3feb5ed6aa40dd9b2319b3fb784f1f6',
+  'dawn_revision': '4d6794a7625867209adaaf3839b6969578acea2f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -818,7 +818,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '93f409484e269c3df9017ba14dc28a6ccd84bf2d',
+    'e1d0bc7ff99b302fe11d5a7563481e3fb42c14e2',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -847,7 +847,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'c4c73b5452c7efca23db99cde8746d36e0ed107a',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '00fac7e67918c03a47eb79b5e65d7a5aa6cbf70f',
       'condition': 'checkout_ios',
   },
 
@@ -980,7 +980,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'uEy3v9aofzAf6VZm5g6ymQ4FcurxX2k_KCqjHOw47NoC',
+          'version': 'aX7aKt_tQj6cTy5WGXiiPYsjab9D2DZwSQc5xPUW0KUC',
       },
     ],
     'condition': 'checkout_android',
@@ -1190,13 +1190,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '390005586bde14be9b55fde71ca4ae2107021ac9',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '007dd45a94b8fe400fb69113f7999fed185cb5c1',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '7a46eb1458616c7271b7aa5787a8ae89c800bc34',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'c41591023f94b09a395d82d1c8bf571ead6895b2',
     'condition': 'checkout_src_internal',
   },
 
@@ -1294,11 +1294,6 @@
       'condition': 'checkout_win',
   },
 
-  'src/third_party/gvr-android-sdk/src': {
-      'url': Var('chromium_git') + '/external/github.com/googlevr/gvr-android-sdk.git' + '@' + '233e7fe922a543e0bc55382d64cacd047307d0e7',
-      'condition': 'checkout_android',
-  },
-
   'src/third_party/cardboard/src' : {
       'url': Var('chromium_git') + '/external/github.com/googlevr/cardboard/' + '@' + '5c9f3066dc14962d1dec9a32ec9d3668641c408d',
       'condition': 'checkout_android',
@@ -1661,7 +1656,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '905fb0a0357086378dc057f82a2e6926bf1341be',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '7a68d15808c7e9714206112aaecbcd90ca1f1c18',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1846,7 +1841,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f20c5f7b8f53904edaa98651d764e1b8305d7c14',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'b2e9babeb7aac43e3e27bb7f211b8bf994128720',
+    Var('webrtc_git') + '/src.git' + '@' + 'f698a39eecd1c58108d56d0b541430deebc74a25',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -3949,7 +3944,7 @@
 
   'src/components/optimization_guide/internal': {
       'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' +
-        '2e8649b36bd3e4e0ae00efabffc0e5a512316a2c',
+        'd6d170dc380770ce81ad2f7ea55435c98fe4083a',
       'condition': 'checkout_src_internal',
   },
 
@@ -4009,7 +4004,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '6ab4b39499215991e1d58a879aec026c6f54a925',
+        'ac06513c41078df3c7e5c292bbfdd2423dc61741',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
@@ -4958,30 +4953,6 @@
                 '--gs_url_base=chromeos-prebuilt/afdo-job/llvm',
     ],
   },
-  {
-    'name': 'gvr_static_shim_android',
-    'pattern': '\\.sha1',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                '--no_resume',
-                '--no_auth',
-                '--bucket', 'chromium-gvr-static-shim',
-                '-d', 'src/third_party/gvr-android-sdk',
-    ],
-  },
-  {
-    'name': 'vr_controller_test_api',
-    'pattern': '\\.sha1',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                '--no_resume',
-                '--no_auth',
-                '--bucket', 'chromium-gvr-static-shim/controller_test_api',
-                '-s', 'src/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1',
-    ],
-  },
   # Download and unpack MediaPipe Integration tests.
   {
     'name': 'mediapipe_integration_testdata',
@@ -4990,15 +4961,6 @@
                 'src/content/test/gpu/gpu_tests/mediapipe_update.py',
     ],
   },
-  # Download VR test APKs only if the environment variable is set
-  {
-    'name': 'vr_test_apks',
-    'pattern': '.',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/gvr-android-sdk/test-apks/update.py',
-    ],
-  },
   # DOWNLOAD AR test APKs only if the environment variable is set
   {
     'name': 'ar_test_apks',
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
index 8eab837..d038806 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
@@ -17,13 +17,13 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/core/common/utils.h"
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/content/settings_page_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
 #include "components/security_interstitials/core/safe_browsing_quiet_error_ui.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
@@ -106,7 +106,7 @@
   // enhanced protection is supported on aw.
   BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options =
       BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
-          IsMainPageLoadBlocked(unsafe_resources),
+          IsMainPageLoadPending(unsafe_resources),
           safe_browsing::IsExtendedReportingOptInAllowed(*pref_service),
           browser_context->IsOffTheRecord(),
           safe_browsing::IsExtendedReportingEnabled(*pref_service),
@@ -126,7 +126,8 @@
   // committed interstitials, it can be cleaned up when removing non-committed
   // interstitials.
   content::NavigationEntry* entry =
-      GetNavigationEntryForResource(unsafe_resource);
+      safe_browsing::unsafe_resource_util::GetNavigationEntryForResource(
+          unsafe_resource);
   GURL url =
       (main_frame_url.is_empty() && entry) ? entry->GetURL() : main_frame_url;
 
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
index 8ce8a14..9d22870 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
@@ -18,10 +18,10 @@
 #include "base/path_service.h"
 #include "components/safe_browsing/content/browser/base_ui_manager.h"
 #include "components/safe_browsing/content/browser/safe_browsing_network_context.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safebrowsing_constants.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_controller.h"
@@ -71,7 +71,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource);
   // Check the size of the view
   UIManagerClient* client = UIManagerClient::FromWebContents(web_contents);
   if (!client || !client->CanShowInterstitial()) {
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
index eef29ee..73ffcd915 100644
--- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
+++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
@@ -21,12 +21,12 @@
 #include "base/android/jni_android.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/web_ui_constants.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "components/security_interstitials/core/urls.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -193,7 +193,7 @@
     const security_interstitials::UnsafeResource& resource,
     const AwWebResourceRequest& request) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource);
 
   security_interstitials::SecurityInterstitialTabHelper*
       security_interstitial_tab_helper = security_interstitials::
@@ -229,7 +229,7 @@
     SafeBrowsingAction action,
     bool reporting) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource);
   // |web_contents| can be null after RenderFrameHost is destroyed.
   if (!web_contents)
     return;
@@ -240,7 +240,9 @@
     browser_context->SetExtendedReportingAllowed(false);
   }
 
-  content::NavigationEntry* entry = GetNavigationEntryForResource(resource);
+  content::NavigationEntry* entry =
+      safe_browsing::unsafe_resource_util::GetNavigationEntryForResource(
+          resource);
 
   // TODO(ntfschr): fully handle reporting once we add support (crbug/688629)
   bool proceed;
@@ -303,7 +305,7 @@
     scoped_refptr<AwSafeBrowsingUIManager> ui_manager,
     const security_interstitials::UnsafeResource& resource) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource);
   if (web_contents) {
     ui_manager->DisplayBlockingPage(resource);
     return;
diff --git a/ash/clipboard/views/clipboard_history_text_item_view.cc b/ash/clipboard/views/clipboard_history_text_item_view.cc
index 5b28e74..eb9aa71c 100644
--- a/ash/clipboard/views/clipboard_history_text_item_view.cc
+++ b/ash/clipboard/views/clipboard_history_text_item_view.cc
@@ -67,8 +67,8 @@
         views::Builder<views::BoxLayoutView>()
             .SetOrientation(views::BoxLayout::Orientation::kVertical)
             .SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kStart)
-            .SetProperty(views::kFlexBehaviorKey,
-                         views::FlexSpecification().WithWeight(1))
+            .SetProperty(views::kBoxLayoutFlexKey,
+                         views::BoxLayoutFlexSpecification())
             .AddChild(views::Builder<views::Label>(
                           std::make_unique<ClipboardHistoryLabel>(
                               container->text_, display_text_elide_behavior,
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index ed194c26..3ccf45c 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1347,11 +1347,15 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Enables new on-device recognition for legacy handwriting input.
+// This flag should be OVERRIDDEN for devices which do not have on-device
+// handwriting (b/316981973). Please check before using this flag.
 BASE_FEATURE(kHandwritingLegacyRecognition,
              "HandwritingLegacyRecognition",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables downloading the handwriting libraries via DLC.
+// This flag should be OVERRIDDEN for devices which do not have on-device
+// handwriting (b/316981973). Please check before using this flag.
 BASE_FEATURE(kHandwritingLibraryDlc,
              "HandwritingLibraryDlc",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/ash/metrics/feature_discovery_duration_reporter_impl.cc b/ash/metrics/feature_discovery_duration_reporter_impl.cc
index 00cc0597..bfeb0d3 100644
--- a/ash/metrics/feature_discovery_duration_reporter_impl.cc
+++ b/ash/metrics/feature_discovery_duration_reporter_impl.cc
@@ -5,7 +5,6 @@
 #include "ash/metrics/feature_discovery_duration_reporter_impl.h"
 
 #include "ash/public/cpp/feature_discovery_metric_util.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/shell.h"
 #include "base/containers/contains.h"
 #include "base/json/values_util.h"
@@ -13,6 +12,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "ui/display/screen.h"
 
 namespace ash {
 
@@ -134,7 +134,7 @@
     // Record the current tablet mode if `feature`'s discovery duration data
     // should be separated by tablet mode.
     observed_feature_data.Set(kActivatedInTablet,
-                              TabletMode::Get()->IsInTabletMode());
+                              display::Screen::GetScreen()->InTabletMode());
   }
 
   ScopedDictPrefUpdate update(active_pref_service_, kObservedFeatures);
diff --git a/ash/public/cpp/tablet_mode.cc b/ash/public/cpp/tablet_mode.cc
index 9401f7d..418f5295 100644
--- a/ash/public/cpp/tablet_mode.cc
+++ b/ash/public/cpp/tablet_mode.cc
@@ -61,8 +61,4 @@
   }
 }
 
-bool TabletMode::IsInTabletMode() {
-  return display::Screen::GetScreen()->InTabletMode();
-}
-
 }  // namespace ash
diff --git a/ash/public/cpp/tablet_mode.h b/ash/public/cpp/tablet_mode.h
index 18220b4f..3cb0199 100644
--- a/ash/public/cpp/tablet_mode.h
+++ b/ash/public/cpp/tablet_mode.h
@@ -51,13 +51,6 @@
   virtual void AddObserver(TabletModeObserver* observer) = 0;
   virtual void RemoveObserver(TabletModeObserver* observer) = 0;
 
-  // Deprecated, do NOT use this. Please use
-  // display::Screen::GetScreen()->InTabletMode() instead.
-  // TODO(crbug.com/1502114): Remove this.
-  //
-  // Returns true if TabletMode singleton exists and is in the tablet mode.
-  static bool IsInTabletMode();
-
   // Whether the events from the internal mouse/keyboard are blocked.
   virtual bool AreInternalInputDeviceEventsBlocked() const = 0;
 
diff --git a/ash/system/focus_mode/focus_mode_chip_carousel.cc b/ash/system/focus_mode/focus_mode_chip_carousel.cc
index 20491c9..68d433b 100644
--- a/ash/system/focus_mode/focus_mode_chip_carousel.cc
+++ b/ash/system/focus_mode/focus_mode_chip_carousel.cc
@@ -81,9 +81,7 @@
 FocusModeChipCarousel::FocusModeChipCarousel(
     ChipPressedCallback on_chip_pressed)
     : on_chip_pressed_(std::move(on_chip_pressed)) {
-  SetProperty(views::kFlexBehaviorKey,
-              views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                                       views::MaximumFlexSizeRule::kUnbounded));
+  SetProperty(views::kBoxLayoutFlexKey, views::BoxLayoutFlexSpecification());
   SetBorder(views::CreateEmptyBorder(kCarouselInsets));
   SetOrientation(views::BoxLayout::Orientation::kHorizontal);
   SetNotifyEnterExitOnChild(true);
diff --git a/ash/system/focus_mode/focus_mode_task_view.cc b/ash/system/focus_mode/focus_mode_task_view.cc
index 7ef7cf26..7bf7456 100644
--- a/ash/system/focus_mode/focus_mode_task_view.cc
+++ b/ash/system/focus_mode/focus_mode_task_view.cc
@@ -176,11 +176,8 @@
       views::BoxLayout::CrossAxisAlignment::kCenter);
   textfield_container_->SetOrientation(
       views::BoxLayout::Orientation::kHorizontal);
-  textfield_container_->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kUnbounded));
-
+  textfield_container_->SetProperty(views::kBoxLayoutFlexKey,
+                                    views::BoxLayoutFlexSpecification());
   radio_button_ = textfield_container_->AddChildView(
       std::make_unique<views::ImageButton>(base::BindRepeating(
           &FocusModeTaskView::OnCompleteTask, base::Unretained(this))));
diff --git a/ash/system/focus_mode/focus_mode_tray.cc b/ash/system/focus_mode/focus_mode_tray.cc
index 67cf84c9..56366bec 100644
--- a/ash/system/focus_mode/focus_mode_tray.cc
+++ b/ash/system/focus_mode/focus_mode_tray.cc
@@ -248,10 +248,8 @@
             base::UTF8ToUTF16(controller->selected_task_title()),
             base::BindRepeating(&FocusModeTray::OnCompleteTask,
                                 weak_ptr_factory_.GetWeakPtr())));
-    task_item_view_->SetProperty(
-        views::kFlexBehaviorKey,
-        views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                                 views::MaximumFlexSizeRule::kPreferred));
+    task_item_view_->SetProperty(views::kBoxLayoutFlexKey,
+                                 views::BoxLayoutFlexSpecification());
   }
 
   bubble_ = std::make_unique<TrayBubbleWrapper>(this);
diff --git a/ash/system/holding_space/downloads_section.cc b/ash/system/holding_space/downloads_section.cc
index 46f0cae1..4eae63c 100644
--- a/ash/system/holding_space/downloads_section.cc
+++ b/ash/system/holding_space/downloads_section.cc
@@ -74,8 +74,8 @@
             holding_space_ui::CreateSectionHeaderLabel(
                 IDS_ASH_HOLDING_SPACE_DOWNLOADS_TITLE)
                 .SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
-                .SetProperty(views::kFlexBehaviorKey,
-                             views::FlexSpecification().WithWeight(1)),
+                .SetProperty(views::kBoxLayoutFlexKey,
+                             views::BoxLayoutFlexSpecification()),
             views::Builder<views::ImageView>()
                 .CopyAddressTo(&chevron_)
                 .SetFlipCanvasOnPaintForRTLUI(true)
diff --git a/ash/system/holding_space/suggestions_section.cc b/ash/system/holding_space/suggestions_section.cc
index e7e4354..6fac10a9 100644
--- a/ash/system/holding_space/suggestions_section.cc
+++ b/ash/system/holding_space/suggestions_section.cc
@@ -64,8 +64,8 @@
             holding_space_ui::CreateSuggestionsSectionHeaderLabel(
                 IDS_ASH_HOLDING_SPACE_SUGGESTIONS_TITLE)
                 .SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
-                .SetProperty(views::kFlexBehaviorKey,
-                             views::FlexSpecification().WithWeight(1)),
+                .SetProperty(views::kBoxLayoutFlexKey,
+                             views::BoxLayoutFlexSpecification()),
             views::Builder<views::ImageView>().CopyAddressTo(&chevron_).SetID(
                 kHoldingSpaceSuggestionsChevronIconId))
         .BuildChildren();
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index a1ccf08..496e12d 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -1711,10 +1711,8 @@
       views::Builder<views::BoxLayoutView>()
           .CopyAddressTo(&snooze_button_spacer_)
           .SetMainAxisAlignment(MainAxisAlignment::kEnd)
-          .SetProperty(
-              views::kFlexBehaviorKey,
-              views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                                       views::MaximumFlexSizeRule::kUnbounded))
+          .SetProperty(views::kBoxLayoutFlexKey,
+                       views::BoxLayoutFlexSpecification())
           .Build());
 
   auto snooze_button = std::make_unique<IconButton>(
diff --git a/ash/system/phonehub/app_stream_launcher_view.cc b/ash/system/phonehub/app_stream_launcher_view.cc
index 4d9c312f..d46e7c6 100644
--- a/ash/system/phonehub/app_stream_launcher_view.cc
+++ b/ash/system/phonehub/app_stream_launcher_view.cc
@@ -255,12 +255,8 @@
       gfx::DirectionalityMode::DIRECTIONALITY_AS_URL));
   title->SetMultiLine(true);
   title->SetAllowCharacterBreak(true);
-  title->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded,
-                               /*adjust_height_for_width =*/true)
-          .WithWeight(1));
+  title->SetProperty(views::kBoxLayoutFlexKey,
+                     views::BoxLayoutFlexSpecification());
   title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title->SetText(
       l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_APP_STREAM_LAUNCHER_TITLE));
diff --git a/ash/system/unified/feature_tile_pixeltest.cc b/ash/system/unified/feature_tile_pixeltest.cc
index d1df21e9..9b49e1d 100644
--- a/ash/system/unified/feature_tile_pixeltest.cc
+++ b/ash/system/unified/feature_tile_pixeltest.cc
@@ -263,10 +263,8 @@
                     views::Button::PressedCallback(), /*is_togglable=*/true,
                     FeatureTile::TileType::kCompact))
                 ->GetWeakPtr();
-    tile_->SetProperty(
-        views::kFlexBehaviorKey,
-        views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                                 views::MaximumFlexSizeRule::kUnbounded));
+    tile_->SetProperty(views::kBoxLayoutFlexKey,
+                       views::BoxLayoutFlexSpecification());
     tile_->SetTooltipText(u"Tooltip");
     tile_->SetVectorIcon(vector_icons::kDogfoodIcon);
     tile_->SetLabel(u"One-line label");
diff --git a/ash/system/unified/quick_settings_view_unittest.cc b/ash/system/unified/quick_settings_view_unittest.cc
index f2721bc..8ff122b 100644
--- a/ash/system/unified/quick_settings_view_unittest.cc
+++ b/ash/system/unified/quick_settings_view_unittest.cc
@@ -16,6 +16,7 @@
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/display/screen.h"
 
 namespace ash {
 
@@ -78,7 +79,7 @@
 
   // Test that the cast tile is in its primary form when in clamshell mode,
   // when the auto-rotate tile is not visible.
-  EXPECT_FALSE(tablet_mode_controller->IsInTabletMode());
+  EXPECT_FALSE(display::Screen::GetScreen()->InTabletMode());
   tray->ShowBubble();
 
   FeatureTile* cast_tile = GetTileById(VIEW_ID_CAST_MAIN_VIEW);
@@ -93,7 +94,7 @@
 
   // Test that cast and auto-rotate tiles are compact in tablet mode.
   tablet_mode_controller->SetEnabledForTest(true);
-  EXPECT_TRUE(tablet_mode_controller->IsInTabletMode());
+  EXPECT_TRUE(display::Screen::GetScreen()->InTabletMode());
 
   tray->ShowBubble();
 
diff --git a/ash/user_education/welcome_tour/welcome_tour_controller.cc b/ash/user_education/welcome_tour/welcome_tour_controller.cc
index d0386fe..85daa2d 100644
--- a/ash/user_education/welcome_tour/welcome_tour_controller.cc
+++ b/ash/user_education/welcome_tour/welcome_tour_controller.cc
@@ -13,7 +13,6 @@
 #include "ash/public/cpp/system/scoped_toast_pause.h"
 #include "ash/public/cpp/system/system_nudge_pause_manager.h"
 #include "ash/public/cpp/system/toast_manager.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -394,7 +393,7 @@
   // prevented provided that (a) the user is new, and (b) the device is not in
   // tablet mode. This is in keeping with existing first run behavior.
   base::ScopedClosureRunner maybe_launch_explore_app_async(
-      TabletMode::IsInTabletMode()
+      display::Screen::GetScreen()->InTabletMode()
           ? base::DoNothing()
           : base::BindOnce(&LaunchExploreAppAsync,
                            UserEducationPrivateApiKey()));
@@ -407,7 +406,7 @@
   }
 
   // Welcome Tour is not supported in tablet mode.
-  if (TabletMode::IsInTabletMode()) {
+  if (display::Screen::GetScreen()->InTabletMode()) {
     welcome_tour_metrics::RecordTourPrevented(
         welcome_tour_metrics::PreventedReason::kTabletModeEnabled);
     return;
@@ -536,7 +535,7 @@
   // Attempt to launch the Explore app regardless of tour completion so long as
   // the device is not in tablet mode. This is in keeping with existing first
   // run behavior.
-  if (!TabletMode::IsInTabletMode()) {
+  if (!display::Screen::GetScreen()->InTabletMode()) {
     LaunchExploreAppAsync(UserEducationPrivateApiKey());
     SetCurrentStep(welcome_tour_metrics::Step::kExploreAppWindow);
   }
diff --git a/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc b/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc
index b66c8ee..34b57d9c 100644
--- a/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc
+++ b/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc
@@ -448,7 +448,7 @@
                 LaunchSystemWebAppAsync(
                     Eq(primary_account_id), Eq(ash::SystemWebAppType::HELP),
                     Eq(display::Screen::GetScreen()->GetPrimaryDisplay().id())))
-        .Times(TabletMode::IsInTabletMode() ? 0u : 1u);
+        .Times(display::Screen::GetScreen()->InTabletMode() ? 0u : 1u);
     std::move(ended_callback).Run();
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(user_education_delegate);
diff --git a/ash/webui/settings/public/constants/routes.mojom b/ash/webui/settings/public/constants/routes.mojom
index 0b7ea5d..5023ddd 100644
--- a/ash/webui/settings/public/constants/routes.mojom
+++ b/ash/webui/settings/public/constants/routes.mojom
@@ -155,6 +155,7 @@
   kInput = 1205,
   kEditDictionary = 1206,
   kJapaneseManageUserDictionary = 1207,
+  kAppLanguages = 1208,
 
   // Files section.
   kNetworkFileShares = 1300,
@@ -309,6 +310,7 @@
 const string kEditDictionarySubpagePath = "osLanguages/editDictionary";
 const string kJapaneseManageUserDictionarySubpagePath =
     "osLanguages/japaneseManageUserDictionary";
+const string kAppLanguagesSubpagePath = "osLanguages/languages/appLanguages";
 
 // Files section.
 const string kFilesSectionPath = "files";
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc
index 547f7ee..11291322 100644
--- a/ash/wm/client_controlled_state.cc
+++ b/ash/wm/client_controlled_state.cc
@@ -369,12 +369,18 @@
               << ", state=" << state_type_
               << ", next_state=" << next_state_type;
 
+      const gfx::Rect snapped_bounds = GetSnappedWindowBoundsInParent(
+          window, next_state_type, next_snap_ratio);
+
+      // The snap ratio of `snapped_bounds` may be different from the requested
+      // snap ratio (e.g., if the window has a minimum size requirement or the
+      // opposite side of splitview is partial-snapped).
+      window_state->ForceUpdateSnapRatio(snapped_bounds);
+
       // Then ask delegate to set the desired bounds for the snap state.
-      delegate_->HandleBoundsRequest(
-          window_state, next_state_type,
-          GetSnappedWindowBoundsInParent(window, next_state_type,
-                                         next_snap_ratio),
-          window_state->GetDisplay().id());
+      delegate_->HandleBoundsRequest(window_state, next_state_type,
+                                     snapped_bounds,
+                                     window_state->GetDisplay().id());
     }
   } else if (next_state_type == WindowStateType::kFloated) {
     if (chromeos::wm::CanFloatWindow(window)) {
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc
index 6b4a6ff..f3b36ab 100644
--- a/ash/wm/client_controlled_state_unittest.cc
+++ b/ash/wm/client_controlled_state_unittest.cc
@@ -140,6 +140,33 @@
   }
 };
 
+void VerifySnappedBounds(aura::Window* window, float expected_snap_ratio) {
+  const WindowState* window_state = WindowState::Get(window);
+  // `window` must be in any snapped state to use this method.
+  ASSERT_TRUE(window_state->IsSnapped());
+
+  const bool in_tablet = display::Screen::GetScreen()->InTabletMode();
+  const auto* screen = display::Screen::GetScreen();
+  const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
+  const bool is_primary =
+      window_state->GetStateType() == WindowStateType::kPrimarySnapped;
+
+  const gfx::Size expected_size(
+      work_area.width() * expected_snap_ratio -
+          (in_tablet ? kSplitviewDividerShortSideLength / 2 : 0),
+      work_area.height());
+  const gfx::Point expected_origin(
+      is_primary ? work_area.x() : work_area.right() - expected_size.width(),
+      work_area.y());
+
+  const gfx::Rect bounds = window->GetTargetBounds();
+  constexpr int eps = 1;  // Allow 1px rounding errors for partial snap.
+  EXPECT_NEAR(expected_size.width(), bounds.width(), eps);
+  EXPECT_EQ(expected_size.height(), bounds.height());
+  EXPECT_NEAR(expected_origin.x(), bounds.x(), eps);
+  EXPECT_EQ(expected_origin.y(), bounds.y());
+}
+
 }  // namespace
 
 class ClientControlledStateTest : public AshTestBase {
@@ -209,6 +236,24 @@
     widget()->SetBounds(delegate()->requested_bounds());
     state()->set_bounds_locally(false);
   }
+  void ClickOnOverviewItem(aura::Window* window) {
+    auto* const overview_controller = OverviewController::Get();
+    ASSERT_TRUE(overview_controller->InOverviewSession());
+    auto* const overview_item = GetOverviewItemForWindow(window);
+
+    auto* const event_generator = GetEventGenerator();
+    event_generator->set_current_screen_location(
+        gfx::ToRoundedPoint(overview_item->target_bounds().CenterPoint()));
+    event_generator->ClickLeftButton();
+  }
+  void SimulateUnminimizeViaShelfIcon(views::Widget* widget) {
+    // When clicking an app icon on the hotseat to unminimize the window,
+    // `ChromeShelfController` shows and activates the widget.
+    // We here simulate the behavior because //ash should not use any component
+    // from //chrome/browser/ui.
+    widget->Show();
+    widget->Activate();
+  }
 
  private:
   raw_ptr<ClientControlledState, DanglingUntriaged | ExperimentalAsh> state_ =
@@ -614,6 +659,135 @@
   EXPECT_EQ(resized_bounds, delegate()->requested_bounds());
 }
 
+// Tests that auto snapping from maximized/minimized via overview/shelf works
+// for ClientControlledState.
+TEST_F(ClientControlledStateTest, AutoSnap) {
+  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
+  ASSERT_TRUE(display::Screen::GetScreen()->InTabletMode());
+
+  // Snap enabled.
+  widget_delegate()->EnableSnap();
+  ASSERT_TRUE(window_state()->CanResize());
+  ASSERT_TRUE(window_state()->CanSnap());
+
+  // Create a normal (non-client-controlled) window in addition to `window()`
+  // (client-controlled window) to fill the one side of the split view.
+  auto non_client_controlled_window = CreateAppWindow();
+
+  // Snap `non_client_controlled_window` to left.
+  const WindowSnapWMEvent snap_primary(WM_EVENT_SNAP_PRIMARY);
+  WindowState::Get(non_client_controlled_window.get())
+      ->OnWMEvent(&snap_primary);
+
+  // Click `window()`'s overview item to snap to right.
+  ClickOnOverviewItem(window());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kDefaultSnapRatio);
+
+  // Minimize `window()`.
+  const WMEvent minimize(WM_EVENT_MINIMIZE);
+  window_state()->OnWMEvent(&minimize);
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  EXPECT_TRUE(window_state()->IsMinimized());
+  EXPECT_FALSE(window()->IsVisible());
+
+  // Click `window()`'s overview item to snap to right.
+  ClickOnOverviewItem(window());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kDefaultSnapRatio);
+
+  // Minimize `window()`.
+  window_state()->OnWMEvent(&minimize);
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  EXPECT_TRUE(window_state()->IsMinimized());
+  EXPECT_FALSE(window()->IsVisible());
+
+  // Unminimize `window()` by clicking the app icon on the shelf.
+  SimulateUnminimizeViaShelfIcon(widget());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kDefaultSnapRatio);
+}
+
+// Tests that auto partial-snapping from maximized/minimized via overview/shelf
+// works for ClientControlledState.
+TEST_F(ClientControlledStateTest, AutoPartialSnap) {
+  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
+  ASSERT_TRUE(display::Screen::GetScreen()->InTabletMode());
+
+  // Snap enabled.
+  widget_delegate()->EnableSnap();
+  ASSERT_TRUE(window_state()->CanResize());
+  ASSERT_TRUE(window_state()->CanSnap());
+
+  // Create a normal (non-client-controlled) window in addition to `window()`
+  // (client-controlled window) to fill the one side of the split view.
+  auto non_client_controlled_window = CreateAppWindow();
+
+  // Snap `non_client_controlled_window` to 1/3 left.
+  const WindowSnapWMEvent snap_primary(WM_EVENT_SNAP_PRIMARY,
+                                       chromeos::kOneThirdSnapRatio);
+  WindowState::Get(non_client_controlled_window.get())
+      ->OnWMEvent(&snap_primary);
+
+  // Click `window()`'s overview item to snap to 2/3 right.
+  ClickOnOverviewItem(window());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kOneThirdSnapRatio);
+
+  // Minimize `window()`.
+  const WMEvent minimize(WM_EVENT_MINIMIZE);
+  window_state()->OnWMEvent(&minimize);
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  EXPECT_TRUE(window_state()->IsMinimized());
+  EXPECT_FALSE(window()->IsVisible());
+
+  // Click `window()`'s overview item to snap to 2/3 right.
+  ClickOnOverviewItem(window());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kOneThirdSnapRatio);
+
+  // Minimize `window()`.
+  window_state()->OnWMEvent(&minimize);
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  EXPECT_TRUE(window_state()->IsMinimized());
+  EXPECT_FALSE(window()->IsVisible());
+
+  // Unminimize `window()` by clicking the app icon on the shelf.
+  SimulateUnminimizeViaShelfIcon(widget());
+
+  state()->EnterNextState(window_state(), delegate()->new_state());
+  ApplyPendingRequestedBounds();
+  EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType());
+  VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio);
+  VerifySnappedBounds(non_client_controlled_window.get(),
+                      chromeos::kOneThirdSnapRatio);
+}
+
 // Pin events should not be applied immediately. The request should be sent
 // to delegate.
 TEST_F(ClientControlledStateTest, Pinned) {
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index 8f82d3d..8a695590 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -8145,85 +8145,74 @@
 TEST_F(SplitViewOverviewSessionTest, SnappedWindowBoundsWithMinimumSizeTest) {
   const gfx::Rect bounds(400, 400);
   std::unique_ptr<aura::Window> window1(CreateTestWindow(bounds));
-  const int work_area_length =
+  const gfx::Rect work_area =
       screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
-          Shell::GetPrimaryRootWindow())
-          .width();
+          window1.get());
   std::unique_ptr<aura::Window> window2(CreateWindowWithMinimumSize(
-      bounds, gfx::Size(work_area_length / 3 + 20, 0)));
+      bounds, gfx::Size(work_area.width() / 3 + 20, 0)));
 
+  // Snap `window1` in split view, then resize it to 1/3 the work area, which is
+  // less than the minimum size of `window2`.
   ToggleOverview();
   split_view_controller()->SnapWindow(window1.get(), SnapPosition::kPrimary);
   split_view_divider()->StartResizeWithDivider(
       GetSplitViewDividerBounds(/*is_dragging=*/false).CenterPoint());
   split_view_divider()->EndResizeWithDivider(
-      gfx::Point(work_area_length / 3, 10));
-  SkipDividerSnapAnimation();
-  // Use |EXPECT_NEAR| for reasons related to rounding and divider thickness.
-  EXPECT_NEAR(
-      work_area_length / 3,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width(),
-      8);
-  EXPECT_NEAR(work_area_length / 2,
-              split_view_controller()
-                  ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary,
-                                                   window2.get(),
-                                                   chromeos::kDefaultSnapRatio)
-                  .width(),
-              8);
-  EXPECT_NEAR(
-      work_area_length * 2 / 3,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width(),
-      8);
-  EXPECT_NEAR(work_area_length * 2 / 3,
-              split_view_controller()
-                  ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                                   window2.get(),
-                                                   chromeos::kDefaultSnapRatio)
-                  .width(),
-              8);
+      gfx::Point(work_area.width() / 3, 10));
+  ASSERT_TRUE(GetOverviewController()->InOverviewSession());
+  ASSERT_TRUE(split_view_controller()->InSplitViewMode());
+  // Use `EXPECT_NEAR` for reasons related to rounding and divider thickness.
+  constexpr int kDividerWidth = kSplitviewDividerShortSideLength;
+  ASSERT_NEAR(work_area.width() / 3, window1->GetBoundsInScreen().width(),
+              kDividerWidth);
+
+  // Long press to start a drag on `item2` to the left, on top of `window1`, to
+  // show the left highlight preview.
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  const gfx::Point drag_starting_point(
+      gfx::ToRoundedPoint(item2->GetTransformedBounds().CenterPoint()));
+  ui::test::EventGenerator* generator = GetEventGenerator();
+  LongGestureTap(drag_starting_point, generator, /*release_touch=*/false);
+  DragItemToPoint(item2, gfx::Point(0, 0), generator,
+                  /*by_touch_gestures=*/true, /*drop=*/false);
+  ASSERT_TRUE(GetOverviewController()->InOverviewSession());
+  ASSERT_TRUE(split_view_controller()->InSplitViewMode());
+
+  // Test that the highlight bounds are 1/2 the work area, since that's the
+  // closest fixed divider ratio for `window2`.
+  gfx::Rect left_highlight_bounds(work_area);
+  left_highlight_bounds.set_width(work_area.width() / 2 - kDividerWidth / 2);
+  left_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp);
+  auto* overview_grid =
+      GetOverviewSession()->GetGridWithRootWindow(window1->GetRootWindow());
+  EXPECT_EQ(left_highlight_bounds, overview_grid->split_view_drag_indicators()
+                                       ->GetLeftHighlightViewBounds());
+
+  // Drop `item2` back at its starting point.
+  generator->MoveTouch(drag_starting_point);
+  generator->ReleaseTouch();
+
+  // Now resize `window1` where `window2` can't fit in the secondary position.
   split_view_divider()->StartResizeWithDivider(
       GetSplitViewDividerBounds(/*is_dragging=*/false).CenterPoint());
   split_view_divider()->EndResizeWithDivider(
-      gfx::Point(work_area_length * 2 / 3, 10));
-  EXPECT_NEAR(
-      work_area_length * 2 / 3,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width(),
-      8);
-  EXPECT_NEAR(work_area_length * 2 / 3,
-              split_view_controller()
-                  ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary,
-                                                   window2.get(),
-                                                   chromeos::kDefaultSnapRatio)
-                  .width(),
-              8);
-  EXPECT_NEAR(
-      work_area_length / 3,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width(),
-      8);
-  EXPECT_NEAR(work_area_length / 2,
-              split_view_controller()
-                  ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                                   window2.get(),
-                                                   chromeos::kDefaultSnapRatio)
-                  .width(),
-              8);
+      gfx::Point(work_area.width() * 2 / 3, 10));
+  ASSERT_NEAR(work_area.width() * 2 / 3, window1->GetBoundsInScreen().width(),
+              kDividerWidth);
+
+  // Drag `window2` to show the right highlight preview.
+  DragItemToPoint(item2, work_area.top_right(), generator,
+                  /*by_touch_gestures=*/false, /*drop=*/false);
+
+  // Test that the highlight bounds are 1/2 the work area.
+  gfx::Rect right_highlight_bounds(work_area);
+  right_highlight_bounds.set_x(work_area.width() / 2 + kDividerWidth / 2);
+  right_highlight_bounds.set_width(work_area.width() / 2 - kDividerWidth / 2);
+  right_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp);
+  EXPECT_EQ(right_highlight_bounds,
+            overview_grid->split_view_drag_indicators()
+                ->GetRightHighlightViewBoundsForTesting());
+  generator->ReleaseTouch();
 }
 
 // Verify that if the split view divider is dragged all the way to the edge, the
@@ -9332,68 +9321,65 @@
   std::unique_ptr<aura::Window> window2(
       CreateWindowWithMinimumSize(bounds, gfx::Size(window2_minimum_size, 0)));
 
+  // Snap `window1` in split view, then resize it to `window1_size`, which is
+  // less than `window2_minimum_size`.
   ToggleOverview();
   split_view_controller()->SnapWindow(window1.get(), SnapPosition::kPrimary);
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
-                                     window1.get());
-  int divider_position = window1->GetBoundsInScreen().width();
-  generator.MoveMouseTo(divider_position, 10);
-  divider_position = 300;
-  generator.DragMouseTo(divider_position, 10);
-  EXPECT_EQ(divider_position, split_view_controller()
-                                  ->GetSnappedWindowBoundsInScreen(
-                                      SnapPosition::kPrimary,
-                                      /*window_for_minimum_size=*/nullptr,
-                                      chromeos::kDefaultSnapRatio)
-                                  .width());
-  EXPECT_EQ(window2_minimum_size, split_view_controller()
-                                      ->GetSnappedWindowBoundsInScreen(
-                                          SnapPosition::kPrimary, window2.get(),
-                                          chromeos::kDefaultSnapRatio)
-                                      .width());
-  const int work_area_length =
+  ui::test::EventGenerator* generator = GetEventGenerator();
+  ASSERT_TRUE(RootWindowController::ForWindow(window1.get())
+                  ->split_view_overview_session());
+  generator->MoveMouseTo(window1->GetBoundsInScreen().width(), 10);
+  int window1_size = 300;
+  generator->DragMouseTo(window1_size, 10);
+  ASSERT_EQ(window1_size, window1->GetBoundsInScreen().width());
+
+  // Drag `window2` to the left, on top of `window1`, to show the left highlight
+  // preview.
+  const gfx::Rect work_area =
       screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
-          window1.get())
-          .width();
-  EXPECT_EQ(
-      work_area_length - divider_position,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width());
-  EXPECT_EQ(work_area_length - divider_position,
-            split_view_controller()
-                ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                                 window2.get(),
-                                                 chromeos::kDefaultSnapRatio)
-                .width());
-  divider_position = 500;
-  generator.DragMouseTo(divider_position, 10);
-  EXPECT_EQ(divider_position, split_view_controller()
-                                  ->GetSnappedWindowBoundsInScreen(
-                                      SnapPosition::kPrimary,
-                                      /*window_for_minimum_size=*/nullptr,
-                                      chromeos::kDefaultSnapRatio)
-                                  .width());
-  EXPECT_EQ(divider_position, split_view_controller()
-                                  ->GetSnappedWindowBoundsInScreen(
-                                      SnapPosition::kPrimary, window2.get(),
-                                      chromeos::kDefaultSnapRatio)
-                                  .width());
-  EXPECT_EQ(
-      work_area_length - divider_position,
-      split_view_controller()
-          ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                           /*window_for_minimum_size=*/nullptr,
-                                           chromeos::kDefaultSnapRatio)
-          .width());
-  EXPECT_EQ(window2_minimum_size,
-            split_view_controller()
-                ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary,
-                                                 window2.get(),
-                                                 chromeos::kDefaultSnapRatio)
-                .width());
+          window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  const gfx::Point drag_starting_point(
+      gfx::ToRoundedPoint(item2->GetTransformedBounds().CenterPoint()));
+  DragItemToPoint(item2, gfx::Point(0, 0), generator,
+                  /*by_touch_gestures=*/false, /*drop=*/false);
+
+  // Test that the highlight bounds are adjusted for `window2_minimum_size`.
+  gfx::Rect left_highlight_bounds(work_area.x(), work_area.y(),
+                                  window2_minimum_size, work_area.height());
+  left_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp);
+  auto* overview_grid =
+      GetOverviewSession()->GetGridWithRootWindow(window1->GetRootWindow());
+  EXPECT_EQ(left_highlight_bounds, overview_grid->split_view_drag_indicators()
+                                       ->GetLeftHighlightViewBounds());
+
+  // Drop the `window2` item back at its starting point.
+  generator->MoveMouseTo(drag_starting_point);
+  generator->ReleaseLeftButton();
+  ASSERT_TRUE(RootWindowController::ForWindow(window1.get())
+                  ->split_view_overview_session());
+
+  // Now resize `window1` where `window2` can't fit in the secondary position.
+  window1_size = 500;
+  generator->MoveMouseTo(window1->GetBoundsInScreen().width(), 10);
+  generator->DragMouseTo(window1_size, 0);
+  ASSERT_TRUE(RootWindowController::ForWindow(window1.get())
+                  ->split_view_overview_session());
+  ASSERT_EQ(window1_size, window1->GetBoundsInScreen().width());
+
+  // Drag `window2` to show the right highlight preview.
+  DragItemToPoint(item2, work_area.top_right(), generator,
+                  /*by_touch_gestures=*/false, /*drop=*/false);
+
+  // Test that the highlight bounds are adjusted for `window2_minimum_size`.
+  gfx::Rect right_highlight_bounds(work_area.right() - window2_minimum_size,
+                                   work_area.y(), window2_minimum_size,
+                                   work_area.height());
+  right_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp);
+  EXPECT_EQ(right_highlight_bounds,
+            overview_grid->split_view_drag_indicators()
+                ->GetRightHighlightViewBoundsForTesting());
+  generator->ReleaseLeftButton();
 }
 
 // Tests that on a display in portrait orientation, clamshell split view still
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc
index b26fa20..8d596b2 100644
--- a/ash/wm/window_state.cc
+++ b/ash/wm/window_state.cc
@@ -218,18 +218,17 @@
          split_view_controller->split_view_divider();
 }
 
-float GetCurrentSnapRatio(aura::Window* window) {
+float GetCurrentSnapRatio(aura::Window* window,
+                          const gfx::Rect& target_bounds) {
   gfx::Rect maximized_bounds =
       screen_util::GetMaximizedWindowBoundsInParent(window);
   const int divider_delta =
       ShouldConsiderDivider(window) ? kSplitviewDividerShortSideLength / 2 : 0;
   if (IsLayoutHorizontal(window)) {
-    return static_cast<float>(window->GetTargetBounds().width() +
-                              divider_delta) /
+    return static_cast<float>(target_bounds.width() + divider_delta) /
            static_cast<float>(maximized_bounds.width());
   }
-  return static_cast<float>(window->GetTargetBounds().height() +
-                            divider_delta) /
+  return static_cast<float>(target_bounds.height() + divider_delta) /
          static_cast<float>(maximized_bounds.height());
 }
 
@@ -275,6 +274,15 @@
     controller->SaveWindow(window_state);
 }
 
+bool ShouldSetExplicitOpaqueRegionsForOcclusion(WindowState* window_state) {
+  // If the window manager manages the window opacity, set the opaque regions
+  // explicitly if the window must be transparent (e.g. has rounded corners).
+  return chromeos::ShouldWindowStateHaveRoundedCorners(
+             window_state->GetStateType()) &&
+         window_state->window()->GetProperty(
+             ash::kWindowManagerManagesOpacityKey);
+}
+
 }  // namespace
 
 constexpr base::TimeDelta WindowState::kBoundsChangeSlideDuration;
@@ -665,7 +673,11 @@
 void WindowState::UpdateSnapRatio() {
   if (!IsSnapped())
     return;
-  snap_ratio_ = std::make_optional(GetCurrentSnapRatio(window_));
+  ForceUpdateSnapRatio(window_->GetTargetBounds());
+}
+
+void WindowState::ForceUpdateSnapRatio(const gfx::Rect& target_bounds) {
+  snap_ratio_ = std::make_optional(GetCurrentSnapRatio(window_, target_bounds));
   // If the snap ratio was adjusted, partial may have ended.
   MaybeRecordPartialDuration();
 }
@@ -926,9 +938,7 @@
 
   if (window_->GetProperty(ash::kWindowManagerManagesOpacityKey)) {
     const gfx::Size& size = window_->bounds().size();
-    // WindowManager manages the window opacity. Make it opaque unless
-    // the window has rounded corners.
-    if (chromeos::ShouldWindowStateHaveRoundedCorners(GetStateType())) {
+    if (ShouldSetExplicitOpaqueRegionsForOcclusion(this)) {
       window_->SetTransparent(true);
       window_->SetOpaqueRegionsForOcclusion({gfx::Rect(size)});
     } else {
@@ -1361,8 +1371,8 @@
                                         const gfx::Rect& new_bounds,
                                         ui::PropertyChangeReason reason) {
   CHECK_EQ(window_, window);
-  if (window_->GetTransparent() && IsNormalStateType() &&
-      window_->GetProperty(ash::kWindowManagerManagesOpacityKey)) {
+  if (window_->GetTransparent() &&
+      ShouldSetExplicitOpaqueRegionsForOcclusion(this)) {
     window_->SetOpaqueRegionsForOcclusion({gfx::Rect(new_bounds.size())});
   }
 
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h
index 9784f84..43f9baa 100644
--- a/ash/wm/window_state.h
+++ b/ash/wm/window_state.h
@@ -375,6 +375,12 @@
   // snapped window.
   void UpdateSnapRatio();
 
+  // Forcefully updates `snap_ratio` based on the given `target_bounds`. You
+  // usually should use `UpdateSnapRatio()` instead. This method does not check
+  // whether `window()` is in the snapped state, so the caller must be sure that
+  // `window()` is to-be-snapped. Use with care.
+  void ForceUpdateSnapRatio(const gfx::Rect& target_bounds);
+
   // Gets/sets whether the shelf should be hidden when this window is
   // fullscreen.
   bool GetHideShelfWhenFullscreen() const;
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
index bbf74dc..8bf43a00 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
@@ -1788,18 +1788,24 @@
   EXPECT_CHECK_DEATH(--protected_ptr);
 
 #if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
-  // An array type that should be more than a third the size of the available
-  // memory for the allocation such that incrementing a pointer to this type
-  // twice causes it to point to a memory location that is too small to fit a
-  // complete element of this type.
-  typedef int OverThirdArray[200 / sizeof(int)];
-  raw_ptr<OverThirdArray> protected_arr_ptr =
-      reinterpret_cast<OverThirdArray*>(ptr);
+  // An array of a size that doesn't cleanly fit into the allocation. This is to
+  // check that one can't access elements that don't fully fit in the
+  // allocation.
+  const size_t kArraySize = 199;
+  ASSERT_LT(kArraySize, requested_size);
+  ASSERT_NE(requested_size % kArraySize, 0U);
+  typedef char FunkyArray[kArraySize];
+  raw_ptr<FunkyArray, AllowPtrArithmetic> protected_arr_ptr =
+      reinterpret_cast<FunkyArray*>(ptr);
 
-  protected_arr_ptr++;
+  **protected_arr_ptr = 4;
+  protected_arr_ptr += requested_size / kArraySize;
+  EXPECT_CHECK_DEATH(** protected_arr_ptr = 4);
+  protected_arr_ptr--;
   **protected_arr_ptr = 4;
   protected_arr_ptr++;
-  EXPECT_DEATH_IF_SUPPORTED(** protected_arr_ptr = 4, "");
+  EXPECT_CHECK_DEATH(** protected_arr_ptr = 4);
+  protected_arr_ptr = nullptr;
 #endif  // BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
 
   protected_ptr = nullptr;
@@ -1893,6 +1899,8 @@
   allocator_.root()->Free(ptr2);
 }
 
+volatile char g_volatile_char_to_ignore;
+
 TEST_F(BackupRefPtrTest, IndexOperator) {
   size_t requested_size = GetRequestSizeThatFills512BSlot();
   char* ptr = static_cast<char*>(allocator_.root()->Alloc(requested_size));
@@ -1900,10 +1908,11 @@
     raw_ptr<char, AllowPtrArithmetic> array = ptr;
     std::ignore = array[0];
     std::ignore = array[requested_size - 1];
-    EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[-1], "");
-    EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[requested_size + 1], "");
+    EXPECT_CHECK_DEATH(std::ignore = array[-1]);
+    EXPECT_CHECK_DEATH(std::ignore = array[requested_size + 1]);
 #if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
-    EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[requested_size], "");
+    EXPECT_DEATH_IF_SUPPORTED(g_volatile_char_to_ignore = array[requested_size],
+                              "");
 #endif
   }
   allocator_.root()->Free(ptr);
@@ -2138,22 +2147,18 @@
 TEST_F(BackupRefPtrTest, SpatialAlgoCompat) {
   size_t requested_size = GetRequestSizeThatFills512BSlot();
   size_t requested_elements = requested_size / sizeof(uint32_t);
+
   uint32_t* ptr =
       reinterpret_cast<uint32_t*>(allocator_.root()->Alloc(requested_size));
   uint32_t* ptr_end = ptr + requested_elements;
 
-  CountingRawPtr<uint32_t> protected_ptr = ptr;
-  CountingRawPtr<uint32_t> protected_ptr_end =
-      protected_ptr + requested_elements;
-
-#if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
-  EXPECT_DEATH_IF_SUPPORTED(*protected_ptr_end = 1, "");
-#endif
+  CountingRawPtr<uint32_t> counting_ptr = ptr;
+  CountingRawPtr<uint32_t> counting_ptr_end = counting_ptr + requested_elements;
 
   RawPtrCountingImpl::ClearCounters();
 
   uint32_t gen_val = 1;
-  std::generate(protected_ptr, protected_ptr_end, [&gen_val]() {
+  std::generate(counting_ptr, counting_ptr_end, [&gen_val]() {
     gen_val ^= gen_val + 1;
     return gen_val;
   });
@@ -2167,9 +2172,9 @@
 
   RawPtrCountingImpl::ClearCounters();
 
-  for (CountingRawPtr<uint32_t> protected_ptr_i = protected_ptr;
-       protected_ptr_i < protected_ptr_end; protected_ptr_i++) {
-    *protected_ptr_i ^= *protected_ptr_i + 1;
+  for (CountingRawPtr<uint32_t> counting_ptr_i = counting_ptr;
+       counting_ptr_i < counting_ptr_end; counting_ptr_i++) {
+    *counting_ptr_i ^= *counting_ptr_i + 1;
   }
 
   EXPECT_THAT((CountingRawPtrExpectations{
@@ -2181,9 +2186,9 @@
 
   RawPtrCountingImpl::ClearCounters();
 
-  for (CountingRawPtr<uint32_t> protected_ptr_i = protected_ptr;
-       protected_ptr_i < ptr_end; protected_ptr_i++) {
-    *protected_ptr_i ^= *protected_ptr_i + 1;
+  for (CountingRawPtr<uint32_t> counting_ptr_i = counting_ptr;
+       counting_ptr_i < ptr_end; counting_ptr_i++) {
+    *counting_ptr_i ^= *counting_ptr_i + 1;
   }
 
   EXPECT_THAT((CountingRawPtrExpectations{
@@ -2195,7 +2200,7 @@
 
   RawPtrCountingImpl::ClearCounters();
 
-  for (uint32_t* ptr_i = ptr; ptr_i < protected_ptr_end; ptr_i++) {
+  for (uint32_t* ptr_i = ptr; ptr_i < counting_ptr_end; ptr_i++) {
     *ptr_i ^= *ptr_i + 1;
   }
 
@@ -2209,7 +2214,7 @@
   RawPtrCountingImpl::ClearCounters();
 
   size_t iter_cnt = 0;
-  for (uint32_t *ptr_i = protected_ptr, *ptr_i_end = protected_ptr_end;
+  for (uint32_t *ptr_i = counting_ptr, *ptr_i_end = counting_ptr_end;
        ptr_i < ptr_i_end; ptr_i++) {
     *ptr_i ^= *ptr_i + 1;
     iter_cnt++;
@@ -2223,8 +2228,8 @@
               }),
               CountersMatch());
 
-  protected_ptr = nullptr;
-  protected_ptr_end = nullptr;
+  counting_ptr = nullptr;
+  counting_ptr_end = nullptr;
   allocator_.root()->Free(ptr);
 }
 
@@ -2232,24 +2237,27 @@
 TEST_F(BackupRefPtrTest, Duplicate) {
   size_t requested_size = allocator_.root()->AdjustSizeForExtrasSubtract(512);
   char* ptr = static_cast<char*>(allocator_.root()->Alloc(requested_size));
-  raw_ptr<char> protected_ptr1 = ptr;
+  raw_ptr<char, AllowPtrArithmetic> protected_ptr1 = ptr;
   protected_ptr1 += requested_size;  // Pointer should now be poisoned.
 
   // Duplicating a poisoned pointer should be allowed.
-  raw_ptr<char> protected_ptr2 = protected_ptr1;
+  raw_ptr<char, AllowPtrArithmetic> protected_ptr2 = protected_ptr1;
 
   // The poison bit should be propagated to the duplicate such that the OOB
   // access is disallowed:
   EXPECT_DEATH_IF_SUPPORTED(*protected_ptr2 = ' ', "");
 
   // Assignment from a poisoned pointer should be allowed.
-  raw_ptr<char> protected_ptr3;
+  raw_ptr<char, AllowPtrArithmetic> protected_ptr3;
   protected_ptr3 = protected_ptr1;
 
   // The poison bit should be propagated via the assignment such that the OOB
   // access is disallowed:
   EXPECT_DEATH_IF_SUPPORTED(*protected_ptr3 = ' ', "");
 
+  protected_ptr1 = nullptr;
+  protected_ptr2 = nullptr;
+  protected_ptr3 = nullptr;
   allocator_.root()->Free(ptr);
 }
 #endif  // BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 637a1cd..1a7c4cb 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -208,6 +208,8 @@
     "metrics/predictor_jank_tracker.h",
     "metrics/scroll_jank_dropped_frame_tracker.cc",
     "metrics/scroll_jank_dropped_frame_tracker.h",
+    "metrics/scroll_jank_ukm_reporter.cc",
+    "metrics/scroll_jank_ukm_reporter.h",
     "metrics/shared_metrics_buffer.h",
     "metrics/total_frame_counter.cc",
     "metrics/total_frame_counter.h",
@@ -773,6 +775,7 @@
     "metrics/jank_metrics_unittest.cc",
     "metrics/predictor_jank_tracker_unittest.cc",
     "metrics/scroll_jank_dropped_frame_tracker_unittest.cc",
+    "metrics/scroll_jank_ukm_reporter_unittest.cc",
     "metrics/total_frame_counter_unittest.cc",
     "metrics/video_playback_roughness_reporter_unittest.cc",
     "mojo_embedder/async_layer_tree_frame_sink_unittest.cc",
diff --git a/cc/metrics/compositor_frame_reporter.cc b/cc/metrics/compositor_frame_reporter.cc
index 64f6f0ee..b9d3c439 100644
--- a/cc/metrics/compositor_frame_reporter.cc
+++ b/cc/metrics/compositor_frame_reporter.cc
@@ -1519,6 +1519,9 @@
     if (global_trackers_.scroll_jank_dropped_frame_tracker) {
       global_trackers_.scroll_jank_dropped_frame_tracker->OnScrollStarted();
     }
+    if (global_trackers_.scroll_jank_ukm_reporter) {
+      global_trackers_.scroll_jank_ukm_reporter->EmitScrollJankUkm();
+    }
   }
 
   TRACE_EVENT("input,input.scrolling", "PresentedFrameInformation",
diff --git a/cc/metrics/compositor_frame_reporter.h b/cc/metrics/compositor_frame_reporter.h
index ea3a12c..a1783b6 100644
--- a/cc/metrics/compositor_frame_reporter.h
+++ b/cc/metrics/compositor_frame_reporter.h
@@ -49,6 +49,7 @@
   raw_ptr<PredictorJankTracker> predictor_jank_tracker = nullptr;
   raw_ptr<ScrollJankDroppedFrameTracker> scroll_jank_dropped_frame_tracker =
       nullptr;
+  raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter = nullptr;
 };
 
 // This is used for tracing and reporting the duration of pipeline stages within
diff --git a/cc/metrics/compositor_frame_reporting_controller.cc b/cc/metrics/compositor_frame_reporting_controller.cc
index ee4db3c..3efdc1d 100644
--- a/cc/metrics/compositor_frame_reporting_controller.cc
+++ b/cc/metrics/compositor_frame_reporting_controller.cc
@@ -43,6 +43,7 @@
       predictor_jank_tracker_(std::make_unique<PredictorJankTracker>()),
       scroll_jank_dropped_frame_tracker_(
           std::make_unique<ScrollJankDroppedFrameTracker>()),
+      scroll_jank_ukm_reporter_(std::make_unique<ScrollJankUkmReporter>()),
       previous_latency_predictions_main_(base::Microseconds(-1)),
       previous_latency_predictions_impl_(base::Microseconds(-1)),
       event_latency_predictions_(
@@ -52,6 +53,12 @@
     // UKM metrics should be reported if and only if `latency_ukm_reporter` is
     // set on `global_trackers_`.
     global_trackers_.latency_ukm_reporter = latency_ukm_reporter_.get();
+
+    global_trackers_.scroll_jank_ukm_reporter = scroll_jank_ukm_reporter_.get();
+    predictor_jank_tracker_->set_scroll_jank_ukm_reporter(
+        scroll_jank_ukm_reporter_.get());
+    scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter(
+        scroll_jank_ukm_reporter_.get());
   }
   global_trackers_.predictor_jank_tracker = predictor_jank_tracker_.get();
   global_trackers_.scroll_jank_dropped_frame_tracker =
@@ -70,6 +77,9 @@
     pair.reporter->TerminateFrame(FrameTerminationStatus::kDidNotPresentFrame,
                                   Now());
   }
+
+  predictor_jank_tracker_->set_scroll_jank_ukm_reporter(nullptr);
+  scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter(nullptr);
 }
 
 void CompositorFrameReportingController::SetVisible(bool visible) {
@@ -815,6 +825,7 @@
 
 void CompositorFrameReportingController::SetUkmManager(UkmManager* manager) {
   latency_ukm_reporter_->set_ukm_manager(manager);
+  scroll_jank_ukm_reporter_->set_ukm_manager(manager);
 }
 
 CompositorFrameReporter::SmoothThread
diff --git a/cc/metrics/compositor_frame_reporting_controller.h b/cc/metrics/compositor_frame_reporting_controller.h
index b28824b..07d9657 100644
--- a/cc/metrics/compositor_frame_reporting_controller.h
+++ b/cc/metrics/compositor_frame_reporting_controller.h
@@ -206,6 +206,7 @@
   std::unique_ptr<PredictorJankTracker> predictor_jank_tracker_;
   std::unique_ptr<ScrollJankDroppedFrameTracker>
       scroll_jank_dropped_frame_tracker_;
+  std::unique_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_;
 
   std::unique_ptr<CompositorFrameReporter>
       reporters_[PipelineStage::kNumPipelineStages];
diff --git a/cc/metrics/predictor_jank_tracker.cc b/cc/metrics/predictor_jank_tracker.cc
index 9967256..fb20385 100644
--- a/cc/metrics/predictor_jank_tracker.cc
+++ b/cc/metrics/predictor_jank_tracker.cc
@@ -125,6 +125,9 @@
     bool slow_scroll,
     std::optional<EventMetrics::TraceId> trace_id) {
   janky_frames_++;
+  if (scroll_jank_ukm_reporter_) {
+    scroll_jank_ukm_reporter_->IncrementPredictorJankyFrames();
+  }
   TRACE_EVENT_INSTANT(
       "input.scrolling", "PredictorJankTracker::ReportJankyFrame",
       [&](perfetto::EventContext ctx) {
diff --git a/cc/metrics/predictor_jank_tracker.h b/cc/metrics/predictor_jank_tracker.h
index bc6c6be..018655b 100644
--- a/cc/metrics/predictor_jank_tracker.h
+++ b/cc/metrics/predictor_jank_tracker.h
@@ -9,6 +9,7 @@
 #include "base/time/time.h"
 #include "cc/cc_export.h"
 #include "cc/metrics/event_metrics.h"
+#include "cc/metrics/scroll_jank_ukm_reporter.h"
 
 namespace cc {
 
@@ -34,6 +35,11 @@
   // as it should be comparing neighbouring frames only.
   void ResetCurrentScrollReporting();
 
+  void set_scroll_jank_ukm_reporter(
+      raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter) {
+    scroll_jank_ukm_reporter_ = scroll_jank_ukm_reporter;
+  }
+
  private:
   // The metric works by storing a sliding window of the previous two
   // frames, this function moves the sliding window storing the newer
@@ -73,6 +79,8 @@
 
   float total_frames_ = 0;
   float janky_frames_ = 0;
+
+  raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_ = nullptr;
 };
 
 }  // namespace cc
diff --git a/cc/metrics/scroll_jank_dropped_frame_tracker.cc b/cc/metrics/scroll_jank_dropped_frame_tracker.cc
index 81ea98fc..c86a5f40 100644
--- a/cc/metrics/scroll_jank_dropped_frame_tracker.cc
+++ b/cc/metrics/scroll_jank_dropped_frame_tracker.cc
@@ -268,8 +268,21 @@
                                 kVsyncCountsMax, kVsyncCountsBuckets);
     fixed_window_.missed_vsyncs += curr_frame_missed_vsyncs;
     per_scroll_->missed_vsyncs += curr_frame_missed_vsyncs;
+
+    // TODO(b/306611560): If experimental per scroll logic is promoted to
+    // default, then UKM reporting will need to be recorded under the same
+    // conditions.
+    if (scroll_jank_ukm_reporter_) {
+      scroll_jank_ukm_reporter_->IncrementDelayedFrameCount();
+      scroll_jank_ukm_reporter_->AddMissedVsyncs(curr_frame_missed_vsyncs);
+    }
+
     if (curr_frame_missed_vsyncs > per_scroll_->max_missed_vsyncs) {
       per_scroll_->max_missed_vsyncs = curr_frame_missed_vsyncs;
+      if (scroll_jank_ukm_reporter_) {
+        scroll_jank_ukm_reporter_->set_max_missed_vsyncs(
+            curr_frame_missed_vsyncs);
+      }
     }
     if (curr_frame_missed_vsyncs > fixed_window_.max_missed_vsyncs) {
       fixed_window_.max_missed_vsyncs = curr_frame_missed_vsyncs;
@@ -298,13 +311,22 @@
     // Per scroll
     experimental_per_scroll_vsync_->missed_vsyncs += curr_frame_missed_vsyncs;
     experimental_per_scroll_vsync_->num_past_vsyncs += curr_frame_total_vsyncs;
+    if (scroll_jank_ukm_reporter_) {
+      scroll_jank_ukm_reporter_->AddVsyncs(curr_frame_total_vsyncs);
+    }
   } else {
     ++experimental_vsync_fixed_window_.num_past_vsyncs;
     ++experimental_per_scroll_vsync_->num_past_vsyncs;
+    if (scroll_jank_ukm_reporter_) {
+      scroll_jank_ukm_reporter_->AddVsyncs(1);
+    }
   }
 
   ++fixed_window_.num_presented_frames;
   ++per_scroll_->num_presented_frames;
+  if (scroll_jank_ukm_reporter_) {
+    scroll_jank_ukm_reporter_->IncrementFrameCount();
+  }
 
   if (fixed_window_.num_presented_frames == kHistogramEmitFrequency) {
     EmitPerWindowHistogramsAndResetCounters();
diff --git a/cc/metrics/scroll_jank_dropped_frame_tracker.h b/cc/metrics/scroll_jank_dropped_frame_tracker.h
index 80bf649..6acc173 100644
--- a/cc/metrics/scroll_jank_dropped_frame_tracker.h
+++ b/cc/metrics/scroll_jank_dropped_frame_tracker.h
@@ -9,8 +9,10 @@
 #include "base/time/time.h"
 #include "cc/cc_export.h"
 #include "cc/metrics/event_metrics.h"
+#include "cc/metrics/scroll_jank_ukm_reporter.h"
 
 namespace cc {
+class ScrollJankUkmReporter;
 
 class CC_EXPORT ScrollJankDroppedFrameTracker {
  public:
@@ -25,6 +27,11 @@
                                     base::TimeDelta vsync_interval);
   void OnScrollStarted();
 
+  void set_scroll_jank_ukm_reporter(
+      raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter) {
+    scroll_jank_ukm_reporter_ = scroll_jank_ukm_reporter;
+  }
+
   static constexpr int kHistogramEmitFrequency = 64;
   static constexpr const char* kDelayedFramesWindowHistogram =
       "Event.ScrollJank.DelayedFramesPercentage.FixedWindow";
@@ -79,6 +86,8 @@
   JankData experimental_vsync_fixed_window_;
   std::optional<JankData> per_scroll_;
   std::optional<JankData> experimental_per_scroll_vsync_;
+
+  raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_ = nullptr;
 };
 
 }  // namespace cc
diff --git a/cc/metrics/scroll_jank_ukm_reporter.cc b/cc/metrics/scroll_jank_ukm_reporter.cc
new file mode 100644
index 0000000..3be64d3a
--- /dev/null
+++ b/cc/metrics/scroll_jank_ukm_reporter.cc
@@ -0,0 +1,66 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/metrics/scroll_jank_ukm_reporter.h"
+
+#include "cc/trees/ukm_manager.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"
+
+namespace cc {
+
+ScrollJankUkmReporter::ScrollJankUkmReporter() = default;
+ScrollJankUkmReporter::~ScrollJankUkmReporter() {
+  EmitScrollJankUkm();
+  ukm_manager_ = nullptr;
+}
+
+void ScrollJankUkmReporter::IncrementFrameCount() {
+  num_frames_++;
+}
+
+void ScrollJankUkmReporter::IncrementDelayedFrameCount() {
+  num_delayed_frames_++;
+}
+
+void ScrollJankUkmReporter::AddVsyncs(int vsyncs) {
+  num_vsyncs_ += vsyncs;
+}
+
+void ScrollJankUkmReporter::AddMissedVsyncs(int missed_vsyncs) {
+  num_missed_vsyncs_ += missed_vsyncs;
+}
+
+void ScrollJankUkmReporter::IncrementPredictorJankyFrames() {
+  predictor_jank_frames_++;
+}
+
+void ScrollJankUkmReporter::EmitScrollJankUkm() {
+  if (ukm_manager_) {
+    ukm::builders::Event_Scroll builder(ukm_manager_->source_id());
+    builder.SetFrameCount(
+        ukm::GetExponentialBucketMinForCounts1000(num_frames_));
+    builder.SetVsyncCount(
+        ukm::GetExponentialBucketMinForCounts1000(num_vsyncs_));
+    builder.SetScrollJank_MissedVsyncsMax(
+        ukm::GetExponentialBucketMinForCounts1000(max_missed_vsyncs_));
+    builder.SetScrollJank_MissedVsyncsSum(
+        ukm::GetExponentialBucketMinForCounts1000(num_missed_vsyncs_));
+    builder.SetScrollJank_DelayedFrameCount(
+        ukm::GetExponentialBucketMinForCounts1000(num_delayed_frames_));
+    builder.SetPredictorJankyFrameCount(
+        ukm::GetExponentialBucketMinForCounts1000(predictor_jank_frames_));
+    builder.Record(ukm_manager_->recorder());
+  }
+
+  num_frames_ = 0;
+  num_vsyncs_ = 0;
+  num_missed_vsyncs_ = 0;
+  max_missed_vsyncs_ = 0;
+  num_delayed_frames_ = 0;
+  predictor_jank_frames_ = 0;
+}
+
+}  // namespace cc
diff --git a/cc/metrics/scroll_jank_ukm_reporter.h b/cc/metrics/scroll_jank_ukm_reporter.h
new file mode 100644
index 0000000..362c97c
--- /dev/null
+++ b/cc/metrics/scroll_jank_ukm_reporter.h
@@ -0,0 +1,56 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_
+#define CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_
+
+#include <optional>
+#include "base/memory/raw_ptr.h"
+#include "cc/cc_export.h"
+
+// TODO(b/294040250): Add metrics for ScrollPredictor histogram.
+
+namespace cc {
+class UkmManager;
+
+class CC_EXPORT ScrollJankUkmReporter {
+ public:
+  ScrollJankUkmReporter();
+  ~ScrollJankUkmReporter();
+
+  ScrollJankUkmReporter(const ScrollJankUkmReporter&) = delete;
+
+  void IncrementFrameCount();
+  void IncrementDelayedFrameCount();
+  void AddVsyncs(int vsyncs);
+  void AddMissedVsyncs(int missed_vsyncs);
+  void IncrementPredictorJankyFrames();
+
+  void EmitScrollJankUkm();
+
+  void set_max_missed_vsyncs(int max_missed_vsyncs) {
+    max_missed_vsyncs_ = max_missed_vsyncs;
+  }
+
+  void set_ukm_manager(UkmManager* manager) { ukm_manager_ = manager; }
+
+ private:
+  int num_frames_ = 0;
+  int num_vsyncs_ = 0;
+  int num_missed_vsyncs_ = 0;
+  int max_missed_vsyncs_ = 0;
+  int num_delayed_frames_ = 0;
+  int predictor_jank_frames_ = 0;
+
+  // This is pointing to the LayerTreeHostImpl::ukm_manager_, which is
+  // initialized right after the LayerTreeHostImpl is created. So when this
+  // pointer is initialized, there should be no trackers yet. Moreover, the
+  // LayerTreeHostImpl::ukm_manager_ lives as long as the LayerTreeHostImpl, so
+  // this pointer should never be null as long as LayerTreeHostImpl is alive.
+  raw_ptr<UkmManager> ukm_manager_ = nullptr;
+};
+
+}  // namespace cc
+
+#endif  // CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_
diff --git a/cc/metrics/scroll_jank_ukm_reporter_unittest.cc b/cc/metrics/scroll_jank_ukm_reporter_unittest.cc
new file mode 100644
index 0000000..808087d17
--- /dev/null
+++ b/cc/metrics/scroll_jank_ukm_reporter_unittest.cc
@@ -0,0 +1,304 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/metrics/scroll_jank_ukm_reporter.h"
+
+#include "base/test/simple_test_tick_clock.h"
+#include "cc/metrics/predictor_jank_tracker.h"
+#include "cc/metrics/scroll_jank_dropped_frame_tracker.h"
+#include "cc/trees/ukm_manager.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+const char kTestUrl[] = "https://example.com/foo";
+const int64_t kTestSourceId = 100;
+}  // namespace
+
+class ScrollJankUkmReporterTest : public testing::Test {
+ public:
+  ScrollJankUkmReporterTest() = default;
+
+  void SetUp() override {
+    base_time_ = base::TimeTicks::Now();
+
+    auto recorder = std::make_unique<ukm::TestAutoSetUkmRecorder>();
+    test_ukm_recorder_ = recorder.get();
+    ukm_manager_ = std::make_unique<UkmManager>(std::move(recorder));
+    test_ukm_recorder_->UpdateSourceURL(kTestSourceId, GURL(kTestUrl));
+    ukm_manager_->SetSourceId(kTestSourceId);
+
+    scroll_jank_ukm_reporter_ = std::make_unique<ScrollJankUkmReporter>();
+    scroll_jank_ukm_reporter_->set_ukm_manager(ukm_manager_.get());
+
+    scroll_jank_dropped_frame_tracker_ =
+        std::make_unique<ScrollJankDroppedFrameTracker>();
+    scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter(
+        scroll_jank_ukm_reporter_.get());
+    scroll_jank_dropped_frame_tracker_->OnScrollStarted();
+
+    predictor_jank_tracker_ = std::make_unique<PredictorJankTracker>();
+    predictor_jank_tracker_->set_scroll_jank_ukm_reporter(
+        scroll_jank_ukm_reporter_.get());
+  }
+
+  void ReportFramesToScrollJankDroppedFrameTracker(
+      base::TimeTicks first_input_ts,
+      base::TimeTicks last_input_ts,
+      base::TimeTicks presentation_ts) {
+    base::SimpleTestTickClock tick_clock;
+    tick_clock.SetNowTicks(base::TimeTicks(first_input_ts));
+    auto event = ScrollUpdateEventMetrics::CreateForTesting(
+        ui::ET_GESTURE_SCROLL_UPDATE, ui::ScrollInputType::kWheel,
+        /*is_inertial=*/false,
+        ScrollUpdateEventMetrics::ScrollUpdateType::kContinued,
+        /*delta=*/10.0f, first_input_ts, base::TimeTicks(), &tick_clock,
+        /*trace_id=*/std::nullopt);
+    scroll_jank_dropped_frame_tracker_->ReportLatestPresentationData(
+        *event.get(), last_input_ts, presentation_ts, vsync_interval);
+  }
+
+  void ReportFramesToPredictorJankTracker(double delta,
+                                          base::TimeTicks first_input_ts,
+                                          base::TimeTicks presentation_ts) {
+    base::SimpleTestTickClock tick_clock;
+    tick_clock.SetNowTicks(first_input_ts);
+    auto event = ScrollUpdateEventMetrics::CreateForTesting(
+        ui::ET_GESTURE_SCROLL_UPDATE, ui::ScrollInputType::kWheel,
+        /*is_inertial=*/false,
+        ScrollUpdateEventMetrics::ScrollUpdateType::kContinued,
+        /*delta=*/10.0f, first_input_ts, base::TimeTicks(), &tick_clock,
+        /*trace_id=*/std::nullopt);
+    predictor_jank_tracker_->ReportLatestScrollDelta(
+        delta, presentation_ts, vsync_interval, event->trace_id());
+  }
+
+ protected:
+  base::TimeTicks base_time_;
+  raw_ptr<ukm::TestUkmRecorder, DanglingUntriaged> test_ukm_recorder_;
+  std::unique_ptr<UkmManager> ukm_manager_;
+  std::unique_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_;
+  std::unique_ptr<ScrollJankDroppedFrameTracker>
+      scroll_jank_dropped_frame_tracker_;
+  std::unique_ptr<PredictorJankTracker> predictor_jank_tracker_;
+
+ private:
+  constexpr static base::TimeDelta vsync_interval = base::Milliseconds(16);
+};
+
+TEST_F(ScrollJankUkmReporterTest, NoJankUkmRecorded) {
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 0);
+}
+
+TEST_F(ScrollJankUkmReporterTest, NoJankyFrames) {
+  // Report one frame per vsync.
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(111),
+      base_time_ + base::Milliseconds(148));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(119),
+      base_time_ + base::Milliseconds(127),
+      base_time_ + base::Milliseconds(164));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 2);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 0);
+}
+
+TEST_F(ScrollJankUkmReporterTest, JankyFrames) {
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(111),
+      base_time_ + base::Milliseconds(148));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(119),
+      base_time_ + base::Milliseconds(127),
+      base_time_ + base::Milliseconds(196));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(135),
+      base_time_ + base::Milliseconds(143),
+      base_time_ + base::Milliseconds(228));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 3);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 2);
+}
+
+TEST_F(ScrollJankUkmReporterTest, NoMissedVsyncs) {
+  // Report one frame per vsync.
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(111),
+      base_time_ + base::Milliseconds(148));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(119),
+      base_time_ + base::Milliseconds(127),
+      base_time_ + base::Milliseconds(164));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 2);
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 0);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 0);
+}
+
+TEST_F(ScrollJankUkmReporterTest, OneMissedVsync) {
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(111),
+      base_time_ + base::Milliseconds(148));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(119),
+      base_time_ + base::Milliseconds(127),
+      base_time_ + base::Milliseconds(164));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(135),
+      base_time_ + base::Milliseconds(143),
+      base_time_ + base::Milliseconds(196));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 4);
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 1);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 1);
+}
+
+TEST_F(ScrollJankUkmReporterTest, MultipleMissedVsyncs) {
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(103),
+      base_time_ + base::Milliseconds(148));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(119),
+      base_time_ + base::Milliseconds(127),
+      base_time_ + base::Milliseconds(196));
+
+  ReportFramesToScrollJankDroppedFrameTracker(
+      base_time_ + base::Milliseconds(135),
+      base_time_ + base::Milliseconds(151),
+      base_time_ + base::Milliseconds(228));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 6);
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 2);
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 3);
+}
+
+TEST_F(ScrollJankUkmReporterTest, NoPredictorJank) {
+  ReportFramesToPredictorJankTracker(10, base_time_,
+                                     base_time_ + base::Milliseconds(103));
+  ReportFramesToPredictorJankTracker(10, base_time_,
+                                     base_time_ + base::Milliseconds(119));
+  ReportFramesToPredictorJankTracker(10, base_time_,
+                                     base_time_ + base::Milliseconds(135));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 0);
+}
+
+TEST_F(ScrollJankUkmReporterTest, PredictorJank) {
+  ReportFramesToPredictorJankTracker(10, base_time_,
+                                     base_time_ + base::Milliseconds(103));
+  ReportFramesToPredictorJankTracker(50, base_time_,
+                                     base_time_ + base::Milliseconds(135));
+  ReportFramesToPredictorJankTracker(10, base_time_,
+                                     base_time_ + base::Milliseconds(151));
+
+  scroll_jank_ukm_reporter_->EmitScrollJankUkm();
+
+  auto entries = test_ukm_recorder_->GetEntriesByName(
+      ukm::builders::Event_Scroll::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+
+  test_ukm_recorder_->ExpectEntryMetric(
+      entries.back(),
+      ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 1);
+}
+
+}  // namespace cc
diff --git a/cc/trees/ukm_manager.h b/cc/trees/ukm_manager.h
index e61c14a4..2af22a3 100644
--- a/cc/trees/ukm_manager.h
+++ b/cc/trees/ukm_manager.h
@@ -55,7 +55,9 @@
       const CompositorFrameReporter::ProcessedVizBreakdown&
           processed_viz_breakdown) const;
 
-  ukm::UkmRecorder* recorder_for_testing() { return recorder_.get(); }
+  ukm::UkmRecorder* recorder() { return recorder_.get(); }
+
+  ukm::SourceId source_id() { return source_id_; }
 
  private:
   ukm::SourceId source_id_ = ukm::kInvalidSourceId;
diff --git a/cc/trees/ukm_manager_unittest.cc b/cc/trees/ukm_manager_unittest.cc
index 04c3832..2745178e 100644
--- a/cc/trees/ukm_manager_unittest.cc
+++ b/cc/trees/ukm_manager_unittest.cc
@@ -129,7 +129,7 @@
   }
 
   ukm::TestUkmRecorder* recorder() {
-    return static_cast<ukm::TestUkmRecorder*>(manager_->recorder_for_testing());
+    return static_cast<ukm::TestUkmRecorder*>(manager_->recorder());
   }
 
   std::unique_ptr<EventMetrics> SetupEventMetrics(
diff --git a/chrome/VERSION b/chrome/VERSION
index 2e810774..f116613 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=122
 MINOR=0
-BUILD=6196
+BUILD=6197
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java
index a64497cc..77a2cc9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java
@@ -84,11 +84,10 @@
     private static final String ENABLED_GROUP_SUFFIX = "_Enabled";
     private static final String CONTROL_GROUP_SUFFIX = "_Control";
     private static final String DEFAULT_ON_GROUP_NAME_PREFIX = "DefaultOn_";
-    private static final String OPT_IN_GROUP_NAME_PREFIX = "OptIn_";
     // This is used to lookup the name of a feature used to track a cohort of users who triggered
     // the global default experiment, or would have triggered for control groups.
     private static final String PARAM_GLOBAL_DEFAULTS_COHORT_ID = "global_setting_cohort_id";
-    private static final int DEFAULT_GLOBAL_DEFAULTS_COHORT_ID = 0;
+    private static final int DEFAULT_GLOBAL_DEFAULTS_COHORT_ID = 1;
     private static final String GLOBAL_DEFAULTS_COHORT_NAME = "RequestDesktopSiteDefaultsCohort";
     private static final String GLOBAL_DEFAULTS_ENABLED_COHORT_NAME =
             "RequestDesktopSiteDefaultsEnabledCohort";
@@ -982,12 +981,10 @@
             return;
         }
 
-        // For backward compatibility.
-        if (cohortId == 0) {
-            maybeRegisterSyntheticFieldTrials(isControlGroup, screenSizeThreshold, isOptInArm);
+        if (isOptInArm) {
+            // Opt-in arm is not supported for the new cohort tracking.
             return;
         }
-        assert !isOptInArm : "Opt-in arm is not supported for the new cohort tracking.";
 
         String thresholdAsString = String.valueOf(screenSizeThreshold).replace('.', '_');
         String baseGroupName = DEFAULT_ON_GROUP_NAME_PREFIX + thresholdAsString + "_" + cohortId;
@@ -1016,37 +1013,6 @@
                 SyntheticTrialAnnotationMode.CURRENT_LOG);
     }
 
-    private static void maybeRegisterSyntheticFieldTrials(
-            boolean isControlGroup, double screenSizeThreshold, boolean isOptInArm) {
-        String thresholdAsString = String.valueOf(screenSizeThreshold).replace('.', '_');
-        String baseGroupName =
-                (isOptInArm ? OPT_IN_GROUP_NAME_PREFIX : DEFAULT_ON_GROUP_NAME_PREFIX)
-                        + thresholdAsString;
-
-        String syntheticFeatureName =
-                isControlGroup
-                        ? ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL_SYNTHETIC
-                        : ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_SYNTHETIC;
-        if (isOptInArm) {
-            syntheticFeatureName =
-                    isControlGroup
-                            ? ChromeFeatureList.REQUEST_DESKTOP_SITE_OPT_IN_CONTROL_SYNTHETIC
-                            : ChromeFeatureList.REQUEST_DESKTOP_SITE_OPT_IN_SYNTHETIC;
-        }
-
-        if (!isControlGroup && !ChromeFeatureList.isEnabled(syntheticFeatureName)) {
-            UmaSessionStats.registerSyntheticFieldTrial(
-                    syntheticFeatureName,
-                    baseGroupName + ENABLED_GROUP_SUFFIX,
-                    SyntheticTrialAnnotationMode.CURRENT_LOG);
-        } else if (isControlGroup && !ChromeFeatureList.isEnabled(syntheticFeatureName)) {
-            UmaSessionStats.registerSyntheticFieldTrial(
-                    syntheticFeatureName,
-                    baseGroupName + CONTROL_GROUP_SUFFIX,
-                    SyntheticTrialAnnotationMode.CURRENT_LOG);
-        }
-    }
-
     @VisibleForTesting
     static void onGlobalSettingOptInMessageClicked(
             Profile profile, ObservableSupplier<Tab> currentTabSupplier) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
index 9fe17d6..42fdcb0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
@@ -931,19 +931,6 @@
     }
 
     @Test
-    public void testMaybeRegisterSyntheticFieldTrials_DefaultOnEnabled12Inches() {
-        RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 0, false);
-        Assert.assertEquals(
-                "Trial name is incorrect.",
-                "RequestDesktopSiteDefaultsSynthetic",
-                sGlobalDefaultsExperimentTrialName);
-        Assert.assertEquals(
-                "Group name is incorrect.",
-                "DefaultOn_12_0_Enabled",
-                sGlobalDefaultsExperimentGroupName);
-    }
-
-    @Test
     public void testMaybeRegisterSyntheticFieldTrials_DefaultOnEnabled12Inches_WithCohortId() {
         RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 2, false);
         Assert.assertEquals(
@@ -955,19 +942,6 @@
     }
 
     @Test
-    public void testMaybeRegisterSyntheticFieldTrials_DefaultOnControl12Inches() {
-        RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(true, 12.0, 0, false);
-        Assert.assertEquals(
-                "Trial name is incorrect.",
-                "RequestDesktopSiteDefaultsControlSynthetic",
-                sGlobalDefaultsExperimentTrialName);
-        Assert.assertEquals(
-                "Group name is incorrect.",
-                "DefaultOn_12_0_Control",
-                sGlobalDefaultsExperimentGroupName);
-    }
-
-    @Test
     public void testMaybeRegisterSyntheticFieldTrials_DefaultOnControl12Inches_WithCohortId() {
         RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(true, 12.0, 2, false);
         Assert.assertEquals(
@@ -979,29 +953,6 @@
     }
 
     @Test
-    public void testMaybeRegisterSyntheticFieldTrials_OptInEnabled10Inches() {
-        RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 10.0, 0, true);
-        Assert.assertEquals(
-                "Trial name is incorrect.",
-                "RequestDesktopSiteOptInSynthetic",
-                sGlobalDefaultsExperimentTrialName);
-        Assert.assertEquals(
-                "Group name is incorrect.",
-                "OptIn_10_0_Enabled",
-                sGlobalDefaultsExperimentGroupName);
-    }
-
-    @Test
-    public void testMaybeRegisterSyntheticFieldTrials_DoNothingWhenExperimentIsActive() {
-        enableFeatureWithParams("RequestDesktopSiteDefaultsSynthetic", null, true);
-        RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 0, false);
-        Assert.assertTrue(
-                "Synthetic trial should not be registered.",
-                sGlobalDefaultsExperimentTrialName == null
-                        && sGlobalDefaultsExperimentGroupName == null);
-    }
-
-    @Test
     public void testMaybeRegisterSyntheticFieldTrials_ExperimentIsActive_WithCohortId() {
         enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort2", null, true);
         RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 2, false);
@@ -1807,10 +1758,8 @@
     private void disableGlobalDefaultsExperimentFeatures() {
         enableFeatureWithParams("RequestDesktopSiteDefaults", null, false);
         enableFeatureWithParams("RequestDesktopSiteDefaultsControl", null, false);
-        enableFeatureWithParams("RequestDesktopSiteDefaultsControlSynthetic", null, false);
-        enableFeatureWithParams("RequestDesktopSiteDefaultsSynthetic", null, false);
-        enableFeatureWithParams("RequestDesktopSiteOptInControlSynthetic", null, false);
-        enableFeatureWithParams("RequestDesktopSiteOptInSynthetic", null, false);
+        enableFeatureWithParams("RequestDesktopSiteDefaultsControlCohort1", null, false);
+        enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort1", null, false);
         enableFeatureWithParams("RequestDesktopSiteDefaultsControlCohort2", null, false);
         enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort2", null, false);
     }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index b4da2225..8534f64 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9106,32 +9106,32 @@
       </message>
 
       <!-- Strings for tab organization -->
-      <message name="IDS_TOOLTIP_TAB_ORGANIZE" desc="The tooltip for the Tab Organization button." translateable="false">
+      <message name="IDS_TOOLTIP_TAB_ORGANIZE" desc="The tooltip for the Tab Organization button.">
         Organize tabs?
       </message>
-      <message name="IDS_TAB_ORGANIZE" desc="The text label of the Tab Organization button." translateable="false">
+      <message name="IDS_TAB_ORGANIZE" desc="The text label of the Tab Organization button.">
         Organize tabs?
       </message>
-      <message name="IDS_TOOLTIP_TAB_ORGANIZE_CLOSE" desc="The tooltip for the close button within the Tab Organization button." translateable="false">
+      <message name="IDS_TOOLTIP_TAB_ORGANIZE_CLOSE" desc="The tooltip for the close button within the Tab Organization button.">
         Dismiss suggestion
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER" desc="Placeholder text for the Tab Organization feedback dialog." translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER" desc="Placeholder text for the Tab Organization feedback dialog.">
         Send feedback for Suggested Groups
       </message>
       <if expr="use_titlecase">
-        <message name="IDS_TAB_ORGANIZE_MENU" desc="In Title Case: The text label for the tab organization app menu item." translateable="false">
+        <message name="IDS_TAB_ORGANIZE_MENU" desc="In Title Case: The text label for the tab organization app menu item.">
           Organize Tabs
         </message>
       </if>
       <if expr="not use_titlecase">
-        <message name="IDS_TAB_ORGANIZE_MENU" desc="The text label for the tab organization app menu item." translateable="false">
+        <message name="IDS_TAB_ORGANIZE_MENU" desc="The text label for the tab organization app menu item.">
           Organize tabs
         </message>
       </if>
-      <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH" desc="The body text of the IPH describing how to interact with a tab group resulting from tab organization." translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH" desc="The body text of the IPH describing how to interact with a tab group resulting from tab organization.">
         Right-click on the tab group name to edit this group or click to collapse
       </message>
-      <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH_SCREENREADER" desc="The screen reader text of the IPH describing how to interact with a tab group resulting from tab organization." translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH_SCREENREADER" desc="The screen reader text of the IPH describing how to interact with a tab group resulting from tab organization." is_accessibility_with_no_ui="true">
         Select the tab group and activate the context menu to edit
       </message>
 
@@ -9320,7 +9320,7 @@
       <message name="IDS_ACCNAME_TAB_SEARCH" desc="The accessible name for the Tab Search bubble.">
         Search tabs
       </message>
-      <message name="IDS_ACCNAME_TAB_ORGANIZE" desc="The accessible name for the Tab Organization button." translateable="false">
+      <message name="IDS_ACCNAME_TAB_ORGANIZE" desc="The accessible name for the Tab Organization button." is_accessibility_with_no_ui="true">
         Group related tabs
       </message>
       <message name="IDS_ACCNAME_TAB_SCROLL_LEADING" desc="The accessible name for the TabStrip leading scroll button.">
@@ -10428,7 +10428,7 @@
         <message name="IDS_TAB_CXMENU_MOVETOANOTHERNEWWINDOW" desc="The label for the Tab context item to move items to a new window from the 'Move tabs to another window' submenu.">
           New window
         </message>
-        <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="The label of the 'Organize tabs' Tab context menu item." translateable="false">
+        <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="The label of the 'Organize tabs' Tab context menu item.">
           Organize similar tabs
         </message>
         <message name="IDS_TAB_CXMENU_FOLLOW_SITE" desc="The label of the tab context menu item
@@ -10531,7 +10531,7 @@
         <message name="IDS_TAB_CXMENU_MOVETOANOTHERNEWWINDOW" desc="In Title Case: The label for the Tab context item to move items to a new window from the 'Move tabs to another window' submenu.">
           New Window
         </message>
-        <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="In Title Case: The label of the 'Organize tabs' Tab context menu item." translateable="false">
+        <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="In Title Case: The label of the 'Organize tabs' Tab context menu item.">
           Organize Similar Tabs
         </message>
         <message name="IDS_TAB_CXMENU_FOLLOW_SITE" desc="In Title Case: The label of the tab context menu item for following a site.">
@@ -10635,10 +10635,10 @@
       <message name="IDS_TAB_SEARCH_COLLAPSE_RECENTLY_CLOSED" desc="The tooltip for the RECENTLY CLOSED button when it's expanded">
         Collapse recently closed
       </message>
-      <message name="IDS_TAB_SEARCH_TAB_NAME" desc="The tab title for tab search in the tab search bubble" translateable="false">
+      <message name="IDS_TAB_SEARCH_TAB_NAME" desc="The tab title for tab search in the tab search bubble">
         All tabs
       </message>
-      <message name="IDS_TAB_ORGANIZATION_TAB_NAME" desc="The tab title for tab organization in the tab search bubble" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_TAB_NAME" desc="The tab title for tab organization in the tab search bubble">
         Organize tabs
       </message>
       <message name="IDS_TAB_ORGANIZATION_CREATE_GROUP" desc="The label for the button that creates a tab group in the tab organization UI">
@@ -10647,100 +10647,100 @@
       <message name="IDS_TAB_ORGANIZATION_DISMISS" desc="The label for the button that dismisses the tab organization UI">
         Dismiss
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE" desc="The header text for the not started state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE" desc="The header text for the not started state in the tab organization UI">
         Check if tabs can be organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE" desc="The header text for the first run experience of the not started state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE" desc="The header text for the first run experience of the not started state in the tab organization UI">
         Let Chrome organize your tabs
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY" desc="The body text for the not started state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY" desc="The body text for the not started state in the tab organization UI">
         You can check for tab group suggestions at any time
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE" desc="The body text for the first run experience of the not started state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE" desc="The body text for the first run experience of the not started state in the tab organization UI">
         You'll get tab group suggestions that group similar tabs to help you stay organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT" desc="The body text for the not started state in the tab organization UI, when not signed in" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT" desc="The body text for the not started state in the tab organization UI, when not signed in">
         Sign in and turn on sync to let Chrome suggest tab groups and keep your tabs organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED" desc="The body text for the not started state in the tab organization UI, when signed in but unsynced" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED" desc="The body text for the not started state in the tab organization UI, when signed in but unsynced">
         Turn on sync to let Chrome suggest tab groups and keep your tabs organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY" desc="The body text for the not started state in the tab organization UI, when history sync is disabled" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY" desc="The body text for the not started state in the tab organization UI, when history sync is disabled">
         Turn on History sync in Settings to let Chrome suggest tab groups and keep your tabs organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED" desc="The body text for the not started state in the tab organization UI, sync is paused" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED" desc="The body text for the not started state in the tab organization UI, sync is paused">
         Sign in to let Chrome suggest tab groups and keep your tabs organized
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON" desc="The label for the button in the not started state of the tab organization UI, when synced" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON" desc="The label for the button in the not started state of the tab organization UI, when synced">
         Check now
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE" desc="The first run experience label for the button in the not started state of the tab organization UI, when synced" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE" desc="The first run experience label for the button in the not started state of the tab organization UI, when synced">
         Let's go
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED" desc="The label for the button in the not started state of the tab organization UI, when not signed in or signed in but unsynced" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED" desc="The label for the button in the not started state of the tab organization UI, when not signed in or signed in but unsynced">
         Turn on sync
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY" desc="The label for the button in the not started state of the tab organization UI, when history sync is disabled" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY" desc="The label for the button in the not started state of the tab organization UI, when history sync is disabled">
         Settings
       </message>
-      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED" desc="The label for the button in the not started state of the tab organization UI, when sync is paused" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED" desc="The label for the button in the not started state of the tab organization UI, when sync is paused">
         Sign in
       </message>
-      <message name="IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE" desc="The header text for the in progress state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE" desc="The header text for the in progress state in the tab organization UI">
         Organizing into a tab group…
       </message>
-      <message name="IDS_TAB_ORGANIZATION_SUCCESS_TITLE" desc="The header text for the success state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_SUCCESS_TITLE" desc="The header text for the success state in the tab organization UI">
         Tab group suggestion
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC" desc="The header text for the generic failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC" desc="The header text for the generic failure state in the tab organization UI">
         Something went wrong
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING" desc="The header text for the grouping failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING" desc="The header text for the grouping failure state in the tab organization UI">
         No groups found
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK" desc="The pre-link body text for the generic failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK" desc="The pre-link body text for the generic failure state in the tab organization UI. This should form a sentence when followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.">
         Tab group suggestions are currently unavailable. You can
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK" desc="The link body text for the generic failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK" desc="The link body text for the generic failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK and followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.">
         refresh now
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK" desc="The post-link body text for the generic failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK" desc="The post-link body text for the generic failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.">
         or try again later.
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK" desc="The pre-link body text for the grouping failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK" desc="The pre-link body text for the grouping failure state in the tab organization UI. This should form a sentence when followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.">
         You can
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK" desc="The link body text for the grouping failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK" desc="The link body text for the grouping failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK and followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.">
          refresh now
       </message>
-      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK" desc="The post-link body text for the grouping failure state in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK" desc="The post-link body text for the grouping failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.">
          or try again later after you open new similar tabs.
       </message>
-      <message name="IDS_TAB_ORGANIZATION_TIP_TITLE" desc="The bolded text at the start of the tip in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_TIP_TITLE" desc="The bolded text at the start of the tip in the tab organization UI">
         Tip:
       </message>
-      <message name="IDS_TAB_ORGANIZATION_TIP_BODY" desc="The main text of the tip in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_TIP_BODY" desc="The main text of the tip in the tab organization UI">
         You can create your own tab group.
       </message>
-      <message name="IDS_TAB_ORGANIZATION_TIP_ACTION" desc="The actionable text of the tip in the tab organization UI" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_TIP_ACTION" desc="The actionable text of the tip in the tab organization UI">
         Show me how
       </message>
-      <message name="IDS_TAB_ORGANIZATION_TIP_ARIA_DESCRIPTION" desc="The a11y description of the tip in the tab organization UI" translateable="false" is_accessibility_with_no_ui="true">
+      <message name="IDS_TAB_ORGANIZATION_TIP_ARIA_DESCRIPTION" desc="The a11y description of the tip in the tab organization UI" is_accessibility_with_no_ui="true">
         Launch tab group tutorial
       </message>
-      <message name="IDS_TAB_ORGANIZATION_DISCLAIMER" desc="The disclaimer text in the tab organization UI results state for getting more information" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_DISCLAIMER" desc="The disclaimer text in the tab organization UI results state for getting more information">
         This is an experimental AI feature and won't always get it right.
       </message>
-      <message name="IDS_TAB_ORGANIZATION_LEARN_MORE" desc="The actionable text in the tab organization UI results state for getting more information" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_LEARN_MORE" desc="The actionable text in the tab organization UI results state for getting more information">
         Learn more
       </message>
-      <message name="IDS_TAB_ORGANIZATION_CLOSE_TAB" desc="The accessible label in the tab organization UI results state for removing a tab" translateable="false" is_accessibility_with_no_ui="true">
+      <message name="IDS_TAB_ORGANIZATION_CLOSE_TAB" desc="The accessible label in the tab organization UI results state for removing a tab" is_accessibility_with_no_ui="true">
         Remove <ph name="TAB_TITLE">$1<ex>New Tab</ex></ph> from tab group
       </message>
-      <message name="IDS_TAB_ORGANIZATION_REJECT_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current suggestion" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_REJECT_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current suggestion">
         Refresh
       </message>
-      <message name="IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current (and final) suggestion" translateable="false">
+      <message name="IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current (and final) suggestion">
         Clear
       </message>
 
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1
new file mode 100644
index 0000000..c4610b87
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1
@@ -0,0 +1 @@
+4496b3c76fc1f14929491b8ff0911276dee22b5f
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1
index e1333e5..c1bcfb9a 100644
--- a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1
@@ -1 +1 @@
-f54132a5f004928712119e0367b7f58d77f1dbc7
\ No newline at end of file
+4f599c7f3dbb17f3c40cbeba78cfb2841fd033ce
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1
new file mode 100644
index 0000000..7f0ee12
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1
@@ -0,0 +1 @@
+7786d7ac7758cc3d1d61de53965fd9e6cec09983
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1
new file mode 100644
index 0000000..e3e934d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1
@@ -0,0 +1 @@
+d948ede26072e039e12bbe510fba21f03a377485
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1
new file mode 100644
index 0000000..e3e934d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1
@@ -0,0 +1 @@
+d948ede26072e039e12bbe510fba21f03a377485
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1
new file mode 100644
index 0000000..e3e934d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1
@@ -0,0 +1 @@
+d948ede26072e039e12bbe510fba21f03a377485
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1
new file mode 100644
index 0000000..9b63e69f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1
@@ -0,0 +1 @@
+a20d651a3346ac62951076befe514b6e2211bb5c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1
new file mode 100644
index 0000000..9b63e69f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1
@@ -0,0 +1 @@
+a20d651a3346ac62951076befe514b6e2211bb5c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1
new file mode 100644
index 0000000..9b63e69f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1
@@ -0,0 +1 @@
+a20d651a3346ac62951076befe514b6e2211bb5c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1
new file mode 100644
index 0000000..e3e934d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1
@@ -0,0 +1 @@
+d948ede26072e039e12bbe510fba21f03a377485
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1
new file mode 100644
index 0000000..9b63e69f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1
@@ -0,0 +1 @@
+a20d651a3346ac62951076befe514b6e2211bb5c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1
new file mode 100644
index 0000000..bdf645f6
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1
@@ -0,0 +1 @@
+08fad7898a5da3ecf26eade4fd9cc8ff0c54cf17
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1
new file mode 100644
index 0000000..b3133cb
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1
@@ -0,0 +1 @@
+48f6b91c6dc42f6e2b142baa880569dfe0902392
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1
new file mode 100644
index 0000000..7f0ee12
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1
@@ -0,0 +1 @@
+7786d7ac7758cc3d1d61de53965fd9e6cec09983
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1
new file mode 100644
index 0000000..a479520
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1
@@ -0,0 +1 @@
+3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1
new file mode 100644
index 0000000..9b04a8c
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1
@@ -0,0 +1 @@
+7d7533129e5e7faaf06cad184cd1a3a46a35de1c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1
new file mode 100644
index 0000000..3cce170
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1
@@ -0,0 +1 @@
+229d5d94f765211db84552b420734b2b414350c6
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1
new file mode 100644
index 0000000..acecd83
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1
@@ -0,0 +1 @@
+aefddc2ca85392563aac0b8b121109b4bb8983b4
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1
new file mode 100644
index 0000000..738a73b9
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1
@@ -0,0 +1 @@
+9db679e9293cdc7b8abe42195e49f6ef183348cf
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1
new file mode 100644
index 0000000..4107492
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1
@@ -0,0 +1 @@
+2242a9208af02e6f0ca4e650c967b96df8e08a54
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1
new file mode 100644
index 0000000..a479520
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1
@@ -0,0 +1 @@
+3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1
new file mode 100644
index 0000000..9b04a8c
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1
@@ -0,0 +1 @@
+7d7533129e5e7faaf06cad184cd1a3a46a35de1c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1
new file mode 100644
index 0000000..acecd83
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1
@@ -0,0 +1 @@
+aefddc2ca85392563aac0b8b121109b4bb8983b4
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1
new file mode 100644
index 0000000..738a73b9
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1
@@ -0,0 +1 @@
+9db679e9293cdc7b8abe42195e49f6ef183348cf
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1
new file mode 100644
index 0000000..4107492
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1
@@ -0,0 +1 @@
+2242a9208af02e6f0ca4e650c967b96df8e08a54
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1
new file mode 100644
index 0000000..a479520
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1
@@ -0,0 +1 @@
+3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1
new file mode 100644
index 0000000..9b04a8c
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1
@@ -0,0 +1 @@
+7d7533129e5e7faaf06cad184cd1a3a46a35de1c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1
new file mode 100644
index 0000000..d8404e83
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1
@@ -0,0 +1 @@
+9a83acb21eb6287fbeb691f10de7efc85f930bc3
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1
new file mode 100644
index 0000000..d9cfd8e
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1
@@ -0,0 +1 @@
+03f218e3948a30a60e0f5a67ce91c77b9bc0c782
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1
new file mode 100644
index 0000000..d81e1ff9
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1
@@ -0,0 +1 @@
+6f2741643cb6879b42ae222a728c84d4148f568d
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1
new file mode 100644
index 0000000..c1bcfb9a
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1
@@ -0,0 +1 @@
+4f599c7f3dbb17f3c40cbeba78cfb2841fd033ce
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1
index 86cb60c..d80a79c7 100644
--- a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1
@@ -1 +1 @@
-4716f0245f707b5e8f26d23e72273beb4d95d0fa
\ No newline at end of file
+ec79cd1e1022c32bd901b6713d9cd646633b1c18
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1
new file mode 100644
index 0000000..f847279aa
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1
@@ -0,0 +1 @@
+b805bebaa5a201834cf3c5086cc5a6cdea9cc951
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1
new file mode 100644
index 0000000..f847279aa
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1
@@ -0,0 +1 @@
+b805bebaa5a201834cf3c5086cc5a6cdea9cc951
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1
new file mode 100644
index 0000000..f847279aa
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1
@@ -0,0 +1 @@
+b805bebaa5a201834cf3c5086cc5a6cdea9cc951
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1
new file mode 100644
index 0000000..f24af764
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1
@@ -0,0 +1 @@
+c2f8891aa44d1e6a1ad8602945a76d7ef619994d
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1
new file mode 100644
index 0000000..afe3dbf9
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1
@@ -0,0 +1 @@
+a91f660cf6938db71beec1287af71e3de44c9a8e
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1
new file mode 100644
index 0000000..d80a79c7
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1
@@ -0,0 +1 @@
+ec79cd1e1022c32bd901b6713d9cd646633b1c18
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1
new file mode 100644
index 0000000..c9648a0
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1
@@ -0,0 +1 @@
+cedfb58841265e3a1582ce49dc09bfe2edd81b99
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1
new file mode 100644
index 0000000..22144c90
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1
@@ -0,0 +1 @@
+9b6af533672c540f591bc088bfd73c93ad244ba9
\ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp
index e5183b54..41ca89eb 100644
--- a/chrome/app/os_settings_search_tag_strings.grdp
+++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -1150,6 +1150,9 @@
   <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_PREDICTIVE_WRITING_ALT2" desc="Text for search result item which, when clicked, navigates the user to suggestions settings, with a section having a toggle to enable/disable showing predictive writing suggestions after a user types a word.">
     Next word prediction
   </message>
+  <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES" desc="Text for search result item which, when clicked, navigates the user to app language settings, with a list of apps which language can be customized.">
+    App languages
+  </message>
 
   <!-- Files section. -->
   <message name="IDS_OS_SETTINGS_TAG_FILES" desc="Text for search result item which, when clicked, navigates the user to files settings.">
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1
new file mode 100644
index 0000000..e3381f3
--- /dev/null
+++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1
@@ -0,0 +1 @@
+53a6cbbca23b8f15e287998723c8e81f704a0403
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 9606430..73cfd680 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -5768,6 +5768,10 @@
     {"files-trash-drive", flag_descriptions::kFilesTrashDriveName,
      flag_descriptions::kFilesTrashDriveDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kFilesTrashDrive)},
+    {"file-system-provider-content-cache",
+     flag_descriptions::kFileSystemProviderContentCacheName,
+     flag_descriptions::kFileSystemProviderContentCacheDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kFileSystemProviderContentCache)},
     {"force-resync-drive", flag_descriptions::kForceReSyncDriveName,
      flag_descriptions::kForceReSyncDriveDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kForceReSyncDrive)},
diff --git a/chrome/browser/ash/app_list/app_list_client_impl.cc b/chrome/browser/ash/app_list/app_list_client_impl.cc
index 40b504d..69eef55af 100644
--- a/chrome/browser/ash/app_list/app_list_client_impl.cc
+++ b/chrome/browser/ash/app_list/app_list_client_impl.cc
@@ -14,7 +14,6 @@
 #include "ash/public/cpp/app_list/app_list_controller.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "ash/public/cpp/new_window_delegate.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/shell.h"
 #include "ash/system/federated/federated_service_controller_impl.h"
 #include "base/feature_list.h"
@@ -73,10 +72,6 @@
 constexpr base::TimeDelta kTimeMetricsMax = base::Days(7);
 constexpr int kTimeMetricsBucketCount = 100;
 
-bool IsTabletMode() {
-  return ash::TabletMode::IsInTabletMode();
-}
-
 // Returns whether the session is active.
 bool IsSessionActive() {
   return session_manager::SessionManager::Get()->session_state() ==
@@ -167,7 +162,7 @@
 
     // Prefer the function to the macro because the usage data is recorded no
     // more than once per second.
-    if (IsTabletMode()) {
+    if (display::Screen::GetScreen()->InTabletMode()) {
       base::UmaHistogramEnumeration(
           "Apps.AppListUsageByNewUsers.TabletMode",
           AppListUsageStateByNewUsers::kNotUsedBeforeDestruction);
@@ -220,7 +215,8 @@
       if (!state_for_new_user_->first_search_result_recorded &&
           state_for_new_user_->started_search && trimmed_query.empty()) {
         state_for_new_user_->first_search_result_recorded = true;
-        RecordFirstSearchResult(ash::NO_RESULT, IsTabletMode());
+        RecordFirstSearchResult(ash::NO_RESULT,
+                                display::Screen::GetScreen()->InTabletMode());
       } else if (!trimmed_query.empty()) {
         state_for_new_user_->started_search = true;
       }
@@ -278,7 +274,7 @@
   }
 
   if (launched_from == ash::AppListLaunchedFrom::kLaunchedFromSearchBox) {
-    if (IsTabletMode()) {
+    if (display::Screen::GetScreen()->InTabletMode()) {
       base::UmaHistogramCounts100("Apps.AppListSearchQueryLengthV2.TabletMode",
                                   last_query_length);
     } else {
@@ -294,8 +290,9 @@
       result->display_type(),
       ash::AppListNotifier::Result(result_id, result->metrics_type()));
 
-  RecordSearchResultOpenTypeHistogram(launched_from, result->metrics_type(),
-                                      IsTabletMode());
+  RecordSearchResultOpenTypeHistogram(
+      launched_from, result->metrics_type(),
+      display::Screen::GetScreen()->InTabletMode());
 
   if (launch_as_default) {
     RecordDefaultSearchResultOpenTypeHistogram(result->metrics_type());
@@ -315,7 +312,8 @@
   if (state_for_new_user_ && state_for_new_user_->started_search &&
       !state_for_new_user_->first_search_result_recorded) {
     state_for_new_user_->first_search_result_recorded = true;
-    RecordFirstSearchResult(result->metrics_type(), IsTabletMode());
+    RecordFirstSearchResult(result->metrics_type(),
+                            display::Screen::GetScreen()->InTabletMode());
   }
 
   // OpenResult may cause |result| to be deleted.
@@ -438,7 +436,8 @@
     if (state_for_new_user_ && state_for_new_user_->started_search &&
         !state_for_new_user_->first_search_result_recorded) {
       state_for_new_user_->first_search_result_recorded = true;
-      RecordFirstSearchResult(ash::NO_RESULT, IsTabletMode());
+      RecordFirstSearchResult(ash::NO_RESULT,
+                              display::Screen::GetScreen()->InTabletMode());
     }
   }
 }
@@ -469,7 +468,7 @@
     if (!state_for_new_user_->showing_recorded) {
       // We assume that the previous user before switching was new if
       // `state_for_new_user_` is not null.
-      if (IsTabletMode()) {
+      if (display::Screen::GetScreen()->InTabletMode()) {
         base::UmaHistogramEnumeration(
             "Apps.AppListUsageByNewUsers.TabletMode",
             AppListUsageStateByNewUsers::kNotUsedBeforeSwitchingAccounts);
@@ -795,7 +794,8 @@
   }
 
   state_for_new_user_->showing_recorded = true;
-  state_for_new_user_->shown_in_tablet_mode = IsTabletMode();
+  state_for_new_user_->shown_in_tablet_mode =
+      display::Screen::GetScreen()->InTabletMode();
 
   CHECK(new_user_session_activation_time_.has_value());
   const base::TimeDelta opening_duration =
@@ -879,7 +879,7 @@
   }
 
   state_for_new_user_->action_recorded = true;
-  if (IsTabletMode()) {
+  if (display::Screen::GetScreen()->InTabletMode()) {
     base::UmaHistogramEnumeration("Apps.NewUserFirstLauncherAction.TabletMode",
                                   launched_from);
   } else {
@@ -893,7 +893,7 @@
   if (launcher_action_duration >= base::TimeDelta()) {
     // `base::Time` may skew. Therefore only record when the time duration is
     // non-negative.
-    if (IsTabletMode()) {
+    if (display::Screen::GetScreen()->InTabletMode()) {
       UMA_HISTOGRAM_CUSTOM_TIMES(
           /*name=*/
           "Apps.TimeBetweenNewUserSessionActivationAndFirstLauncherAction."
diff --git a/chrome/browser/ash/app_list/app_list_sort_unittest.cc b/chrome/browser/ash/app_list/app_list_sort_unittest.cc
index 2e18512..b99e794 100644
--- a/chrome/browser/ash/app_list/app_list_sort_unittest.cc
+++ b/chrome/browser/ash/app_list/app_list_sort_unittest.cc
@@ -14,6 +14,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/crx_file/id_util.h"
 #include "components/sync/test/fake_sync_change_processor.h"
+#include "ui/display/test/test_screen.h"
 
 namespace app_list {
 
@@ -61,6 +62,8 @@
   }
 
  private:
+  display::test::TestScreen test_screen_{/*create_dispay=*/true,
+                                         /*register_screen=*/true};
   std::unique_ptr<test::TestAppListController> app_list_controller_;
 };
 
diff --git a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc
index e922af6..3163c67b 100644
--- a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc
@@ -14,7 +14,6 @@
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "ash/public/cpp/app_list/app_list_controller.h"
 #include "ash/public/cpp/app_list/app_list_metrics.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/strings/utf_string_conversions.h"
@@ -32,6 +31,7 @@
 #include "components/feature_engagement/public/tracker.h"
 #include "extensions/common/constants.h"
 #include "ui/base/models/menu_model.h"
+#include "ui/display/screen.h"
 
 namespace {
 
@@ -1268,9 +1268,8 @@
 
   order_delegate_->SetAppListPreferredOrder(ash::AppListSortOrder::kCustom);
 
-  // The tablet mode controller may not exist in tests.
-  if (ash::TabletMode::Get())
-    ReportPrefOrderClearAction(event, ash::TabletMode::Get()->IsInTabletMode());
+  ReportPrefOrderClearAction(event,
+                             display::Screen::GetScreen()->InTabletMode());
 }
 
 void ChromeAppListModelUpdater::MaybeUpdatePositionWhenIconColorChange(
diff --git a/chrome/browser/ash/arc/window_predictor/window_predictor.cc b/chrome/browser/ash/arc/window_predictor/window_predictor.cc
index 6935881..e9ddfdf 100644
--- a/chrome/browser/ash/arc/window_predictor/window_predictor.cc
+++ b/chrome/browser/ash/arc/window_predictor/window_predictor.cc
@@ -149,7 +149,7 @@
         window_info->display_id, &disp);
   }
 
-  if (ash::TabletMode::Get()->IsInTabletMode()) {
+  if (display::Screen::GetScreen()->InTabletMode()) {
     // TODO: Figure out why setting kMaximized doesn't work.
     window_info->state =
         static_cast<int32_t>(chromeos::WindowStateType::kDefault);
diff --git a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc
index 94d39a4e..ad2bfa5 100644
--- a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc
+++ b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc
@@ -97,11 +97,8 @@
       views::LayoutAlignment::kCenter);
   candidate_wrapper_layout->SetMainAxisAlignment(
       views::LayoutAlignment::kCenter);
-  candidate_wrapper->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
-                               views::MaximumFlexSizeRule::kUnbounded, false)
-          .WithAlignment(views::LayoutAlignment::kCenter));
+  candidate_wrapper->SetProperty(views::kBoxLayoutFlexKey,
+                                 views::BoxLayoutFlexSpecification());
   candidate_wrapper->SetPreferredSize(
       gfx::Size(kCandidateSquareSide, kCandidateSquareSide));
   candidate_wrapper->AddChildView(
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc
index c86c5f7f..35d0288 100644
--- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc
+++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -16,7 +16,6 @@
 #include "ash/constants/ash_features.h"
 #include "ash/controls/contextual_tooltip.h"
 #include "ash/public/cpp/image_util.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/wallpaper/google_photos_wallpaper_params.h"
 #include "ash/public/cpp/wallpaper/online_wallpaper_params.h"
 #include "ash/public/cpp/wallpaper/online_wallpaper_variant.h"
@@ -62,6 +61,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/aura/window.h"
 #include "ui/base/webui/web_ui_util.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/codec/jpeg_codec.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image.h"
@@ -777,7 +777,7 @@
 
 void PersonalizationAppWallpaperProviderImpl::IsInTabletMode(
     IsInTabletModeCallback callback) {
-  std::move(callback).Run(ash::TabletMode::IsInTabletMode());
+  std::move(callback).Run(display::Screen::GetScreen()->InTabletMode());
 }
 
 void PersonalizationAppWallpaperProviderImpl::ConfirmPreviewWallpaper() {
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc
index 991208c..bfe757c1 100644
--- a/chrome/browser/autofill/autofill_server_browsertest.cc
+++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -242,9 +242,9 @@
   std::string data_present;
   if (base::FeatureList::IsEnabled(
           features::kAutofillEnableSupportForHonorificPrefixes)) {
-    data_present = "1f7e0003f80000080004000001c424180002";
+    data_present = "1f7e0003f80000080004000001c424780002";
   } else {
-    data_present = "1f7e0003f80000080004000001c420180002";
+    data_present = "1f7e0003f80000080004000001c420780002";
   }
 
   // TODO(crbug.com/1311937): Additional phone number trunk types are present
@@ -255,8 +255,6 @@
     data_present.rbegin()[5] = '7';
   }
   upload->set_data_present(data_present);
-
-  upload->set_passwords_revealed(false);
   upload->set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_HTML_FORM_SUBMISSION);
   upload->set_has_form_tag(true);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index eeeab70..4d9d5994 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5412,24 +5412,6 @@
 #endif
 }
 
-void ChromeContentBrowserClient::OverridePageVisibilityState(
-    RenderFrameHost* render_frame_host,
-    content::PageVisibilityState* visibility_state) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  WebContents* web_contents =
-      WebContents::FromRenderFrameHost(render_frame_host);
-  DCHECK(web_contents);
-
-  prerender::NoStatePrefetchManager* no_state_prefetch_manager =
-      prerender::NoStatePrefetchManagerFactory::GetForBrowserContext(
-          web_contents->GetBrowserContext());
-  if (no_state_prefetch_manager &&
-      no_state_prefetch_manager->IsWebContentsPrefetching(web_contents)) {
-    *visibility_state = content::PageVisibilityState::kHidden;
-  }
-}
-
 void ChromeContentBrowserClient::InitOnUIThread() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index efc041c..1d2098c5 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -492,9 +492,6 @@
   bool IsPluginAllowedToUseDevChannelAPIs(
       content::BrowserContext* browser_context,
       const GURL& url) override;
-  void OverridePageVisibilityState(
-      content::RenderFrameHost* render_frame_host,
-      content::PageVisibilityState* visibility_state) override;
 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
   void GetAdditionalMappedFilesForChildProcess(
       const base::CommandLine& command_line,
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
index 8ea70a5..4123228 100644
--- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
+++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -15,6 +15,7 @@
 #include "ash/public/cpp/keyboard/keyboard_types.h"
 #include "ash/webui/settings/public/constants/routes.mojom-forward.h"
 #include "base/check.h"
+#include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/metrics/user_metrics.h"
@@ -27,6 +28,7 @@
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
+#include "chromeos/services/machine_learning/public/cpp/ml_switches.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/audio_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -174,6 +176,33 @@
   return router;
 }
 
+// Returns whether the `ondevice_handwriting` USE flag has been set.
+// Adapted from
+// `//chromeos/services/machine_learning/cpp/ash/handwriting_model_loader.cc`.
+// This flag is set from the CrOS side in
+// https://crsrc.org/o/src/platform2/login_manager/chrome_setup.cc;l=1014;drc=e44a81d180823c2a0758c52f0520862d0545b98d
+bool IsOndeviceHandwritingEnabledViaCommandLine() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  return command_line->HasSwitch(::switches::kOndeviceHandwritingSwitch) &&
+         command_line->GetSwitchValueASCII(
+             ::switches::kOndeviceHandwritingSwitch) == "use_rootfs";
+}
+
+bool IsHandwritingLegacyRecognitionEnabled() {
+  // Disable handwriting DLC flags if device does not have on-device handwriting
+  // (see b/316981973).
+  return IsOndeviceHandwritingEnabledViaCommandLine() &&
+         base::FeatureList::IsEnabled(
+             ash::features::kHandwritingLegacyRecognition);
+}
+
+bool IsHandwritingLibraryDlcEnabled() {
+  // Disable handwriting DLC flags if device does not have on-device handwriting
+  // (see b/316981973).
+  return IsOndeviceHandwritingEnabledViaCommandLine() &&
+         base::FeatureList::IsEnabled(ash::features::kHandwritingLibraryDlc);
+}
+
 }  // namespace
 
 namespace extensions {
@@ -498,10 +527,8 @@
   features.Append(GenerateFeatureFlag(
       "handwritinggesture",
       base::FeatureList::IsEnabled(features::kHandwritingGesture)));
-  features.Append(
-      GenerateFeatureFlag("handwritinglegacyrecognition",
-                          base::FeatureList::IsEnabled(
-                              ash::features::kHandwritingLegacyRecognition)));
+  features.Append(GenerateFeatureFlag("handwritinglegacyrecognition",
+                                      IsHandwritingLegacyRecognitionEnabled()));
   features.Append(GenerateFeatureFlag(
       "hindiinscriptlayout",
       base::FeatureList::IsEnabled(ash::features::kHindiInscriptLayout)));
@@ -527,9 +554,8 @@
   features.Append(GenerateFeatureFlag(
       "autocorrectparamstuning",
       base::FeatureList::IsEnabled(ash::features::kAutocorrectParamsTuning)));
-  features.Append(GenerateFeatureFlag(
-      "handwritinglibrarydlc",
-      base::FeatureList::IsEnabled(ash::features::kHandwritingLibraryDlc)));
+  features.Append(GenerateFeatureFlag("handwritinglibrarydlc",
+                                      IsHandwritingLibraryDlcEnabled()));
   features.Append(
       GenerateFeatureFlag("jelly", chromeos::features::IsJellyEnabled()));
   features.Append(GenerateFeatureFlag(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 52fe2ae..480875af 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4243,6 +4243,11 @@
     "expiry_milestone": 123
   },
   {
+    "name": "file-system-provider-content-cache",
+    "owners": [ "benreich@chromium.org", "cassycc@chromium.org", "simmonsjosh@google.com" ],
+    "expiry_milestone": 130
+  },
+  {
     "name": "file-transfer-enterprise-connector",
     "owners": [ "sseckler@google.com", "marcgrimme@chromium.org", "poromov@chromium.org" ],
     "expiry_milestone": 130
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index a35c252..20a40658 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -6374,6 +6374,12 @@
 const char kFilesTrashDriveDescription[] =
     "Enable trash for Drive volume in Files App.";
 
+const char kFileSystemProviderContentCacheName[] =
+    "Enable content caching for FileSystemProvider extensions.";
+const char kFileSystemProviderContentCacheDescription[] =
+    "Enable the ability for individual FileSystemProvider extensions to "
+    "leverage a content cache.";
+
 const char kFilesGoogleDriveSettingsPageName[] =
     "Enable Google Drive settings page";
 const char kFilesGoogleDriveSettingsPageDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 852fcb3..c0b4654 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3662,6 +3662,9 @@
 extern const char kFilesTrashDriveName[];
 extern const char kFilesTrashDriveDescription[];
 
+extern const char kFileSystemProviderContentCacheName[];
+extern const char kFileSystemProviderContentCacheDescription[];
+
 extern const char kFilesGoogleDriveSettingsPageName[];
 extern const char kFilesGoogleDriveSettingsPageDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 1aefac8b..a6c028d 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -247,14 +247,10 @@
     &kRequestDesktopSiteDefaultsControlCohort2,
     &kRequestDesktopSiteDefaultsControlCohort3,
     &kRequestDesktopSiteDefaultsControlCohort4,
-    &kRequestDesktopSiteDefaultsControlSynthetic,
     &kRequestDesktopSiteDefaultsEnabledCohort1,
     &kRequestDesktopSiteDefaultsEnabledCohort2,
     &kRequestDesktopSiteDefaultsEnabledCohort3,
     &kRequestDesktopSiteDefaultsEnabledCohort4,
-    &kRequestDesktopSiteDefaultsSynthetic,
-    &kRequestDesktopSiteOptInControlSynthetic,
-    &kRequestDesktopSiteOptInSynthetic,
     &kRequestDesktopSiteDefaultsDowngrade,
     &kRequestDesktopSiteDefaultsLogging,
     &kRestoreTabsOnFRE,
@@ -756,10 +752,6 @@
              "RequestDesktopSiteDefaultsControlCohort4",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-BASE_FEATURE(kRequestDesktopSiteDefaultsControlSynthetic,
-             "RequestDesktopSiteDefaultsControlSynthetic",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 BASE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort1,
              "RequestDesktopSiteDefaultsEnabledCohort1",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -776,18 +768,6 @@
              "RequestDesktopSiteDefaultsEnabledCohort4",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-BASE_FEATURE(kRequestDesktopSiteDefaultsSynthetic,
-             "RequestDesktopSiteDefaultsSynthetic",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kRequestDesktopSiteOptInControlSynthetic,
-             "RequestDesktopSiteOptInControlSynthetic",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kRequestDesktopSiteOptInSynthetic,
-             "RequestDesktopSiteOptInSynthetic",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 BASE_FEATURE(kRequestDesktopSiteDefaultsDowngrade,
              "RequestDesktopSiteDefaultsDowngrade",
              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 57730cd..afa0fe4 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -124,14 +124,10 @@
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort2);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort3);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort4);
-BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlSynthetic);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort1);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort2);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort3);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort4);
-BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsSynthetic);
-BASE_DECLARE_FEATURE(kRequestDesktopSiteOptInControlSynthetic);
-BASE_DECLARE_FEATURE(kRequestDesktopSiteOptInSynthetic);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsDowngrade);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsLogging);
 BASE_DECLARE_FEATURE(kRestoreTabsOnFRE);
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 6a54432..f563b457 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
@@ -361,18 +361,10 @@
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS = "RequestDesktopSiteDefaults";
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL =
             "RequestDesktopSiteDefaultsControl";
-    public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL_SYNTHETIC =
-            "RequestDesktopSiteDefaultsControlSynthetic";
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS_DOWNGRADE =
             "RequestDesktopSiteDefaultsDowngrade";
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS_LOGGING =
             "RequestDesktopSiteDefaultsLogging";
-    public static final String REQUEST_DESKTOP_SITE_DEFAULTS_SYNTHETIC =
-            "RequestDesktopSiteDefaultsSynthetic";
-    public static final String REQUEST_DESKTOP_SITE_OPT_IN_CONTROL_SYNTHETIC =
-            "RequestDesktopSiteOptInControlSynthetic";
-    public static final String REQUEST_DESKTOP_SITE_OPT_IN_SYNTHETIC =
-            "RequestDesktopSiteOptInSynthetic";
     public static final String SAFE_BROWSING_DELAYED_WARNINGS = "SafeBrowsingDelayedWarnings";
     public static final String SAFE_BROWSING_NEW_GMS_API_FOR_BROWSE_URL_DATABASE_CHECK =
             "SafeBrowsingNewGmsApiForBrowseUrlDatabaseCheck";
diff --git a/chrome/browser/lacros/input_method_lacros_browsertest.cc b/chrome/browser/lacros/input_method_lacros_browsertest.cc
index df04496..e65e823 100644
--- a/chrome/browser/lacros/input_method_lacros_browsertest.cc
+++ b/chrome/browser/lacros/input_method_lacros_browsertest.cc
@@ -101,6 +101,9 @@
           ->GetNativeWindow()
           ->GetRootWindow());
   EXPECT_TRUE(browser_test_util::WaitForWindowCreation(window_id));
+  EXPECT_TRUE(BrowserView::GetBrowserViewForBrowser(browser)
+                  ->contents_web_view()
+                  ->HasFocus());
   return true;
 }
 
@@ -581,12 +584,14 @@
 
 IN_PROC_BROWSER_TEST_P(InputMethodLacrosBrowserTest,
                        CommitTextUpdatesSurroundingText) {
+  const std::string id = RenderAutofocusedInputFieldInLacros(browser());
+
   mojo::Remote<InputMethodTestInterface> input_method =
       BindInputMethodTestInterface(GetParam());
   if (!input_method.is_bound()) {
     GTEST_SKIP() << "Unsupported ash version";
   }
-  const std::string id = RenderAutofocusedInputFieldInLacros(browser());
+
   InputMethodTestInterfaceAsyncWaiter input_method_async_waiter(
       input_method.get());
   input_method_async_waiter.WaitForFocus();
@@ -874,15 +879,16 @@
   EXPECT_FALSE(event_listener.HasMessages());
 }
 
-// TODO(crbug.com/1510768): Reenable once fixed.
 IN_PROC_BROWSER_TEST_P(InputMethodLacrosBrowserTest,
-                       DISABLED_SetCompositionUpdatesSurroundingText) {
+                       SetCompositionUpdatesSurroundingText) {
+  const std::string id = RenderAutofocusedInputFieldInLacros(browser());
+
   mojo::Remote<InputMethodTestInterface> input_method =
       BindInputMethodTestInterface(GetParam());
   if (!input_method.is_bound()) {
     GTEST_SKIP() << "Unsupported ash version";
   }
-  const std::string id = RenderAutofocusedInputFieldInLacros(browser());
+
   InputMethodTestInterfaceAsyncWaiter input_method_async_waiter(
       input_method.get());
   input_method_async_waiter.WaitForFocus();
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
index 2113fc05..7f9b501d 100644
--- a/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
+++ b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
@@ -105,6 +105,15 @@
            {tpcd::experiment::kForceEligibleForTestingName, "true"}}};
 }
 
+base::test::FeatureRefAndParams ControlFeaturesWithSilentOnboarding() {
+  return {features::kCookieDeprecationFacilitatedTesting,
+          {
+              {tpcd::experiment::kDisable3PCookiesName, "false"},
+              {tpcd::experiment::kForceEligibleForTestingName, "true"},
+              {tpcd::experiment::kEnableSilentOnboardingName, "true"},
+          }};
+}
+
 std::vector<base::test::FeatureRefAndParams> HatsImmediateControlFeatures() {
   return {
       ControlFeatures(),
@@ -114,6 +123,16 @@
         {"tracking-protection-control-immediate-trigger-id", "trigger-1"}}}};
 }
 
+std::vector<base::test::FeatureRefAndParams>
+HatsImmediateControlFeaturesWithSilentOnboarding() {
+  return {
+      ControlFeaturesWithSilentOnboarding(),
+      {features::kTrackingProtectionSentimentSurvey,
+       {{"tracking-protection-immediate-over-delayed-probability", "1"},
+        {"tracking-protection-control-immediate-probability", "1.0"},
+        {"tracking-protection-control-immediate-trigger-id", "trigger-1"}}}};
+}
+
 std::vector<base::test::FeatureRefAndParams> HatsDelayedControlFeatures() {
   return {ControlFeatures(),
           {features::kTrackingProtectionSentimentSurvey,
@@ -1134,6 +1153,7 @@
   bool has_topics_enabled = false;
   bool has_fledge_enabled = false;
   bool has_measurement_enabled = false;
+  std::optional<bool> should_silently_onboard = std::nullopt;
   std::optional<NoticeAction> ack_action = std::nullopt;
   base::TimeDelta to_start_survey;
   base::TimeDelta after_end_of_survey;
@@ -1222,6 +1242,14 @@
       prefs::kPrivacySandboxM1AdMeasurementEnabled,
       params.has_measurement_enabled);
 
+  if (params.should_silently_onboard) {
+    {
+      base::subtle::ScopedTimeClockOverrides override([]() { return Now(); },
+                                                      nullptr, nullptr);
+      onboarding_service()->MaybeMarkSilentEligible();
+      onboarding_service()->SilentOnboardingNoticeShown();
+    }
+  }
   // Ack if necessary.
   if (params.ack_action.has_value()) {
     // Onboarding first
@@ -1347,6 +1375,19 @@
             .trigger_id = kHatsSurveyTriggerTrackingProtectionControlImmediate,
             .group = SentimentSurveyGroup::kControlImmediate,
         },
+        // Immediate Control with silent onbaording. No Ads API Enabled
+        TrackingProtectionSurveyTestData{
+            .features = HatsImmediateControlFeaturesWithSilentOnboarding(),
+            .has_cookie_controls_3pc_blocked = true,
+            .has_topics_enabled = false,
+            .has_fledge_enabled = false,
+            .has_measurement_enabled = false,
+            .should_silently_onboard = true,
+            .to_start_survey = base::Minutes(5),
+            .after_end_of_survey = base::Minutes(65),
+            .trigger_id = kHatsSurveyTriggerTrackingProtectionControlImmediate,
+            .group = SentimentSurveyGroup::kControlImmediate,
+        },
         // Delayed Control No Ads API Enabled
         TrackingProtectionSurveyTestData{
             .features = HatsDelayedControlFeatures(),
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc b/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc
index 58a59389..6674ba15 100644
--- a/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc
+++ b/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc
@@ -7,6 +7,7 @@
 #include "base/no_destructor.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_selections.h"
+#include "chrome/browser/tpcd/experiment/tpcd_experiment_features.h"
 #include "chrome/common/channel_info.h"
 
 TrackingProtectionOnboardingFactory*
@@ -35,5 +36,6 @@
   Profile* profile = Profile::FromBrowserContext(context);
 
   return std::make_unique<privacy_sandbox::TrackingProtectionOnboarding>(
-      profile->GetPrefs(), chrome::GetChannel());
+      profile->GetPrefs(), chrome::GetChannel(),
+      tpcd::experiment::kEnableSilentOnboarding.Get());
 }
diff --git a/chrome/browser/resources/ash/settings/device_page/audio.html b/chrome/browser/resources/ash/settings/device_page/audio.html
index 6dde84f..8b0c63e 100644
--- a/chrome/browser/resources/ash/settings/device_page/audio.html
+++ b/chrome/browser/resources/ash/settings/device_page/audio.html
@@ -199,7 +199,8 @@
       </div>
       <cr-toggle id="audioInputNoiseCancellationToggle"
           checked="{{isNoiseCancellationEnabled_}}"
-          aria-labelledby="audioInputNoiseCancellationLabel">
+          aria-labelledby="audioInputNoiseCancellationLabel"
+          on-change="toggleNoiseCancellationEnabled_">
       </cr-toggle>
     </div>
     <div id="audioInputAllowAGCSubsection" class="settings-box"
diff --git a/chrome/browser/resources/ash/settings/device_page/audio.ts b/chrome/browser/resources/ash/settings/device_page/audio.ts
index 40004b0..89a0ff0 100644
--- a/chrome/browser/resources/ash/settings/device_page/audio.ts
+++ b/chrome/browser/resources/ash/settings/device_page/audio.ts
@@ -77,8 +77,6 @@
 
       isNoiseCancellationEnabled_: {
         type: Boolean,
-        observer:
-            SettingsAudioElement.prototype.onNoiseCancellationEnabledChanged,
       },
 
       isNoiseCancellationSupported_: {
@@ -228,22 +226,6 @@
     this.crosAudioConfig_.setActiveDevice(BigInt(inputDeviceSelect.value));
   }
 
-  /** Handles updates to noise cancellation state. */
-  protected onNoiseCancellationEnabledChanged(
-      enabled: SettingsAudioElement['isNoiseCancellationEnabled_'],
-      previousEnabled: SettingsAudioElement['isNoiseCancellationEnabled_']):
-      void {
-    // Polymer triggers change event on all assignment to
-    // `isNoiseCancellationEnabled_` even if the value is logically unchanged.
-    // Check previous value before calling `setNoiseCancellationEnabled` to test
-    // if value actually updated.
-    if (previousEnabled === undefined || previousEnabled === enabled) {
-      return;
-    }
-
-    this.crosAudioConfig_.setNoiseCancellationEnabled(enabled);
-  }
-
   /** Handles updates to force respect ui gains state. */
   protected onAllowAGCEnabledChanged(
       enabled: SettingsAudioElement['isAllowAGCEnabled'],
@@ -417,6 +399,10 @@
         this.i18n('audioOutputMuteButtonAriaLabelNotMuted');
   }
 
+  private toggleNoiseCancellationEnabled_(e: CustomEvent<boolean>): void {
+    this.crosAudioConfig_.setNoiseCancellationEnabled(e.detail);
+  }
+
   private toggleStartupSoundEnabled_(e: CustomEvent<boolean>): void {
     this.audioAndCaptionsBrowserProxy_.setStartupSoundEnabled(e.detail);
   }
diff --git a/chrome/browser/resources/ash/settings/device_page/display.html b/chrome/browser/resources/ash/settings/device_page/display.html
index 6b879454..7932649 100644
--- a/chrome/browser/resources/ash/settings/device_page/display.html
+++ b/chrome/browser/resources/ash/settings/device_page/display.html
@@ -76,8 +76,7 @@
     <template is="dom-if"
         if="[[showMirror(unifiedDesktopMode_, displays)]]" restamp>
       <!-- Mirror display toggle button -->
-      <template is="dom-if"
-          if="[[isRevampWayfindingEnabled_]]" restamp>
+      <template is="dom-if" if="[[isRevampWayfindingEnabled_]]">
         <div id="mirrorDisplayToggleButton" class="text-area">
           <div id="mirrorDisplayToggleLabel" class="start">
             [[getDisplayMirrorText_(displays)]]
@@ -92,8 +91,7 @@
       </template>
 
       <!-- Mirror display checkbox -->
-      <template is="dom-if"
-          if="[[!isRevampWayfindingEnabled_]]" restamp>
+      <template is="dom-if" if="[[!isRevampWayfindingEnabled_]]">
         <div class="secondary self-start">
           <cr-checkbox id="displayMirrorCheckbox"
               checked="[[isMirrored(displays)]]"
diff --git a/chrome/browser/resources/ash/settings/device_page/display.ts b/chrome/browser/resources/ash/settings/device_page/display.ts
index e874731..cfdc19b8 100644
--- a/chrome/browser/resources/ash/settings/device_page/display.ts
+++ b/chrome/browser/resources/ash/settings/device_page/display.ts
@@ -92,6 +92,7 @@
         value: () => {
           return isRevampWayfindingEnabled();
         },
+        readOnly: true,
       },
 
       selectedModePref_: {
@@ -262,7 +263,7 @@
   private displaySettingsProvider: DisplaySettingsProviderInterface;
   private displayTabNames_: string[];
   private invalidDisplayId_: string;
-  private isRevampWayfindingEnabled_: boolean;
+  private readonly isRevampWayfindingEnabled_: boolean;
   private isTabletMode_: boolean;
   private listAllDisplayModes_: boolean;
   private logicalResolutionText_: string;
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts
index d76ff8f..3ad9367 100644
--- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts
+++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts
@@ -38,7 +38,7 @@
 import {RouteObserverMixin} from '../common/route_observer_mixin.js';
 import {recordSettingChange} from '../metrics_recorder.js';
 import {Setting} from '../mojom-webui/setting.mojom-webui.js';
-import {Route, routes} from '../router.js';
+import {Route, Router, routes} from '../router.js';
 
 import {LanguagesMetricsProxyImpl, LanguagesPageInteraction} from './languages_metrics_proxy.js';
 import {LanguageHelper, LanguagesModel, LanguageState} from './languages_types.js';
@@ -199,7 +199,7 @@
    * Navigates to app languages subpage.
    */
   private onAppLanguagesClick_(): void {
-    // TODO(b/261200827): Route to App Languages page.
+    Router.getInstance().navigateTo(routes.OS_LANGUAGES_APP_LANGUAGES);
   }
 
   /**
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
index 6af5919..b6058b3 100644
--- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
+++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
@@ -21,6 +21,14 @@
     </os-settings-subpage>
   </template>
 
+  <!-- "App Languages" sub-page. -->
+  <template is="dom-if" route-path="/osLanguages/languages/appLanguages">
+    <os-settings-subpage page-title="$i18n{appLanguagesTitle}">
+      <os-settings-app-languages-page prefs="{{prefs}}">
+      </os-settings-app-languages-page>
+    </os-settings-subpage>
+  </template>
+
   <!-- "Input" page. -->
   <template is="dom-if" route-path="/osLanguages/input">
     <os-settings-subpage page-title="$i18n{inputPageTitle}">
diff --git a/chrome/browser/resources/ash/settings/os_settings_routes.ts b/chrome/browser/resources/ash/settings/os_settings_routes.ts
index 853f8f0..af1691c 100644
--- a/chrome/browser/resources/ash/settings/os_settings_routes.ts
+++ b/chrome/browser/resources/ash/settings/os_settings_routes.ts
@@ -184,6 +184,7 @@
   ONE_DRIVE: Route;
   OS_ACCESSIBILITY: Route;
   OS_LANGUAGES: Route;
+  OS_LANGUAGES_APP_LANGUAGES: Route;
   OS_LANGUAGES_EDIT_DICTIONARY: Route;
   OS_LANGUAGES_JAPANESE_MANAGE_USER_DICTIONARY: Route;
   OS_LANGUAGES_INPUT: Route;
@@ -556,6 +557,11 @@
     r.OS_LANGUAGES_LANGUAGES = createSubpage(
         r.SYSTEM_PREFERENCES, routesMojom.LANGUAGES_SUBPAGE_PATH,
         Subpage.kLanguages);
+    if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) {
+      r.OS_LANGUAGES_APP_LANGUAGES = createSubpage(
+          r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH,
+          Subpage.kAppLanguages);
+    }
 
     // Search and Assistant subpages.
     r.SEARCH_SUBPAGE = createSubpage(
@@ -657,6 +663,11 @@
         r.OS_LANGUAGES_INPUT,
         routesMojom.JAPANESE_MANAGE_USER_DICTIONARY_SUBPAGE_PATH,
         Subpage.kJapaneseManageUserDictionary);
+    if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) {
+      r.OS_LANGUAGES_APP_LANGUAGES = createSubpage(
+          r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH,
+          Subpage.kAppLanguages);
+    }
 
     // Reset section.
     if (isPowerwashAllowed()) {
diff --git a/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html b/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html
index a00754d..0439532 100644
--- a/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html
+++ b/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html
@@ -84,6 +84,14 @@
     </os-settings-subpage>
   </template>
 
+  <!-- "App Languages" sub-page. -->
+  <template is="dom-if" route-path="/osLanguages/languages/appLanguages">
+    <os-settings-subpage page-title="$i18n{appLanguagesTitle}">
+      <os-settings-app-languages-page prefs="{{prefs}}">
+      </os-settings-app-languages-page>
+    </os-settings-subpage>
+  </template>
+
   <!-- Search and Assistant subpages -->
   <template is="dom-if" if="[[shouldShowQuickAnswersSettings_]]">
     <template is="dom-if" route-path="/osSearch/search">
diff --git a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
index df7931a4..5c71825 100644
--- a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
+++ b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
@@ -33,6 +33,10 @@
   private proxy: CloudUploadBrowserProxy =
       CloudUploadBrowserProxy.getInstance();
 
+  // Save reference to listener so it can be removed from the document in
+  // disconnectedCallback().
+  private boundKeyDownListener_: (e: KeyboardEvent) => void;
+
   constructor() {
     super();
     const shadowRoot = this.attachShadow({mode: 'open'});
@@ -40,19 +44,36 @@
     shadowRoot.innerHTML = getTemplate();
     const openButton = this.$<CrButtonElement>('.action-button');
     const cancelButton = this.$<CrButtonElement>('.cancel-button');
-    const header = this.$<HTMLDialogElement>('#header');
     assert(openButton);
     assert(cancelButton);
-    assert(header);
 
     openButton.disabled = true;
     openButton.addEventListener('click', () => this.onOpenButtonClick());
     cancelButton.addEventListener('click', () => this.onCancelButtonClick());
-    header.addEventListener('keydown', this.handleKeyDown.bind(this));
+    this.boundKeyDownListener_ = this.handleKeyDown.bind(this);
 
     this.initDynamicContent();
   }
 
+  // Initialises the scrollable content styles and add document event listeners.
+  connectedCallback(): void {
+    const contentElement = this.$<HTMLElement>('#content')!;
+    window.requestAnimationFrame(() => {
+      this.updateContentFade(contentElement);
+    });
+    contentElement.addEventListener(
+        'scroll', this.updateContentFade.bind(undefined, contentElement),
+        {passive: true});
+    contentElement.addEventListener('keydown', this.boundKeyDownListener_);
+
+    document.addEventListener('keydown', this.boundKeyDownListener_);
+  }
+
+  // Remove document event listeners.
+  disconnectedCallback(): void {
+    document.removeEventListener('keydown', this.boundKeyDownListener_);
+  }
+
   $<T extends HTMLElement>(query: string): T {
     return this.shadowRoot!.querySelector(query)!;
   }
@@ -188,18 +209,6 @@
         'click', () => this.selectCard(localHandlerCard));
   }
 
-  // Initialises the scrollable content styles.
-  connectedCallback(): void {
-    const contentElement = this.$<HTMLElement>('#content')!;
-    window.requestAnimationFrame(() => {
-      this.updateContentFade(contentElement);
-    });
-    contentElement.addEventListener(
-        'scroll', this.updateContentFade.bind(undefined, contentElement),
-        {passive: true});
-    contentElement.addEventListener('keydown', this.handleKeyDown.bind(this));
-  }
-
   private selectCard(card: FileHandlerCardElement) {
     assert(card.style.display != 'none', 'Attempting to select a hidden card');
     for (const providerCard of this.cloudProviderCards) {
@@ -248,6 +257,14 @@
   }
 
   handleKeyDown(e: KeyboardEvent): void {
+    if (e.key === 'Escape') {
+      // Handle Escape as a "cancel".
+      e.stopImmediatePropagation();
+      e.preventDefault();
+      this.onCancelButtonClick();
+      return;
+    }
+
     // Prevent scroll on spacebar.
     if (e.key === ' ') {
       e.preventDefault();
diff --git a/chrome/browser/resources/chromeos/emoji_picker/app.ts b/chrome/browser/resources/chromeos/emoji_picker/app.ts
index 0dba58baa..75c9c12 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/app.ts
+++ b/chrome/browser/resources/chromeos/emoji_picker/app.ts
@@ -296,8 +296,7 @@
 
     // After initial data is loaded, if the GIF nudge is not shown before, show
     // the GIF nudge.
-    if (this.gifSupport &&
-        !GifNudgeHistoryStore.getInstance().hasNudgeShown()) {
+    if (this.gifSupport && !GifNudgeHistoryStore.hasNudgeShown()) {
       this.showGifNudgeOverlay = true;
     }
 
@@ -1103,7 +1102,7 @@
       return [];
     }
 
-    return this.categoriesHistory[category]?.data?.history?.map(
+    return this.categoriesHistory[category]?.getHistory().map(
                emoji => ({
                  base: {
                    string: emoji.base.string,
@@ -1241,8 +1240,7 @@
    * @returns {boolean} True for empty history.
    */
   private isCategoryHistoryEmpty(category: CategoryEnum) {
-    return this.incognito ||
-        (this.categoriesHistory[category]?.data?.history?.length ?? 0) === 0;
+    return this.incognito || this.categoriesHistory[category]?.isHistoryEmpty();
   }
 
   /**
@@ -1320,7 +1318,7 @@
     return this.incognito ? {} :
                             // ! is safe as categories history must contain
                             // entries for all categories.
-                            this.categoriesHistory[category]!.data.preference;
+        this.categoriesHistory[category]!.getPreferenceMapping();
   }
 
   private onShowEmojiVariants(ev: events.EmojiVariantsShownEvent) {
@@ -1590,7 +1588,7 @@
       this.showGifNudgeOverlay = false;
     }
 
-    GifNudgeHistoryStore.getInstance().setNudgeShown(true);
+    GifNudgeHistoryStore.setNudgeShown(true);
   }
 }
 
diff --git a/chrome/browser/resources/chromeos/emoji_picker/store.ts b/chrome/browser/resources/chromeos/emoji_picker/store.ts
index bb53144..9a35079 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/store.ts
+++ b/chrome/browser/resources/chromeos/emoji_picker/store.ts
@@ -8,37 +8,64 @@
 
 const MAX_RECENTS = 10;
 
-/**
- * @param {string} keyName Keyname of the object stored in storage
- * @return {{history:!Array<EmojiVariants>, preference:Object<string,string>}}
- *     recently used emoji, most recent first.
- */
-function load(keyName: string) {
-  const stored = window.localStorage.getItem(keyName);
-  if (!stored) {
-    return {history: [], preference: {}};
+class Store<T> {
+  data: T;
+
+  /**
+   * @param storageKey The key to use in local storage.
+   * @param defaultData The initial data for this store. A new copy should
+   *     be passed for each `Store` instance.
+   */
+  constructor(private readonly storageKey: string, defaultData: T) {
+    this.data = this.load(defaultData);
   }
-  const parsed = /** @type {?} */ (JSON.parse(stored));
-  // Throw out any old data
-  return {history: parsed.history || [], preference: parsed.preference || {}};
+
+  /**
+   * @param defaultData The initial data for this store. A new copy should
+   *     be passed each time this is called.
+   * @return The data from local storage if it exists, otherwise a reference
+   *     to `defaultData`.
+   */
+  private load(defaultData: T): T {
+    const stored = window.localStorage.getItem(this.storageKey);
+
+    if (!stored) {
+      return defaultData;
+    }
+
+    const parsed = JSON.parse(stored);
+
+    // Checking for null because values of type 'object' can still be null.
+    if (typeof defaultData !== 'object' || defaultData === null ||
+        typeof parsed !== 'object' || parsed === null) {
+      return parsed;
+    }
+
+    // Throw out any old data.
+    const filteredEntries =
+        Object.entries(parsed).filter(([key, _]) => key in defaultData);
+
+    return {...defaultData, ...Object.fromEntries(filteredEntries)};
+  }
+
+  /**
+   * Saves the existing data to local storage.
+   */
+  save() {
+    window.localStorage.setItem(this.storageKey, JSON.stringify(this.data));
+  }
 }
 
-/**
- * @param {{history:!Array<EmojiVariants>, preference:Object<string,string>}}
- *     data recently used emoji, most recent first.
- */
-function save(
-    keyName: string,
-    data: {history: EmojiVariants[], preference: {[index: string]: string}}) {
-  window.localStorage.setItem(keyName, JSON.stringify(data));
+interface RecentlyUsed {
+  history: EmojiVariants[];
+  preference: {[index: string]: string};
 }
 
 export class RecentlyUsedStore {
-  storeName: string;
-  data: {history: EmojiVariants[], preference: {[index: string]: string}};
+  private store: Store<RecentlyUsed>;
+
   constructor(name: string) {
-    this.storeName = name;
-    this.data = load(name);
+    this.store = new Store(name, {history: [], preference: {}});
   }
 
   /**
@@ -51,42 +78,53 @@
       return false;
     }
 
+    const preference = this.store.data.preference;
+
     // Base emoji must not be set as preference. So, store it only
     // if variant and baseEmoji are different and remove it from preference
     // otherwise.
     if (baseEmoji !== variant && variant) {
-      this.data.preference[baseEmoji] = variant;
-    } else if (baseEmoji in this.data.preference) {
-      delete this.data.preference[baseEmoji];
+      preference[baseEmoji] = variant;
+    } else if (baseEmoji in preference) {
+      delete preference[baseEmoji];
     } else {
       return false;
     }
 
-    save(this.storeName, this.data);
+    this.store.save();
     return true;
   }
 
-  getPreferenceMapping() {
-    return this.data.preference;
+  getHistory(): EmojiVariants[] {
+    return this.store.data.history;
+  }
+
+  isHistoryEmpty(): boolean {
+    return this.store.data.history.length === 0;
+  }
+
+  getPreferenceMapping(): {[index: string]: string} {
+    return this.store.data.preference;
   }
 
   clearRecents() {
-    this.data.history = [];
-    save(this.storeName, this.data);
+    this.store.data.history = [];
+    this.store.save();
   }
 
   clearItem(category: CategoryEnum, item: EmojiVariants) {
+    const history = this.store.data.history;
+
     if (category === CategoryEnum.GIF) {
-      this.data.history = this.data.history.filter(
-        x =>
-          (x.base.visualContent &&
-            x.base.visualContent.id !== item.base.visualContent?.id));
+      this.store.data.history = history.filter(
+          x =>
+              (x.base.visualContent &&
+               x.base.visualContent.id !== item.base.visualContent?.id));
     } else {
-      this.data.history = this.data.history.filter(
-        x =>
-          (x.base.string && x.base.string !== item.base.string));
+      this.store.data.history = history.filter(
+          x => (x.base.string && x.base.string !== item.base.string));
     }
-    save(this.storeName, this.data);
+    this.store.save();
   }
 
   /**
@@ -94,45 +132,49 @@
    * it did not previously exist.
    */
   bumpItem(category: CategoryEnum, newItem: EmojiVariants) {
+    const history = this.store.data.history;
+
     // Find and remove newItem from array if it previously existed.
     // Note, this explicitly allows for multiple recent item entries for the
     // same "base" emoji just with a different variant.
     let oldIndex;
     if (category === CategoryEnum.GIF) {
-      oldIndex = this.data.history.findIndex(
+      oldIndex = history.findIndex(
           x =>
               (x.base.visualContent &&
                x.base.visualContent.id === newItem.base.visualContent?.id));
     } else {
-      oldIndex = this.data.history.findIndex(
+      oldIndex = history.findIndex(
           x => (x.base.string && x.base.string === newItem.base.string));
     }
 
     if (oldIndex !== -1) {
-      this.data.history.splice(oldIndex, 1);
+      history.splice(oldIndex, 1);
     }
     // insert newItem to the front of the array.
-    this.data.history.unshift(newItem);
+    history.unshift(newItem);
     // slice from end of array if it exceeds MAX_RECENTS.
-    if (this.data.history.length > MAX_RECENTS) {
+    if (history.length > MAX_RECENTS) {
       // setting length is sufficient to truncate an array.
-      this.data.history.length = MAX_RECENTS;
+      history.length = MAX_RECENTS;
     }
-    save(this.storeName, this.data);
+    this.store.save();
   }
 
   /**
    * Removes invalid GIFs from history.
    */
   async validate(apiProxy: EmojiPickerApiProxy): Promise<boolean> {
-    if (this.data.history.length === 0) {
+    const history = this.store.data.history;
+
+    if (history.length === 0) {
       // No GIFs to validate.
       return false;
     }
 
     // This function is only called on history items with visual content (i.e.
     // GIFs) so we can be confident an id will always exist.
-    const ids = this.data.history.map(x => x.base.visualContent!.id);
+    const ids = history.map(x => x.base.visualContent!.id);
 
     const {selectedGifs} = await apiProxy.getGifsByIds(ids);
     const map = new Map<string, VisualContent>();
@@ -141,30 +183,27 @@
     });
 
     const validGifHistory =
-        this.data.history.filter(item => map.has(item.base.visualContent!.id));
-    const updated = (validGifHistory.length !== this.data.history.length);
+        history.filter(item => map.has(item.base.visualContent!.id));
+    const updated = (validGifHistory.length !== history.length);
 
     if (updated) {
-      this.data.history = validGifHistory;
-      save(this.storeName, this.data);
+      this.store.data.history = validGifHistory;
+      this.store.save();
     }
 
     return updated;
   }
 }
 
-const GIF_NUDGE_SHOWN_KEY = 'emoji-picker-gif-nudge-shown';
-
 export class GifNudgeHistoryStore {
-  hasNudgeShown(): boolean {
-    return window.localStorage.getItem(GIF_NUDGE_SHOWN_KEY) === true.toString();
+  private static store = new Store('emoji-picker-gif-nudge-shown', false);
+
+  static hasNudgeShown(): boolean {
+    return GifNudgeHistoryStore.store.data;
   }
 
-  setNudgeShown(value: boolean): void {
-    window.localStorage.setItem(GIF_NUDGE_SHOWN_KEY, value.toString());
-  }
-
-  static getInstance(): GifNudgeHistoryStore {
-    return new GifNudgeHistoryStore();
+  static setNudgeShown(value: boolean): void {
+    GifNudgeHistoryStore.store.data = value;
+    GifNudgeHistoryStore.store.save();
   }
 }
diff --git a/chrome/browser/resources/chromeos/login/login.gni b/chrome/browser/resources/chromeos/login/login.gni
index 2624c84c..58cd79c 100644
--- a/chrome/browser/resources/chromeos/login/login.gni
+++ b/chrome/browser/resources/chromeos/login/login.gni
@@ -142,7 +142,7 @@
   "screens/common/gesture_navigation.js",
   "screens/common/guest_tos.js",
   "screens/common/hw_data_collection.js",
-  "screens/common/local_state_error.js",
+  "screens/common/local_state_error.ts",
   "screens/common/managed_terms_of_service.js",
   "screens/common/marketing_opt_in.js",
   "screens/common/multidevice_setup.js",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
index e0e1c41..f53d559 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
@@ -39,7 +39,6 @@
     ":gesture_navigation",
     ":guest_tos",
     ":hw_data_collection",
-    ":local_state_error",
     ":managed_terms_of_service",
     ":marketing_opt_in",
     ":offline_ad_login",
@@ -223,18 +222,6 @@
   extra_deps = [ ":web_components" ]
 }
 
-js_library("local_state_error") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js" ]
-  deps = [
-    "../../components/behaviors:login_screen_behavior",
-    "../../components/behaviors:oobe_dialog_host_behavior",
-    "../../components/behaviors:oobe_i18n_behavior",
-    "../../components/dialogs:oobe_adaptive_dialog",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-  extra_deps = [ ":web_components" ]
-}
-
 js_library("managed_terms_of_service") {
   sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/managed_terms_of_service.js" ]
   deps = [
diff --git a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js
deleted file mode 100644
index d3f7c4a..0000000
--- a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Polymer element for displaying local state error screen.
- */
-
-import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
-import '../../components/oobe_icons.html.js';
-import '../../components/buttons/oobe_text_button.js';
-import '../../components/common_styles/oobe_common_styles.css.js';
-import '../../components/common_styles/oobe_dialog_host_styles.css.js';
-import '../../components/dialogs/oobe_adaptive_dialog.js';
-
-import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
-import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js';
-import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
-import {OOBE_UI_STATE} from '../../components/display_manager_types.js';
-
-import {getTemplate} from './local_state_error.html.js';
-
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {LoginScreenBehaviorInterface}
- * @implements {OobeI18nBehaviorInterface}
- */
-const LocalStateErrorBase = mixinBehaviors(
-    [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
-    PolymerElement);
-
-/**
- * @polymer
- */
-class LocalStateError extends LocalStateErrorBase {
-  static get is() {
-    return 'local-state-error-element';
-  }
-
-  static get template() {
-    return getTemplate();
-  }
-
-  static get properties() {
-    return {};
-  }
-
-  ready() {
-    super.ready();
-    this.initializeLoginScreen('LocalStateErrorScreen');
-  }
-
-  /** Initial UI State for screen */
-  getOobeUIInitialState() {
-    return OOBE_UI_STATE.BLOCKING;
-  }
-
-  onRestartAndPowerwash_() {
-    this.userActed('restart-and-powerwash');
-  }
-}
-
-customElements.define(LocalStateError.is, LocalStateError);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts
new file mode 100644
index 0000000..95f9d355
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts
@@ -0,0 +1,70 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polymer element for displaying local state error screen.
+ */
+
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../../components/oobe_icons.html.js';
+import '../../components/buttons/oobe_text_button.js';
+import '../../components/common_styles/oobe_common_styles.css.js';
+import '../../components/common_styles/oobe_dialog_host_styles.css.js';
+import '../../components/dialogs/oobe_adaptive_dialog.js';
+
+import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js';
+import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
+import {OobeDialogHostBehavior, OobeDialogHostBehaviorInterface} from '../../components/behaviors/oobe_dialog_host_behavior.js';
+import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
+import {OOBE_UI_STATE} from '../../components/display_manager_types.js';
+
+import {getTemplate} from './local_state_error.html.js';
+
+export const LocalStateErrorBase =
+    mixinBehaviors(
+        [OobeI18nBehavior, LoginScreenBehavior, OobeDialogHostBehavior],
+        PolymerElement) as {
+      new (): PolymerElement & OobeI18nBehaviorInterface &
+          LoginScreenBehaviorInterface & OobeDialogHostBehaviorInterface,
+    };
+
+
+export class LocalStateError extends LocalStateErrorBase {
+  static get is() {
+    return 'local-state-error-element' as const;
+  }
+
+  static get template(): HTMLTemplateElement {
+    return getTemplate();
+  }
+
+  static get properties(): PolymerElementProperties {
+    return {};
+  }
+
+  override ready(): void {
+    super.ready();
+    this.initializeLoginScreen('LocalStateErrorScreen');
+  }
+
+  /** Initial UI State for screen */
+  // eslint-disable-next-line @typescript-eslint/naming-convention
+  override getOobeUIInitialState(): OOBE_UI_STATE {
+    return OOBE_UI_STATE.BLOCKING;
+  }
+
+  private onRestartAndPowerwash_(): void {
+    this.userActed('restart-and-powerwash');
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    [LocalStateError.is]: LocalStateError;
+  }
+}
+
+customElements.define(LocalStateError.is, LocalStateError);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html b/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html
index c2d9c724..fa2f716 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html
@@ -7,7 +7,7 @@
 <style include="oobe-dialog-host-styles"></style>
 <oobe-adaptive-dialog role="dialog">
     <iron-icon slot="icon" icon="oobe-32:enterprise"></iron-icon>
-    <h1 slot="title">
+    <h1 slot="title" aria-live="polite">
         [[i18nDynamic(locale, 'localStateNotificationTitle')]]
     </h1>
     <div slot="subtitle">
@@ -22,4 +22,4 @@
             id="cancelButton">
         </oobe-text-button>
     </div>
-</oobe-adaptive-dialog>
\ No newline at end of file
+</oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/side_panel/commerce/history_graph.ts b/chrome/browser/resources/side_panel/commerce/history_graph.ts
index 845741a..8e538d0 100644
--- a/chrome/browser/resources/side_panel/commerce/history_graph.ts
+++ b/chrome/browser/resources/side_panel/commerce/history_graph.ts
@@ -62,10 +62,14 @@
   private points: Array<{date: Date, price: number}>;
   private isGraphInteracted_: boolean = false;
   private currentPricePointIndex_?: number;
+  private resizeObserver_: ResizeObserver;
+  private currentWidth_: number;
+  private graphSvg_: any;
   private dateTopMarginPx_ = 8;
   private priceRightMarginPx_ = 4;
   private bubbleHorizontalPaddingPx_ = 4;
-  private bubbleVerticalPaddingPx_ = 4;
+  private bubbleTopPaddingPx_ = 4;
+  private bubbleBottomPaddingPx_ = 4;
   private bubbleCornerRadiusPx_ = 3;
 
   override connectedCallback() {
@@ -75,13 +79,22 @@
       this.dateTopMarginPx_ = 12;
       this.priceRightMarginPx_ = 8;
       this.bubbleHorizontalPaddingPx_ = 6;
-      this.bubbleVerticalPaddingPx_ = 2;
+      this.bubbleTopPaddingPx_ = 3;
+      this.bubbleBottomPaddingPx_ = 2;
     }
 
     this.points = this.data.map(
         d => ({date: this.stringToDate_(d.date), price: d.price}));
 
     this.drawHistoryGraph_();
+
+    this.currentWidth_ = this.$.historyGraph.offsetWidth;
+    this.resizeObserver_ = new ResizeObserver(this.onResize_.bind(this));
+    this.resizeObserver_.observe(this.$.historyGraph);
+  }
+
+  override disconnectedCallback() {
+    this.resizeObserver_.disconnect();
   }
 
   private stringToDate_(s: string): Date {
@@ -94,6 +107,14 @@
     return new Date(year, month - 1, day);
   }
 
+  private onResize_() {
+    if (this.$.historyGraph.offsetWidth !== this.currentWidth_) {
+      this.currentWidth_ = this.$.historyGraph.offsetWidth;
+      this.graphSvg_.remove();
+      this.drawHistoryGraph_();
+    }
+  }
+
   private getTooltipText_(i: number): string {
     let formattedDate = d3.timeFormat('%b %-d')(this.points[i].date);
 
@@ -118,7 +139,7 @@
         this.getLabelSize_(formattedTicks[formattedTicks.length - 1]);
 
     const graphMarginTopPx = GRAPH_BUBBLE_BOTTOM_MARGIN_PX +
-        2 * this.bubbleVerticalPaddingPx_ + tooltipHeight;
+        this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ + tooltipHeight;
     const graphMarginBottomPx = this.dateTopMarginPx_ + labelHeight;
     const graphHeightPx =
         LINE_AREA_HEIGHT_PX + graphMarginTopPx + graphMarginBottomPx;
@@ -130,6 +151,7 @@
                     .attr('width', '100%')
                     .attr('height', graphHeightPx)
                     .attr('background-color', 'transparent');
+    this.graphSvg_ = svg;
     const node = svg.node();
     assert(node);
     const graphWidthPx = node.getBoundingClientRect().width;
@@ -199,7 +221,10 @@
     // Set up bubble and mouse listeners.
     const verticalLine =
         svg.append('line')
-            .attr('y1', 2 * this.bubbleVerticalPaddingPx_ + tooltipHeight)
+            .attr(
+                'y1',
+                this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ +
+                    tooltipHeight)
             .attr('y2', graphHeightPx - graphMarginBottomPx)
             .attr('opacity', 0)
             .classed(CssClass.DASH_LINE, true);
@@ -211,25 +236,30 @@
 
     if (document.documentElement.hasAttribute('chrome-refresh-2023')) {
       this.bubbleCornerRadiusPx_ =
-          this.bubbleVerticalPaddingPx_ + tooltipHeight / 2;
+          (this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ +
+           tooltipHeight) /
+          2;
     }
-    const bubble =
-        svg.append('rect')
-            .attr('opacity', 0)
-            .attr('y', 0)
-            .attr('height', 2 * this.bubbleVerticalPaddingPx_ + tooltipHeight)
-            .attr('rx', this.bubbleCornerRadiusPx_)
-            .attr('ry', this.bubbleCornerRadiusPx_)
-            .classed(CssClass.BUBBLE, true);
+    const bubble = svg.append('rect')
+                       .attr('opacity', 0)
+                       .attr('y', 0)
+                       .attr(
+                           'height',
+                           this.bubbleTopPaddingPx_ +
+                               this.bubbleBottomPaddingPx_ + tooltipHeight)
+                       .attr('rx', this.bubbleCornerRadiusPx_)
+                       .attr('ry', this.bubbleCornerRadiusPx_)
+                       .classed(CssClass.BUBBLE, true);
 
-    const tooltip =
-        svg.append('text')
-            .attr('y', this.bubbleVerticalPaddingPx_ + tooltipHeight / 2)
-            .attr('dominant-baseline', 'middle')
-            .attr('opacity', 0)
-            .attr('aria-hidden', 'true');
+    const tooltip = svg.append('text')
+                        .attr('y', this.bubbleTopPaddingPx_ + tooltipHeight / 2)
+                        .attr('dominant-baseline', 'middle')
+                        .attr('opacity', 0)
+                        .attr('aria-hidden', 'true');
 
-    const initialIndex = this.points.length - 1;
+    const initialIndex = this.currentPricePointIndex_ == null ?
+        this.points.length - 1 :
+        this.currentPricePointIndex_;
     this.showTooltip_(
         verticalLine, circle, bubble, tooltip, initialIndex,
         xScale(this.points[initialIndex].date),
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index e317e16..4118ac2 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -43,7 +43,6 @@
     "//components/resources:components_resources_grit",
     "//components/safe_browsing:buildflags",
     "//components/safe_browsing/content/browser",
-    "//components/safe_browsing/content/browser:client_report_util",
     "//components/safe_browsing/content/browser:client_side_detection",
     "//components/safe_browsing/content/browser:client_side_detection_service",
     "//components/safe_browsing/content/browser/triggers:suspicious_site_trigger",
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index 7da85cd8..d451e8a 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -60,6 +60,7 @@
 #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
@@ -72,7 +73,6 @@
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/core/common/safebrowsing_constants.h"
 #include "components/safe_browsing/core/common/utils.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/identity_manager/account_info.h"
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
index d4ba433..26b875dfd 100644
--- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
+++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
@@ -54,7 +54,7 @@
   safe_browsing::UpdatePrefsBeforeSecurityInterstitial(prefs);
 
   security_interstitials::BaseSafeBrowsingErrorUI::SBErrorDisplayOptions
-      display_options(BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
+      display_options(BaseBlockingPage::IsMainPageLoadPending(unsafe_resources),
                       is_extended_reporting_opt_in_allowed,
                       web_contents->GetBrowserContext()->IsOffTheRecord(),
                       IsExtendedReportingEnabled(*prefs),
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
index d5cec9f..6ba8309 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -31,6 +31,7 @@
 #include "components/safe_browsing/content/browser/client_side_detection_service.h"
 #include "components/safe_browsing/content/browser/client_side_phishing_model.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/test_database_manager.h"
@@ -38,7 +39,6 @@
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "content/public/browser/back_forward_cache.h"
@@ -545,7 +545,7 @@
   EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type);
   EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source);
   EXPECT_EQ(web_contents(),
-            security_interstitials::GetWebContentsForResource(resource));
+            unsafe_resource_util::GetWebContentsForResource(resource));
 
   // Make sure the client object will be deleted.
   content::GetIOThreadTaskRunner({})->PostTask(
@@ -616,7 +616,7 @@
   EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type);
   EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source);
   EXPECT_EQ(web_contents(),
-            security_interstitials::GetWebContentsForResource(resource));
+            unsafe_resource_util::GetWebContentsForResource(resource));
 
   // Make sure the client object will be deleted.
   content::GetIOThreadTaskRunner({})->PostTask(
diff --git a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc
index e0e12d4..86c7e67 100644
--- a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc
+++ b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc
@@ -18,8 +18,8 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/common/features.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/mock_render_process_host.h"
@@ -229,8 +229,8 @@
   safe_browsing::SBThreatType threat_type;
   EXPECT_TRUE(ui_manager_->IsUrlAllowlistedOrPendingForWebContents(
       resource.url, resource.is_subresource, /*entry=*/nullptr,
-      security_interstitials::GetWebContentsForResource(resource), true,
-      &threat_type));
+      safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource),
+      true, &threat_type));
 
   const std::string phishy_interaction_histogram = "SafeBrowsing.PhishySite.";
   const int kExpectedClickEventCount = 3;
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 145ee08..59e0b3c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -75,6 +75,7 @@
 #include "components/safe_browsing/content/browser/safe_browsing_blocking_page_factory.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/fake_database_manager.h"
@@ -89,7 +90,6 @@
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
 #include "components/security_interstitials/content/ssl_blocking_page.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/controller_client.h"
 #include "components/security_interstitials/core/metrics_helper.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
@@ -550,7 +550,7 @@
         IsSafeBrowsingSurveysEnabled(*prefs);
 
     BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options(
-        BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
+        BaseBlockingPage::IsMainPageLoadPending(unsafe_resources),
         is_extended_reporting_opt_in_allowed,
         web_contents->GetBrowserContext()->IsOffTheRecord(),
         IsExtendedReportingEnabled(*prefs),
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc
index 631bffff..2d1393c 100644
--- a/chrome/browser/safe_browsing/threat_details_unittest.cc
+++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -25,11 +25,11 @@
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/threat_details_history.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom.h"
 #include "components/safe_browsing/core/browser/referrer_chain_provider.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/global_routing_id.h"
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
index bbc7a99..3bf8558a 100644
--- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
+++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -18,11 +18,11 @@
 #include "components/safe_browsing/buildflags.h"
 #include "components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_entry.h"
@@ -58,7 +58,7 @@
     bool is_main_frame,
     scoped_refptr<SafeBrowsingUIManager> ui_manager) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   // Don't delay the interstitial for prerender pages.
   if (!web_contents ||
       prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
index 9c48516..8849501 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
@@ -62,6 +62,10 @@
   TRACE_EVENT("browser", "BoundSessionRegistrationFetcherImpl::Start",
               perfetto::Flow::FromPointer(this), "endpoint",
               registration_params_.RegistrationEndpoint());
+  CHECK(!registration_duration_.has_value());
+  CHECK(!callback_);
+  CHECK(!registration_token_helper_);
+  registration_duration_.emplace();  // Starts the timer.
   callback_ = std::move(callback);
   // base::Unretained() is safe since `this` owns
   // `registration_token_helper_`.
@@ -70,7 +74,7 @@
       registration_params_.RegistrationEndpoint(),
       base::BindOnce(
           &BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated,
-          base::Unretained(this)));
+          base::Unretained(this), base::ElapsedTimer()));
   registration_token_helper_->Start();
 }
 
@@ -138,10 +142,15 @@
 }
 
 void BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated(
+    base::ElapsedTimer generate_registration_token_timer,
     absl::optional<RegistrationTokenHelper::Result> result) {
   TRACE_EVENT("browser",
               "BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated",
               perfetto::Flow::FromPointer(this), "success", result.has_value());
+  base::UmaHistogramMediumTimes(
+      "Signin.BoundSessionCredentials."
+      "SessionRegistrationGenerateRegistrationTokenDuration",
+      generate_registration_token_timer.Elapsed());
   if (!result.has_value()) {
     RunCallbackAndRecordMetrics(
         base::unexpected(RegistrationError::kGenerateRegistrationTokenFailed));
@@ -234,6 +243,11 @@
   base::UmaHistogramEnumeration(
       "Signin.BoundSessionCredentials.SessionRegistrationResult",
       error_for_metrics);
+  CHECK(registration_duration_.has_value());
+  base::UmaHistogramMediumTimes(
+      "Signin.BoundSessionCredentials.SessionRegistrationTotalDuration",
+      registration_duration_->Elapsed());
+  registration_duration_.reset();
 
   std::move(callback_).Run(
       params_or_error.has_value()
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
index f36ee884..b56e9cd9 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
@@ -13,6 +13,7 @@
 #include "base/functional/callback.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/types/expected.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_param.h"
@@ -20,6 +21,7 @@
 #include "components/unexportable_keys/service_error.h"
 #include "components/unexportable_keys/unexportable_key_id.h"
 #include "services/network/public/cpp/simple_url_loader.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace network {
@@ -81,6 +83,7 @@
 
   void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);
   void OnRegistrationTokenCreated(
+      base::ElapsedTimer generate_registration_token_timer,
       absl::optional<RegistrationTokenHelper::Result> result);
 
   void StartFetchingRegistration(const std::string& registration_token);
@@ -101,6 +104,7 @@
 
   // Non-null after a fetch has started.
   std::unique_ptr<network::SimpleURLLoader> url_loader_;
+  absl::optional<base::ElapsedTimer> registration_duration_;
   const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   std::unique_ptr<RegistrationTokenHelper> registration_token_helper_;
 
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
index 6bcb817..6b058319 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
@@ -193,9 +193,15 @@
     scoped_key_provider_.emplace<crypto::ScopedNullUnexportableKeyProvider>();
   }
 
-  void ExpectRecordedResultHistogram(RegistrationError error) {
+  void ExpectRecordedMetrics(RegistrationError error) {
     histogram_tester_.ExpectUniqueSample(
         "Signin.BoundSessionCredentials.SessionRegistrationResult", error, 1);
+    histogram_tester_.ExpectTotalCount(
+        "Signin.BoundSessionCredentials.SessionRegistrationTotalDuration", 1);
+    histogram_tester_.ExpectTotalCount(
+        "Signin.BoundSessionCredentials."
+        "SessionRegistrationGenerateRegistrationTokenDuration",
+        1);
   }
 
  private:
@@ -252,7 +258,7 @@
               testing::Optional(base::test::EqualsProto(
                   CreateTestBoundSessionParams(future.Get()->wrapped_key()))));
 
-  ExpectRecordedResultHistogram(RegistrationError::kNone);
+  ExpectRecordedMetrics(RegistrationError::kNone);
 
   // Verify the wrapped key.
   std::string wrapped_key = future.Get<>()->wrapped_key();
@@ -302,7 +308,7 @@
   EXPECT_TRUE(future.IsReady());
   EXPECT_EQ(future.Get<>(), absl::nullopt);
 
-  ExpectRecordedResultHistogram(RegistrationError::kParseJsonFailed);
+  ExpectRecordedMetrics(RegistrationError::kParseJsonFailed);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest,
@@ -315,7 +321,7 @@
   RunBackgroundTasks();
 
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(RegistrationError::kRequiredFieldMissing);
+  ExpectRecordedMetrics(RegistrationError::kRequiredFieldMissing);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest,
@@ -328,7 +334,7 @@
   RunBackgroundTasks();
 
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(RegistrationError::kRequiredFieldMissing);
+  ExpectRecordedMetrics(RegistrationError::kRequiredFieldMissing);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest,
@@ -355,8 +361,7 @@
   RunBackgroundTasks();
 
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(
-      RegistrationError::kRequiredCredentialFieldMissing);
+  ExpectRecordedMetrics(RegistrationError::kRequiredCredentialFieldMissing);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest, NonOkHttpResponseCode) {
@@ -368,7 +373,7 @@
   RunBackgroundTasks();
 
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(RegistrationError::kServerError);
+  ExpectRecordedMetrics(RegistrationError::kServerError);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest, NetworkError) {
@@ -380,7 +385,7 @@
   RunBackgroundTasks();
 
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(RegistrationError::kNetworkError);
+  ExpectRecordedMetrics(RegistrationError::kNetworkError);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest, NoKeyProvider) {
@@ -393,8 +398,7 @@
 
   EXPECT_FALSE(WasRequestSent());
   EXPECT_EQ(future.Get<>(), absl::nullopt);
-  ExpectRecordedResultHistogram(
-      RegistrationError::kGenerateRegistrationTokenFailed);
+  ExpectRecordedMetrics(RegistrationError::kGenerateRegistrationTokenFailed);
 }
 
 TEST_F(BoundSessionRegistrationFetcherImplTest, ParseCredentials) {
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client.cc b/chrome/browser/ui/ash/download_status/notification_display_client.cc
index c884506..c358b34 100644
--- a/chrome/browser/ui/ash/download_status/notification_display_client.cc
+++ b/chrome/browser/ui/ash/download_status/notification_display_client.cc
@@ -43,9 +43,8 @@
 constexpr char kNotificationOrigin[] = "chrome://downloads";
 
 // The commands supported by notification buttons.
-// TODO(http://b/316368295): Support pause and resume.
-constexpr std::array<CommandType, 2> kButtonCommands = {CommandType::kCancel,
-                                                        CommandType::kPause};
+constexpr std::array<CommandType, 3> kButtonCommands = {
+    CommandType::kCancel, CommandType::kPause, CommandType::kResume};
 
 // DownloadNotificationDelegate ------------------------------------------------
 
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc
index f13b9c7d..ebdd6f0 100644
--- a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc
+++ b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.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 <memory>
 #include <set>
 #include <string>
 #include <utility>
@@ -418,8 +419,9 @@
   EXPECT_THAT(GetDisplayedNotificationIds(), Not(Contains(notification_id)));
 }
 
-// Verifies pausing download from a notification.
-IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, PauseDownload) {
+// Verifies pausing and resuming download from a notification.
+IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
+                       PauseAndResumeDownload) {
   // Add a pausable download. Cache the notification ID.
   Profile* const profile = ProfileManager::GetActiveUserProfile();
   std::string notification_id;
@@ -433,25 +435,34 @@
                                      /*received_bytes=*/0,
                                      /*target_bytes=*/1024);
   download->pausable = true;
+  download->resumable = false;
   Update(download->Clone());
   Mock::VerifyAndClearExpectations(&service_observer());
 
+  // The notification of a pausable download should not have a resume button.
+  AshNotificationView* const popup_view =
+      GetPopupView(profile, notification_id);
+  ASSERT_TRUE(popup_view);
+  std::vector<views::LabelButton*> action_buttons =
+      popup_view->GetActionButtonsForTest();
+  const std::u16string resume_button_text =
+      l10n_util::GetStringUTF16(GetCommandTextId(CommandType::kResume));
+  auto resume_button_iter = base::ranges::find(
+      action_buttons, resume_button_text, &views::LabelButton::GetText);
+  EXPECT_EQ(resume_button_iter, action_buttons.end());
+
   // Implement download pause for the mock client.
   ON_CALL(download_status_updater_client(), Pause(download->guid, _))
       .WillByDefault([&](const std::string& guid,
                          crosapi::MockDownloadStatusUpdaterClient::PauseCallback
                              callback) {
         download->pausable = false;
+        download->resumable = true;
         Update(download->Clone());
         std::move(callback).Run(/*handled=*/true);
       });
 
   // Get the pause button.
-  AshNotificationView* const popup_view =
-      GetPopupView(profile, notification_id);
-  ASSERT_TRUE(popup_view);
-  std::vector<views::LabelButton*> action_buttons =
-      popup_view->GetActionButtonsForTest();
   const std::u16string pause_button_text =
       l10n_util::GetStringUTF16(GetCommandTextId(CommandType::kPause));
   auto pause_button_iter = base::ranges::find(action_buttons, pause_button_text,
@@ -459,14 +470,15 @@
   ASSERT_NE(pause_button_iter, action_buttons.end());
 
   // Click on the pause button and wait until download is paused.
-  base::RunLoop run_loop;
+  auto run_loop = std::make_unique<base::RunLoop>();
   EXPECT_CALL(service_observer(), OnNotificationDisplayed)
       .WillOnce(WithArg<0>(
           [&run_loop](const message_center::Notification& notification) {
-            run_loop.Quit();
+            run_loop->Quit();
           }));
   test::Click(*pause_button_iter, ui::EF_NONE);
-  run_loop.Run();
+  run_loop->Run();
+  Mock::VerifyAndClearExpectations(&service_observer());
 
   // After pausing, `popup_view` is hidden. Therefore, get the notification view
   // from the notification center bubble.
@@ -481,6 +493,34 @@
   pause_button_iter = base::ranges::find(action_buttons, pause_button_text,
                                          &views::LabelButton::GetText);
   EXPECT_EQ(pause_button_iter, action_buttons.end());
+
+  // The resume button should show.
+  resume_button_iter = base::ranges::find(action_buttons, resume_button_text,
+                                          &views::LabelButton::GetText);
+  ASSERT_NE(resume_button_iter, action_buttons.end());
+
+  // Implement download resume for the mock client.
+  ON_CALL(download_status_updater_client(), Resume(download->guid, _))
+      .WillByDefault(
+          [&](const std::string& guid,
+              crosapi::MockDownloadStatusUpdaterClient::ResumeCallback
+                  callback) {
+            download->pausable = true;
+            download->resumable = false;
+            Update(download->Clone());
+            std::move(callback).Run(/*handled=*/true);
+          });
+
+  // Click on the resume button and wait until download is resumed.
+  run_loop = std::make_unique<base::RunLoop>();
+  EXPECT_CALL(service_observer(), OnNotificationDisplayed)
+      .WillOnce(WithArg<0>(
+          [&run_loop](const message_center::Notification& notification) {
+            run_loop->Quit();
+          }));
+  test::Click(*resume_button_iter, ui::EF_NONE);
+  run_loop->Run();
+  Mock::VerifyAndClearExpectations(&service_observer());
 }
 
 }  // namespace ash::download_status
diff --git a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
index 12c2330..f6b9b07 100644
--- a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h"
 
 #include "ash/display/screen_orientation_controller.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/shell.h"
 #include "content/public/browser/web_contents.h"
+#include "ui/display/screen.h"
 
 namespace {
 
@@ -60,7 +60,7 @@
 
 bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported(
     content::WebContents* web_contents) {
-  return ash::TabletMode::IsInTabletMode();
+  return display::Screen::GetScreen()->InTabletMode();
 }
 
 void ScreenOrientationDelegateChromeos::Unlock(
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 44b97de..3b3f185 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -1945,8 +1945,8 @@
   std::unique_ptr<ScopedJitChromeBrowserClientOverride> scoped_client_override_;
 };
 
-typedef HostedAppJitTestBase<false> HostedAppJitTestBaseDefaultEnabled;
-typedef HostedAppJitTestBase<true> HostedAppJitTestBaseDefaultDisabled;
+using HostedAppJitTestBaseDefaultEnabled = HostedAppJitTestBase<false>;
+using HostedAppJitTestBaseDefaultDisabled = HostedAppJitTestBase<true>;
 
 IN_PROC_BROWSER_TEST_P(HostedAppJitTestBaseDefaultEnabled, JITDisabledTest) {
   JitTestInternal();
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 9dcd9dec..c5e091d3 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -1114,8 +1114,8 @@
   };
 
   for (const auto& test : kTestCases) {
-    ResetMockUI();
     ClearPageInfo();
+    ResetMockUI();
     security_level_ = test.security_level;
     visible_security_state_.url = GURL("https://scheme-is-cryptographic.test");
     visible_security_state_.certificate = cert();
@@ -1818,8 +1818,8 @@
     base::HistogramTester histograms;
     SetURL("https://example.test");
     visible_security_state_.safety_tip_info = test.safety_tip_info;
-    ResetMockUI();
     ClearPageInfo();
+    ResetMockUI();
     SetDefaultUIExpectations(mock_ui());
 
     histograms.ExpectTotalCount(kGenericHistogram, 0);
@@ -1912,8 +1912,8 @@
   EXPECT_FALSE(showing_setting(last_permission_info_list()));
 
   // Reset state.
-  ResetMockUI();
   ClearPageInfo();
+  ResetMockUI();
   SetDefaultUIExpectations(mock_ui());
 
   // Now, explicitly set site activation metadata to simulate activation on
diff --git a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc
index 6667135..c5e7a56 100644
--- a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc
@@ -203,10 +203,8 @@
   nickname_textfield_->set_controller(this);
   nickname_textfield_->SetPlaceholderText(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_IBAN_PLACEHOLDER));
-  nickname_textfield_->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kScaleToMaximum));
+  nickname_textfield_->SetProperty(views::kBoxLayoutFlexKey,
+                                   views::BoxLayoutFlexSpecification());
   nickname_textfield_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   nickname_textfield_->SetBorder(views::NullBorder());
 
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
index 108c3200f..e8e4208 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -153,9 +153,6 @@
   CHECK(!base::FeatureList::IsEnabled(
       extensions_features::kExtensionsMenuAccessControl));
 
-  views::FlexSpecification stretch_specification =
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded);
   auto builder =
       views::Builder<ExtensionMenuItemView>(this)
           // Set so the extension button receives enter/exit on children to
@@ -168,7 +165,10 @@
                   std::make_unique<ExtensionsMenuButton>(browser_,
                                                          controller_.get()))
                   .CopyAddressTo(&primary_action_button_)
-                  .SetProperty(views::kFlexBehaviorKey, stretch_specification),
+                  .SetProperty(views::kFlexBehaviorKey,
+                               views::FlexSpecification(
+                                   views::MinimumFlexSizeRule::kScaleToZero,
+                                   views::MaximumFlexSizeRule::kUnbounded)),
               views::Builder<HoverButton>(
                   std::make_unique<HoverButton>(
                       views::Button::PressedCallback(), std::u16string()))
@@ -225,9 +225,6 @@
   CHECK(base::FeatureList::IsEnabled(
       extensions_features::kExtensionsMenuAccessControl));
 
-  views::FlexSpecification stretch_specification =
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded);
   ChromeLayoutProvider* const provider = ChromeLayoutProvider::Get();
   const int icon_size =
       provider->GetDistanceMetric(DISTANCE_EXTENSIONS_MENU_EXTENSION_ICON_SIZE);
@@ -258,7 +255,8 @@
       .SetNotifyEnterExitOnChild(true)
       .SetOrientation(views::LayoutOrientation::kVertical)
       .SetCrossAxisAlignment(views::LayoutAlignment::kStretch)
-      .SetProperty(views::kFlexBehaviorKey, stretch_specification)
+      .SetProperty(views::kBoxLayoutFlexKey,
+                   views::BoxLayoutFlexSpecification())
       .AddChildren(
           // Main row.
           views::Builder<views::FlexLayoutView>()
@@ -275,7 +273,9 @@
                                                              controller_.get()))
                       .CopyAddressTo(&primary_action_button_)
                       .SetProperty(views::kFlexBehaviorKey,
-                                   stretch_specification),
+                                   views::FlexSpecification(
+                                       views::MinimumFlexSizeRule::kScaleToZero,
+                                       views::MaximumFlexSizeRule::kUnbounded)),
                   // Site access toggle.
                   views::Builder<views::ToggleButton>()
                       .CopyAddressTo(&site_access_toggle_)
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
index 7d3bf72..af14b31f 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -535,7 +535,8 @@
               .SetInteriorMargin(gfx::Insets::TLBR(dialog_insets.top(),
                                                    dialog_insets.left(), 0,
                                                    dialog_insets.right()))
-              .SetProperty(views::kFlexBehaviorKey, stretch_specification)
+              .SetProperty(views::kBoxLayoutFlexKey,
+                           views::BoxLayoutFlexSpecification())
               .SetVisible(true)
               .AddChildren(
                   views::Builder<views::FlexLayoutView>()
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc
index aff7e68..bc950cd 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc
@@ -257,7 +257,8 @@
               .SetInteriorMargin(gfx::Insets::TLBR(dialog_insets.top(),
                                                    dialog_insets.left(), 0,
                                                    dialog_insets.right()))
-              .SetProperty(views::kFlexBehaviorKey, stretch_specification)
+              .SetProperty(views::kBoxLayoutFlexKey,
+                           views::BoxLayoutFlexSpecification())
               .AddChildren(
                   // Back button.
                   views::Builder<views::ImageButton>(
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc
index 4c40c318..ac6a59b7 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc
@@ -138,10 +138,8 @@
   label_wrapper->SetLayoutManager(std::make_unique<views::FlexLayout>())
       ->SetOrientation(views::LayoutOrientation::kVertical)
       .SetMainAxisAlignment(views::LayoutAlignment::kCenter);
-  label_wrapper->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded));
+  label_wrapper->SetProperty(views::kBoxLayoutFlexKey,
+                             views::BoxLayoutFlexSpecification());
   label_wrapper->SetProperty(views::kMarginsKey,
                              gfx::Insets::VH(vertical_spacing, 0));
 
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc
index eaf00a59..508be728 100644
--- a/chrome/browser/ui/views/page_action/pwa_install_view.cc
+++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -40,7 +40,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/metrics/structured/event_logging_features.h"
-// TODO(crbug/4925196): enable gn check once it learn about conditional includes
+// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes
 #include "components/metrics/structured/structured_events.h"  // nogncheck
 #endif
 
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
index 54d86f3c..e9a1394d 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
@@ -220,10 +220,8 @@
       std::make_unique<views::BoxLayoutView>();
   auto* password_label_ptr = password_label_with_eye_icon_view->AddChildView(
       std::move(password_label));
-  password_label_ptr->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kScaleToMaximum));
+  password_label_ptr->SetProperty(views::kBoxLayoutFlexKey,
+                                  views::BoxLayoutFlexSpecification());
 
   auto* eye_icon = password_label_with_eye_icon_view->AddChildView(
       CreateVectorToggleImageButton(views::Button::PressedCallback()));
diff --git a/chrome/browser/ui/views/passwords/password_add_username_view.cc b/chrome/browser/ui/views/passwords/password_add_username_view.cc
index 7756d83..18f7997 100644
--- a/chrome/browser/ui/views/passwords/password_add_username_view.cc
+++ b/chrome/browser/ui/views/passwords/password_add_username_view.cc
@@ -39,10 +39,8 @@
   auto* password_label_ptr = password_label_with_eye_icon_view->AddChildView(
       std::move(password_label));
   password_label_ptr->SetTextStyle(views::style::STYLE_PRIMARY);
-  password_label_ptr->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kScaleToMaximum));
+  password_label_ptr->SetProperty(views::kBoxLayoutFlexKey,
+                                  views::BoxLayoutFlexSpecification());
 
   auto* eye_icon = password_label_with_eye_icon_view->AddChildView(
       CreateVectorToggleImageButton(views::Button::PressedCallback()));
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index 645c793..d677797 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -627,11 +627,8 @@
 
   // The |edit_button| is on the right and has fixed width.
   if (edit_button) {
-    edit_button->SetProperty(
-        views::kFlexBehaviorKey,
-        views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                                 views::MaximumFlexSizeRule::kPreferred)
-            .WithOrder(2));
+    edit_button->SetProperty(views::kBoxLayoutFlexKey,
+                             views::BoxLayoutFlexSpecification());
     views::View* edit_button_container =
         profile_background_container_->AddChildView(
             std::make_unique<views::View>());
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 6d27d6e..4c9d3153 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -11,7 +11,6 @@
 #include <utility>
 
 #include "ash/public/cpp/shell_window_ids.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
@@ -50,6 +49,7 @@
 #include "ui/base/base_window.h"
 #include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/color/color_provider.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 #include "ui/shell_dialogs/selected_file_info.h"
@@ -452,7 +452,8 @@
                                     owner.android_task_id.has_value() ||
                                     owner.lacros_window_id.has_value();
 
-  can_resize_ = !ash::TabletMode::IsInTabletMode() && !is_for_capture_mode;
+  can_resize_ =
+      !display::Screen::GetScreen()->InTabletMode() && !is_for_capture_mode;
 
   // Obtain BaseWindow and WebContents if the owner window is browser.
   if (!skip_finding_browser)
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc
index 9157f2f..d49a6e7 100644
--- a/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc
+++ b/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc
@@ -66,11 +66,8 @@
   if (orientation == views::BoxLayout::Orientation::kHorizontal) {
     button_layout->set_cross_axis_alignment(
         views::BoxLayout::CrossAxisAlignment::kCenter);
-    hover_button->SetProperty(
-        views::kFlexBehaviorKey,
-        views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                                 views::MaximumFlexSizeRule::kUnbounded)
-            .WithAlignment(views::LayoutAlignment::kStart));
+    hover_button->SetProperty(views::kBoxLayoutFlexKey,
+                              views::BoxLayoutFlexSpecification());
   }
 
   views::Builder<BubbleSyncPromoSigninButtonView>(this)
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
index 74673fa..69451a3 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -152,6 +152,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h"
+#include "chromeos/constants/chromeos_features.h"
 #else
 #include "chrome/browser/ui/webui/app_home/app_home.mojom.h"
 #include "chrome/browser/ui/webui/app_home/app_home_page_handler.h"
@@ -1153,6 +1154,10 @@
 }
 
 void WebAppIntegrationTestDriver::EnterFullScreenApp() {
+// TODO(crbug.com/1481727): Fullscreen is flaky on Lacros.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  GTEST_SKIP() << "Flaky on Lacros (crbug.com/1481727)";
+#else
   if (!BeforeStateChangeAction(__FUNCTION__)) {
     return;
   }
@@ -1164,9 +1169,14 @@
   fullscreen_observer.Wait();
   ASSERT_TRUE(fullscreen_controller->IsFullscreenForBrowser());
   AfterStateChangeAction();
+#endif  // IS_CHROMEOS_LACROS
 }
 
 void WebAppIntegrationTestDriver::ExitFullScreenApp() {
+// TODO(crbug.com/1481727): Fullscreen is flaky on Lacros.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  GTEST_SKIP() << "Flaky on Lacros (crbug.com/1481727)";
+#else
   if (!BeforeStateChangeAction(__FUNCTION__)) {
     return;
   }
@@ -1178,6 +1188,7 @@
   fullscreen_observer.Wait();
   ASSERT_FALSE(fullscreen_controller->IsFullscreenForBrowser());
   AfterStateChangeAction();
+#endif  // IS_CHROMEOS_LACROS
 }
 
 void WebAppIntegrationTestDriver::DisableFileHandling(Site site) {
@@ -1198,11 +1209,20 @@
 
 void WebAppIntegrationTestDriver::CreateShortcut(Site site,
                                                  WindowOptions options) {
+  bool open_in_window = options == WindowOptions::kWindowed;
+
+#if BUILDFLAG(IS_CHROMEOS)
+  if (chromeos::features::IsCrosShortstandEnabled() && open_in_window) {
+    GTEST_SKIP() << "With project Shortstand, users are no longer allowed to "
+                    "create shortcut and open in window.";
+  }
+#endif
+
   if (!BeforeStateChangeAction(__FUNCTION__)) {
     return;
   }
   MaybeNavigateTabbedBrowserInScope(site);
-  bool open_in_window = options == WindowOptions::kWindowed;
+
   SetAutoAcceptWebAppDialogForTesting(
       /*auto_accept=*/true,
       /*auto_open_in_window=*/open_in_window);
@@ -3771,6 +3791,9 @@
   if (testing::Test::HasFatalFailure() && !in_tear_down_) {
     return false;
   }
+  if (testing::Test::IsSkipped() && !in_tear_down_) {
+    return false;
+  }
   LOG(INFO) << "BeforeStateChangeAction: "
             << std::string(executing_action_level_, ' ') << function;
   ++executing_action_level_;
@@ -3864,6 +3887,9 @@
   if (testing::Test::HasFatalFailure() && !in_tear_down_) {
     return false;
   }
+  if (testing::Test::IsSkipped() && !in_tear_down_) {
+    return false;
+  }
   ++executing_action_level_;
   provider()->command_manager().AwaitAllCommandsCompleteForTesting();
   LOG(INFO) << "BeforeStateCheckAction: "
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index fefc67f..9f2e1187 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -134,7 +134,7 @@
 #include "ui/views/test/dialog_test.h"
 #include "ui/views/widget/any_widget_observer.h"
 #include "ui/views/widget/widget.h"
-// TODO(crbug/4925196): enable gn check once it learn about conditional includes
+// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes
 #include "components/metrics/structured/structured_events.h"  // nogncheck
 #endif
 
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
index 57edf00..edbb5575 100644
--- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -37,7 +37,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/metrics/structured/event_logging_features.h"
-// TODO(crbug/4925196): enable gn check once it learn about conditional includes
+// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes
 #include "components/metrics/structured/structured_events.h"  // nogncheck
 #endif
 
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
index 31ca2cb..3fc7c9b 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
@@ -1179,6 +1179,8 @@
     cloud_open_metrics_->LogTaskResult(
         OfficeTaskResult::kCancelledAtConfirmation);
   } else {
+    // TODO(b/315727684): mark an empty user response case NOTREACHED() once
+    // Escape is handled for all dialogs.
     cloud_open_metrics_->LogTaskResult(OfficeTaskResult::kLocalFileTask);
     LaunchLocalFileTask(user_response);
   }
@@ -1319,10 +1321,13 @@
 }
 
 bool CloudUploadDialog::ShouldCloseDialogOnEscape() const {
-  // The One Drive setup dialog handles escape in the webui as it needs to
-  // display a confirmation dialog on cancellation.
+  // TODO(b/315727684): Handle escape for all dialogs to ensure dialog is
+  // properly closed.
+  // The One Drive setup and File Handler dialogs handle escape.
   CHECK(dialog_args_);
-  return !dialog_args_->dialog_specific_args->is_one_drive_setup_dialog_args();
+  return !(
+      dialog_args_->dialog_specific_args->is_one_drive_setup_dialog_args() ||
+      dialog_args_->dialog_specific_args->is_file_handler_dialog_args());
 }
 
 bool CloudUploadDialog::ShouldShowCloseButton() const {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc
index 4cfe7bb..53c88c7 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc
@@ -28,6 +28,7 @@
 namespace ash::settings {
 
 namespace mojom {
+using ::chromeos::settings::mojom::kAppLanguagesSubpagePath;
 using ::chromeos::settings::mojom::kLanguagesAndInputSectionPath;
 using ::chromeos::settings::mojom::kLanguagesSubpagePath;
 using ::chromeos::settings::mojom::kSystemPreferencesSectionPath;
@@ -68,6 +69,18 @@
   return *tags;
 }
 
+const std::vector<SearchConcept>& GetAppLanguagesPageSearchConcepts() {
+  static const base::NoDestructor<std::vector<SearchConcept>> tags({
+      {IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES,
+       mojom::kAppLanguagesSubpagePath,
+       mojom::SearchResultIcon::kLanguage,
+       mojom::SearchResultDefaultRank::kMedium,
+       mojom::SearchResultType::kSubpage,
+       {.subpage = mojom::Subpage::kAppLanguages}},
+  });
+  return *tags;
+}
+
 void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
       {"deviceLanguageTitle", IDS_OS_SETTINGS_LANGUAGES_DEVICE_LANGUAGE_TITLE},
@@ -160,6 +173,9 @@
               : std::nullopt) {
   SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
   updater.AddSearchTags(GetLanguagesPageSearchConceptsV2());
+  if (IsPerAppLanguageEnabled(profile)) {
+    updater.AddSearchTags(GetAppLanguagesPageSearchConcepts());
+  }
 }
 
 LanguagesSection::~LanguagesSection() = default;
@@ -237,6 +253,16 @@
   RegisterNestedSettingBulk(mojom::Subpage::kLanguages, kLanguagesPageSettings,
                             generator);
 
+  if (IsPerAppLanguageEnabled(profile())) {
+    // App language subpage.
+    generator->RegisterNestedSubpage(
+        IDS_OS_SETTINGS_LANGUAGES_APP_LANGUAGES_TITLE,
+        mojom::Subpage::kAppLanguages, mojom::Subpage::kLanguages,
+        mojom::SearchResultIcon::kLanguage,
+        mojom::SearchResultDefaultRank::kMedium,
+        mojom::kAppLanguagesSubpagePath);
+  }
+
   // Inputs subsection exists only when the OsSettingsRevampWayfinding feature
   // is disabled. It is part of the Device section when the feature is enabled.
   if (!ash::features::IsOsSettingsRevampWayfindingEnabled()) {
diff --git a/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc b/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc
index 4949ad29..bdc2c53 100644
--- a/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc
+++ b/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc
@@ -4,30 +4,39 @@
 
 #include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager.h"
 
+#include "ash/components/arc/arc_features.h"
+#include "ash/components/arc/test/arc_util_test_support.h"
 #include "ash/constants/ash_features.h"
 #include "ash/webui/settings/public/constants/routes.mojom.h"
+#include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/metrics/histogram_base.h"
 #include "base/test/metrics/histogram_enum_reader.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs_factory.h"
+#include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/eche_app/eche_app_manager_factory.h"
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager_factory.h"
+#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h"
 #include "chrome/browser/ash/phonehub/phone_hub_manager_factory.h"
 #include "chrome/browser/ash/printing/cups_printers_manager_factory.h"
+#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/webui/ash/settings/constants/constants_util.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
 #include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_factory.h"
 #include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h"
 #include "chromeos/ash/components/local_search_service/search_metrics_reporter.h"
+#include "components/account_id/account_id.h"
+#include "components/user_manager/scoped_user_manager.h"
+#include "components/user_manager/user_manager.h"
+#include "components/user_manager/user_names.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/ash/mock_input_method_manager.h"
@@ -44,19 +53,32 @@
 class OsSettingsManagerTest : public testing::Test {
  protected:
   OsSettingsManagerTest()
-      : profile_manager_(TestingBrowserProcess::GetGlobal()) {}
+      : fake_user_manager_(std::make_unique<ash::FakeChromeUserManager>()),
+        profile_manager_(TestingBrowserProcess::GetGlobal()) {}
   ~OsSettingsManagerTest() override = default;
 
   // testing::Test:
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
         {ash::features::kInputDeviceSettingsSplit,
-         ash::features::kPeripheralCustomization},
+         ash::features::kPeripheralCustomization, arc::kPerAppLanguage},
         {});
     ASSERT_TRUE(profile_manager_.SetUp());
-    TestingProfile* profile =
-        profile_manager_.CreateTestingProfile("TestingProfile");
+    Profile* profile = profile_manager_.CreateTestingProfile(
+        TestingProfile::kDefaultProfileUserName);
+    // Log in user to ensure ARC PlayStore can be enabled.
+    const AccountId account_id(
+        AccountId::FromUserEmailGaiaId(profile->GetProfileUserName(), "1234"));
+    fake_user_manager_->AddUser(account_id);
+    fake_user_manager_->LoginUser(account_id);
 
+    // Enables ARC for test profile.
+    arc::SetArcAvailableCommandLineForTesting(
+        base::CommandLine::ForCurrentProcess());
+    arc::SetArcPlayStoreEnabledForProfile(profile, true);
+
+    NearbySharingServiceFactory::
+        SetIsNearbyShareSupportedForBrowserContextForTesting(false);
     local_search_service::SearchMetricsReporter::RegisterLocalStatePrefs(
         pref_service_.registry());
     local_search_service::LocalSearchServiceProxyFactory::GetInstance()
@@ -79,6 +101,8 @@
         eche_app::EcheAppManagerFactory::GetForProfile(profile));
   }
 
+  user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
+      fake_user_manager_;
   content::BrowserTaskEnvironment task_environment_;
   TestingPrefServiceSimple pref_service_;
   TestingProfileManager profile_manager_;
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
index 892ddf2..9c1c2ac5 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -33,6 +33,7 @@
 #include "components/lookalikes/core/lookalike_url_util.h"
 #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h"
 #include "components/safe_browsing/content/browser/ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/content/bad_clock_blocking_page.h"
@@ -41,7 +42,6 @@
 #include "components/security_interstitials/content/insecure_form_blocking_page.h"
 #include "components/security_interstitials/content/mitm_software_blocking_page.h"
 #include "components/security_interstitials/content/security_interstitial_page.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/https_only_mode_metrics.h"
 #include "components/security_interstitials/core/ssl_error_options_mask.h"
 #include "components/security_interstitials/core/ssl_error_ui.h"
diff --git a/chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc b/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
similarity index 74%
rename from chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc
rename to chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
index ac3d825..66b3b00 100644
--- a/chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc
+++ b/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -11,11 +11,7 @@
 #include "build/branding_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/performance_manager/public/user_tuning/battery_saver_mode_manager.h"
-#include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/views/tabs/tab.h"
-#include "chrome/browser/ui/views/tabs/tab_close_button.h"
-#include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/webui/feedback/feedback_dialog.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -24,7 +20,6 @@
 #include "components/performance_manager/public/features.h"
 #include "components/performance_manager/public/user_tuning/prefs.h"
 #include "content/public/test/browser_test.h"
-#include "net/dns/mock_host_resolver.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -37,11 +32,9 @@
 
 namespace {
 DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPerformanceSettingsPage);
-DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kSecondTabContent);
 DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kButtonWasClicked);
 DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kElementRenders);
 DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kIronCollapseContentShows);
-DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kExceptionDialogShows);
 
 constexpr char kCheckJsElementIsChecked[] = "(el) => { return el.checked; }";
 constexpr char kCheckJsElementIsNotChecked[] =
@@ -64,30 +57,13 @@
     "settings-performance-page",
     "controlled-radio-button#enabledOnTimerButton"};
 
-const WebContentsInteractionTestUtil::DeepQuery kExceptionDialogEntry = {
-    "settings-ui",
-    "settings-main",
-    "settings-basic-page",
-    "settings-performance-page",
-    "tab-discard-exception-list",
-    "tab-discard-exception-tabbed-add-dialog",
-    "tab-discard-exception-current-sites-list#list",
-    "settings-checkbox-list-entry"};
-
-const WebContentsInteractionTestUtil::DeepQuery kExceptionDialogAddButton = {
-    "settings-ui",
-    "settings-main",
-    "settings-basic-page",
-    "settings-performance-page",
-    "tab-discard-exception-list",
-    "tab-discard-exception-tabbed-add-dialog",
-    "cr-button#actionButton"};
-
 }  // namespace
 
-class MemorySaverSettingsInteractiveTest : public InteractiveBrowserTest {
+class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest {
  public:
-  void SetUp() override { InteractiveBrowserTest::SetUp(); }
+  void SetUp() override {
+    InteractiveBrowserTest::SetUp();
+  }
 
   void SetUpOnMainThread() override {
     InteractiveBrowserTest::SetUpOnMainThread();
@@ -103,22 +79,9 @@
     InteractiveBrowserTest::TearDownOnMainThread();
   }
 
-  auto WaitForElementToRender(const ui::ElementIdentifier& contents_id,
-                              const DeepQuery& element) {
-    StateChange element_renders;
-    element_renders.event = kElementRenders;
-    element_renders.where = element;
-    element_renders.test_function =
-        "(el) => { if (el !== null) { let rect = el.getBoundingClientRect(); "
-        "return rect.width > 0 && rect.height > 0; } return false; }";
-
-    return WaitForStateChange(contents_id, element_renders);
-  }
-
   auto ClickElement(const ui::ElementIdentifier& contents_id,
                     const DeepQuery& element) {
-    return Steps(WaitForElementToRender(contents_id, element),
-                 MoveMouseTo(contents_id, element), ClickMouse());
+    return Steps(MoveMouseTo(contents_id, element), ClickMouse());
   }
 
   auto CheckTabCount(int expected_tab_count) {
@@ -161,6 +124,18 @@
     return WaitForStateChange(contents_id, toggle_selection_change);
   }
 
+  auto WaitForElementToRender(const ui::ElementIdentifier& contents_id,
+                              const DeepQuery& element) {
+    StateChange element_renders;
+    element_renders.event = kElementRenders;
+    element_renders.where = element;
+    element_renders.type = StateChange::Type::kExistsAndConditionTrue;
+    element_renders.test_function =
+        "(el) => { return el.clientWidth > 0 && el.clientHeight > 0; }";
+
+    return WaitForStateChange(contents_id, element_renders);
+  }
+
   auto WaitForIronListCollapseStateChange(ui::ElementIdentifier webcontents_id,
                                           DeepQuery query) {
     StateChange iron_collapse_finish_animating;
@@ -178,7 +153,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
                        MemorySaverPrefChanged) {
   RunTestSequence(
       InstrumentTab(kPerformanceSettingsPage),
@@ -201,7 +176,7 @@
       CheckMemorySaverModePrefState(MemorySaverModeState::kEnabledOnTimer));
 }
 
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
                        MemorySaverLearnMoreLinkNavigates) {
   DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kLearnMorePage);
   const DeepQuery memory_saver_learn_more = {"settings-ui",
@@ -222,7 +197,7 @@
                               GURL(chrome::kMemorySaverModeLearnMoreUrl)));
 }
 
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
                        MemorySaverMetricsShouldLogOnToggle) {
   base::HistogramTester histogram_tester;
 
@@ -251,7 +226,7 @@
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // TODO(http://b/281528238): reenable the test.
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
                        DISABLED_MemorySaverSendFeedbackDialogOpens) {
   const DeepQuery memory_saver_feedback = {
       "settings-ui", "settings-main", "settings-basic-page",
@@ -266,8 +241,8 @@
 }
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-class MemorySaverSettingsMultiStateModeInteractiveTest
-    : public MemorySaverSettingsInteractiveTest {
+class PerformanceSettingsMultiStateModeInteractiveTest
+    : public PerformanceSettingsInteractiveTest {
  public:
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(
@@ -282,6 +257,7 @@
     StateChange toggle_selection_change;
     toggle_selection_change.event = kButtonWasClicked;
     toggle_selection_change.where = element;
+    toggle_selection_change.type = StateChange::Type::kExistsAndConditionTrue;
     toggle_selection_change.test_function =
         is_disabled ? "(el) => el.disabled === true"
                     : "(el) => el.disabled === false";
@@ -293,7 +269,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest,
                        MemorySaverPrefChanged) {
   RunTestSequence(
       InstrumentTab(kPerformanceSettingsPage),
@@ -322,7 +298,7 @@
       CheckMemorySaverModePrefState(MemorySaverModeState::kEnabled));
 }
 
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest,
                        MemorySaverMetricsShouldLogOnToggle) {
   base::HistogramTester histogram_tester;
 
@@ -374,7 +350,7 @@
 
 // Checks that the selected discard timer value is preserved as the high
 // efficiency mode gets toggled
-IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest,
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest,
                        DiscardTimerStateIsPreserved) {
   const DeepQuery discard_time_menu = {
       "settings-ui", "settings-main", "settings-basic-page",
@@ -470,6 +446,9 @@
         std::make_unique<base::test::TestSamplingEventSource>();
     auto test_battery_level_provider =
         std::make_unique<base::test::TestBatteryLevelProvider>();
+
+    sampling_source_ = test_sampling_event_source.get();
+    battery_level_provider_ = test_battery_level_provider.get();
     test_battery_level_provider->SetBatteryState(
         base::test::TestBatteryLevelProvider::CreateBatteryState(1, true, 100));
 
@@ -540,6 +519,10 @@
   }
 
  private:
+  raw_ptr<base::test::TestSamplingEventSource, DanglingUntriaged>
+      sampling_source_;
+  raw_ptr<base::test::TestBatteryLevelProvider, DanglingUntriaged>
+      battery_level_provider_;
   std::unique_ptr<base::BatteryStateSampler> battery_state_sampler_;
   base::test::ScopedFeatureList scoped_feature_list_;
 };
@@ -702,176 +685,3 @@
                               GURL("chrome://os-settings/power")));
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-class TabDiscardExceptionsSettingsInteractiveTest
-    : public MemorySaverSettingsInteractiveTest {
- public:
-  void SetUp() override {
-    scoped_feature_list_.InitAndEnableFeature(
-        performance_manager::features::kDiscardExceptionsImprovements);
-
-    InteractiveBrowserTest::SetUp();
-  }
-
-  void SetUpOnMainThread() override {
-    host_resolver()->AddRule("*", "127.0.0.1");
-    MemorySaverSettingsInteractiveTest::SetUpOnMainThread();
-  }
-
-  GURL GetTestingURL(std::string hostname) {
-    return embedded_test_server()->GetURL(hostname, "/title1.html");
-  }
-
-  auto WaitForElementToHide(const ui::ElementIdentifier& contents_id,
-                            const DeepQuery& element) {
-    StateChange element_renders;
-    element_renders.event = kElementRenders;
-    element_renders.where = element;
-    element_renders.test_function =
-        "(el) => { let rect = el.getBoundingClientRect(); return rect.width "
-        "=== 0 && rect.height === 0; }";
-
-    return WaitForStateChange(contents_id, element_renders);
-  }
-
-  auto OpenAddExceptionDialog(const ui::ElementIdentifier& contents_id) {
-    const WebContentsInteractionTestUtil::DeepQuery add_exceptions_button = {
-        "settings-ui",
-        "settings-main",
-        "settings-basic-page",
-        "settings-performance-page",
-        "tab-discard-exception-list",
-        "cr-button#addButton"};
-
-    const WebContentsInteractionTestUtil::DeepQuery picker_dialog = {
-        "settings-ui",
-        "settings-main",
-        "settings-basic-page",
-        "settings-performance-page",
-        "tab-discard-exception-list",
-        "tab-discard-exception-tabbed-add-dialog"};
-
-    const WebContentsInteractionTestUtil::DeepQuery tab_picker_tab = {
-        "settings-ui",
-        "settings-main",
-        "settings-basic-page",
-        "settings-performance-page",
-        "tab-discard-exception-list",
-        "tab-discard-exception-tabbed-add-dialog",
-        "cr-tabs",
-        "div.tab"};
-
-    StateChange exceptions_dialog;
-    exceptions_dialog.event = kExceptionDialogShows;
-    exceptions_dialog.where = picker_dialog;
-    return Steps(ClickElement(contents_id, add_exceptions_button),
-                 WaitForStateChange(contents_id, exceptions_dialog),
-                 ClickElement(contents_id, tab_picker_tab));
-  }
-
-  auto WaitForDisabledStateChange(const ui::ElementIdentifier& contents_id,
-                                  const DeepQuery element,
-                                  bool is_disabled) {
-    StateChange toggle_selection_change;
-    toggle_selection_change.event = kButtonWasClicked;
-    toggle_selection_change.where = element;
-    toggle_selection_change.type = StateChange::Type::kExistsAndConditionTrue;
-    toggle_selection_change.test_function =
-        is_disabled ? "(el) => el.disabled === true"
-                    : "(el) => el.disabled === false";
-
-    return WaitForStateChange(contents_id, toggle_selection_change);
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest,
-                       AddSiteToExceptionList) {
-  const WebContentsInteractionTestUtil::DeepQuery exception_entry = {
-      "settings-ui",
-      "settings-main",
-      "settings-basic-page",
-      "settings-performance-page",
-      "tab-discard-exception-list",
-      "tab-discard-exception-entry"};
-
-  RunTestSequence(
-      InstrumentTab(kPerformanceSettingsPage),
-      NavigateWebContents(kPerformanceSettingsPage,
-                          GURL(chrome::kChromeUIPerformanceSettingsURL)),
-      WaitForWebContentsReady(kPerformanceSettingsPage,
-                              GURL(chrome::kChromeUIPerformanceSettingsURL)),
-      AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")),
-      SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage),
-      OpenAddExceptionDialog(kPerformanceSettingsPage),
-      WaitForDisabledStateChange(kPerformanceSettingsPage,
-                                 kExceptionDialogAddButton, true),
-      ClickElement(kPerformanceSettingsPage, kExceptionDialogEntry),
-      WaitForDisabledStateChange(kPerformanceSettingsPage,
-                                 kExceptionDialogAddButton, false),
-      ClickElement(kPerformanceSettingsPage, kExceptionDialogAddButton),
-      WaitForElementToRender(kPerformanceSettingsPage, exception_entry));
-}
-
-// The high efficiency tab picker should live update when the user open or
-// closes a tab that can be added to the exceptions list
-IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest,
-                       UpdatesEntryListLive) {
-  constexpr char tab_close_button[] = "tab_close_button";
-
-  RunTestSequence(
-      InstrumentTab(kPerformanceSettingsPage),
-      NavigateWebContents(kPerformanceSettingsPage,
-                          GURL(chrome::kChromeUIPerformanceSettingsURL)),
-      // Make sure there is no entry in the tab picker since there are no other
-      // tabs open
-      OpenAddExceptionDialog(kPerformanceSettingsPage),
-      EnsureNotPresent(kPerformanceSettingsPage, kExceptionDialogEntry),
-
-      // Dialog should show new entry when opening a new tab
-      AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")),
-      SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage),
-      WaitForElementToRender(kPerformanceSettingsPage, kExceptionDialogEntry),
-
-      // Dialog entry should hide when its corresponding tab is closed
-      NameViewRelative(kTabStripElementId, tab_close_button,
-                       base::BindOnce([](TabStrip* tab_strip) {
-                         return tab_strip->tab_at(1)->close_button().get();
-                       })),
-      PressButton(tab_close_button),
-      WaitForElementToHide(kPerformanceSettingsPage, kExceptionDialogEntry));
-}
-
-// The high efficiency exceptions tab picker should only show sites that are
-// non-chrome sites and have not been added to the exceptions list yet
-IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest,
-                       IgnoreIneligibleTabs) {
-  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kThirdTabContent);
-
-  RunTestSequence(
-      InstrumentTab(kPerformanceSettingsPage),
-      NavigateWebContents(kPerformanceSettingsPage,
-                          GURL(chrome::kChromeUIPerformanceSettingsURL)),
-      // Open a new tab navigated to a non-chrome site
-      AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")),
-      SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage),
-
-      // Add the non-chrome site to the exceptions list
-      OpenAddExceptionDialog(kPerformanceSettingsPage),
-      ClickElement(kPerformanceSettingsPage, kExceptionDialogEntry),
-      WaitForDisabledStateChange(kPerformanceSettingsPage,
-                                 kExceptionDialogAddButton, false),
-      ClickElement(kPerformanceSettingsPage, kExceptionDialogAddButton),
-
-      // Re-open the tab picker and verify that the excluded tab doesn't show
-      OpenAddExceptionDialog(kPerformanceSettingsPage),
-      EnsureNotPresent(kPerformanceSettingsPage, kExceptionDialogEntry),
-
-      // Verify that opening a new tab navigated to a non-excluded site will
-      // produce a new entry in the tab picker
-      AddInstrumentedTab(kThirdTabContent, GetTestingURL("second.com")),
-      SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage),
-      WaitForElementToRender(kPerformanceSettingsPage, kExceptionDialogEntry));
-}
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 2d4cce63..468a69a 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -658,6 +658,9 @@
       "//chrome/browser/ash/system_web_apps/types",
     ]
   }
+  if (is_chromeos) {
+    deps += [ "//chromeos/constants" ]
+  }
 }
 
 # This has to be a separate target to avoid circular dependencies with
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
index c72cc6de..eab28c3 100644
--- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -29,6 +29,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(IS_CHROMEOS)
+#include "chromeos/constants/chromeos_features.h"
+#endif
+
 namespace web_app {
 namespace test {
 
@@ -86,32 +90,40 @@
                              std::unique_ptr<WebAppInstallInfo> web_app_info,
                              bool overwrite_existing_manifest_fields,
                              webapps::WebappInstallSource install_source) {
+  // Use InstallShortcut for Create Shortcut install source.
+  CHECK_NE(install_source, webapps::WebappInstallSource::MENU_CREATE_SHORTCUT);
+
   // The sync system requires that sync entity name is never empty.
   if (web_app_info->title.empty())
     web_app_info->title = u"WebAppInstallInfo App Name";
 
+#if BUILDFLAG(IS_CHROMEOS)
+  // In Shortstand, user-installed web app should always have a scope.
+  if (chromeos::features::IsCrosShortstandEnabled() &&
+      web_app_info->scope.is_empty()) {
+    web_app_info->scope = web_app_info->start_url;
+  }
+#endif
+
   webapps::AppId app_id;
-  base::RunLoop run_loop;
+  base::test::TestFuture<const webapps::AppId&, webapps::InstallResultCode>
+      future;
   auto* provider = WebAppProvider::GetForTest(profile);
   DCHECK(provider);
   WaitUntilReady(provider);
   // In unit tests, we do not have Browser or WebContents instances. Hence we
   // use `InstallFromInfoCommand` instead of `FetchManifestAndInstallCommand` or
   // `WebAppInstallCommand` to install the web app.
-  provider->scheduler().InstallFromInfo(
-      std::move(web_app_info), overwrite_existing_manifest_fields,
-      install_source,
-      base::BindLambdaForTesting([&](const webapps::AppId& installed_app_id,
-                                     webapps::InstallResultCode code) {
-        EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall, code);
-        app_id = installed_app_id;
-        run_loop.Quit();
-      }));
+  provider->scheduler().InstallFromInfo(std::move(web_app_info),
+                                        overwrite_existing_manifest_fields,
+                                        install_source, future.GetCallback());
 
-  run_loop.Run();
+  EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall,
+            future.Get<webapps::InstallResultCode>());
   // Allow updates to be published to App Service listeners.
   base::RunLoop().RunUntilIdle();
-  return app_id;
+
+  return future.Get<webapps::AppId>();
 }
 
 webapps::AppId InstallShortcut(Profile* profile,
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 88ba302..9f2b8ded1 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1703030261-3e81724e2d506c761ac86b6ed1f72bea16d31813.profdata
+chrome-android32-main-1703051928-7709a5363b727067cafa77e72fc93fee3f027c89.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 996b3f61..49d9fcd 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1703030261-051082be6ecb7ab4cf24c3f74d66399611678cbf.profdata
+chrome-android64-main-1703051928-8af698ea242be2dd48257b2f6857067311670b47.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 33fdd47..24e2298 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1703008763-9170b64889c50a5a466311742c287b2ffaf80184.profdata
+chrome-linux-main-1703051928-d7054369ede80cf828e08659f213b7be6554a98d.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 7cf89de2..0a9fd20 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1703023000-e9a3d0c545f1db78e55693cd6d67e6d40ee762f9.profdata
+chrome-mac-arm-main-1703066398-4c184c33dd2e61ddcbce228ebd3419a217eafa78.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 990fc63a..9a52284 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1703008763-aeb33e02834b2a86fa46ce77f8d0c513427fc6ca.profdata
+chrome-mac-main-1703051928-cd57a5b874db8300c855b1ce22c65d86127ea377.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 9d1476cf..b8408a7 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1703008763-ecdc5bfcce46b47dc1830691a2c0277420a0b1d3.profdata
+chrome-win-arm64-main-1703030261-e65c9ccbe5fc04c4c698e5ab479331b660bea4c1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 855937aa..7b68c56 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1703008763-6a9fee6c9c61d020644b893a2a648bebf093e4d1.profdata
+chrome-win64-main-1703051928-63c641bef4765ac151a13fa0ef435026758d0fbe.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 91bd5fd..a72f5e72 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -10543,6 +10543,10 @@
       deps += [ "//extensions/browser" ]
     }
 
+    if (is_chromeos) {
+      deps += [ "//chromeos/constants" ]
+    }
+
     if (is_chromeos_lacros) {
       deps += [
         "//chromeos/lacros",
@@ -10778,6 +10782,7 @@
       "../browser/ui/webui/access_code_cast/access_code_cast_dialog_browsertest.cc",
       "../browser/ui/webui/access_code_cast/access_code_cast_handler_browsertest.cc",
       "../browser/ui/webui/downloads/downloads_page_interactive_uitest.cc",
+      "../browser/ui/webui/settings/performance_settings_interactive_uitest.cc",
       "../browser/ui/webui/settings/settings_interactive_uitest.cc",
       "../browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_interactive_uitest.cc",
       "../browser/webapps/web_app_offline_browsertest.cc",
@@ -11057,7 +11062,6 @@
         "../browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc",
         "../browser/ui/views/passwords/password_bubble_interactive_uitest.cc",
         "../browser/ui/views/performance_controls/memory_saver_interactive_ui_test.cc",
-        "../browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc",
         "../browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc",
         "../browser/ui/views/permissions/one_time_permission_interactive_ui_test.cc",
         "../browser/ui/views/permissions/permission_bubble_interactive_uitest.cc",
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts b/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts
index 11c4c294..0c846825 100644
--- a/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts
+++ b/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts
@@ -440,4 +440,62 @@
         assertEquals(localTaskCard.style.display, 'none');
         assertTrue(actionButton.disabled);
       });
+
+  /**
+   * Test that clicking the cancel button triggers the right
+   * `respondWithUserActionAndClose` mojo request.
+   */
+  test('Cancel', async () => {
+    const numTasks = 5;
+    await setUp({
+      fileNames: ['file.docx'],
+      officeWebAppInstalled: true,
+      installOfficeWebAppResult: false,
+      odfsMounted: false,
+      dialogSpecificArgs: {
+        fileHandlerDialogArgs: {
+          localTasks: createTasks(numTasks),
+          showGoogleWorkspaceTask: true,
+          showMicrosoftOfficeTask: true,
+        },
+      },
+    });
+
+    fileHandlerPageApp.$('.cancel-button').click();
+    await testProxy.handler.whenCalled('respondWithUserActionAndClose');
+    assertEquals(
+        1, testProxy.handler.getCallCount('respondWithUserActionAndClose'));
+    assertDeepEquals(
+        [UserAction.kCancel],
+        testProxy.handler.getArgs('respondWithUserActionAndClose'));
+  });
+
+  /**
+   * Test that an Escape keydown triggers the right
+   * `respondWithUserActionAndClose` mojo request.
+   */
+  test('Escape', async () => {
+    const numTasks = 5;
+    await setUp({
+      fileNames: ['file.docx'],
+      officeWebAppInstalled: true,
+      installOfficeWebAppResult: false,
+      odfsMounted: false,
+      dialogSpecificArgs: {
+        fileHandlerDialogArgs: {
+          localTasks: createTasks(numTasks),
+          showGoogleWorkspaceTask: true,
+          showMicrosoftOfficeTask: true,
+        },
+      },
+    });
+
+    document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'}));
+    await testProxy.handler.whenCalled('respondWithUserActionAndClose');
+    assertEquals(
+        1, testProxy.handler.getCallCount('respondWithUserActionAndClose'));
+    assertDeepEquals(
+        [UserAction.kCancel],
+        testProxy.handler.getArgs('respondWithUserActionAndClose'));
+  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts
index d8872e5..7b423ad 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts
@@ -10,13 +10,11 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
-import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
-let subpage: BruschettaSubpageElement;
-let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
 interface PrefParams {
   sharedPaths?: {[key: string]: string[]};
@@ -26,38 +24,37 @@
   bruschettaInstalled?: boolean;
 }
 
-function setCrostiniPrefs(enabled: boolean, {
-  sharedPaths = {},
-  forwardedPorts = [],
-  micAllowed = false,
-  arcEnabled = false,
-  bruschettaInstalled = false,
-}: PrefParams = {}): void {
-  subpage.prefs = {
-    arc: {
-      enabled: {value: arcEnabled},
-    },
-    bruschetta: {
-      installed: {
-        value: bruschettaInstalled,
-      },
-    },
-    crostini: {
-      enabled: {value: enabled},
-      mic_allowed: {value: micAllowed},
-      port_forwarding: {ports: {value: forwardedPorts}},
-    },
-    guest_os: {
-      paths_shared_to_vms: {value: sharedPaths},
-    },
-  };
-  flush();
-}
-
 suite('<settings-bruschetta-subpage>', () => {
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-  });
+  let subpage: BruschettaSubpageElement;
+  let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+
+  function setCrostiniPrefs(enabled: boolean, {
+    sharedPaths = {},
+    forwardedPorts = [],
+    micAllowed = false,
+    arcEnabled = false,
+    bruschettaInstalled = false,
+  }: PrefParams = {}): void {
+    subpage.prefs = {
+      arc: {
+        enabled: {value: arcEnabled},
+      },
+      bruschetta: {
+        installed: {
+          value: bruschettaInstalled,
+        },
+      },
+      crostini: {
+        enabled: {value: enabled},
+        mic_allowed: {value: micAllowed},
+        port_forwarding: {ports: {value: forwardedPorts}},
+      },
+      guest_os: {
+        paths_shared_to_vms: {value: sharedPaths},
+      },
+    };
+    flush();
+  }
 
   setup(async () => {
     loadTimeData.overrideValues({
@@ -70,16 +67,15 @@
 
     Router.getInstance().navigateTo(routes.BRUSCHETTA_DETAILS);
 
+    clearBody();
     subpage = document.createElement('settings-bruschetta-subpage');
     document.body.appendChild(subpage);
     setCrostiniPrefs(false, {bruschettaInstalled: true});
-    flushTasks();
+    await flushTasks();
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
   });
 
   test('Navigate to shared USB devices', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts
index 73aed526..96b6776 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts
@@ -11,10 +11,9 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 import {isVisible} from 'chrome://webui-test/test_util.js';
 
-let subpage: SettingsCrostiniArcAdbElement;
+import {clearBody} from '../utils.js';
 
 interface PrefParams {
   sharedPaths?: {[key: string]: string[]};
@@ -24,38 +23,36 @@
   bruschettaInstalled?: boolean;
 }
 
-function setCrostiniPrefs(enabled: boolean, {
-  sharedPaths = {},
-  forwardedPorts = [],
-  micAllowed = false,
-  arcEnabled = false,
-  bruschettaInstalled = false,
-}: PrefParams = {}): void {
-  subpage.prefs = {
-    arc: {
-      enabled: {value: arcEnabled},
-    },
-    bruschetta: {
-      installed: {
-        value: bruschettaInstalled,
-      },
-    },
-    crostini: {
-      enabled: {value: enabled},
-      mic_allowed: {value: micAllowed},
-      port_forwarding: {ports: {value: forwardedPorts}},
-    },
-    guest_os: {
-      paths_shared_to_vms: {value: sharedPaths},
-    },
-  };
-  flush();
-}
-
 suite('<settings-crostini-arc-adb>', () => {
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-  });
+  let subpage: SettingsCrostiniArcAdbElement;
+
+  function setCrostiniPrefs(enabled: boolean, {
+    sharedPaths = {},
+    forwardedPorts = [],
+    micAllowed = false,
+    arcEnabled = false,
+    bruschettaInstalled = false,
+  }: PrefParams = {}): void {
+    subpage.prefs = {
+      arc: {
+        enabled: {value: arcEnabled},
+      },
+      bruschetta: {
+        installed: {
+          value: bruschettaInstalled,
+        },
+      },
+      crostini: {
+        enabled: {value: enabled},
+        mic_allowed: {value: micAllowed},
+        port_forwarding: {ports: {value: forwardedPorts}},
+      },
+      guest_os: {
+        paths_shared_to_vms: {value: sharedPaths},
+      },
+    };
+    flush();
+  }
 
   setup(async () => {
     loadTimeData.overrideValues({
@@ -65,6 +62,8 @@
     });
 
     Router.getInstance().navigateTo(routes.CROSTINI_ANDROID_ADB);
+
+    clearBody();
     subpage = document.createElement('settings-crostini-arc-adb');
     document.body.appendChild(subpage);
     setCrostiniPrefs(true, {arcEnabled: true});
@@ -72,7 +71,6 @@
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts
index 01a908f..5097003 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts
@@ -12,45 +12,13 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 import {isVisible} from 'chrome://webui-test/test_util.js';
 
 import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
 import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
-let subpage: SettingsCrostiniExportImportElement;
-let guestOsBrowserProxy: TestGuestOsBrowserProxy;
-let crostiniBrowserProxy: TestCrostiniBrowserProxy;
-
-const singleContainer: ContainerInfo[] = [
-  {
-    id: {
-      vm_name: 'termina',
-      container_name: 'penguin',
-    },
-    ipv4: '1.2.3.4',
-  },
-];
-
-const multipleContainers: ContainerInfo[] = [
-  {
-    id: {
-      vm_name: 'termina',
-      container_name: 'penguin',
-    },
-    ipv4: '1.2.3.4',
-  },
-  {
-    id: {
-      vm_name: 'not-termina',
-      container_name: 'not-penguin',
-
-    },
-    ipv4: '1.2.3.5',
-  },
-];
-
 interface PrefParams {
   sharedPaths?: {[key: string]: string[]};
   forwardedPorts?: CrostiniPortSetting[];
@@ -59,48 +27,75 @@
   bruschettaInstalled?: boolean;
 }
 
-function setCrostiniPrefs(enabled: boolean, {
-  sharedPaths = {},
-  forwardedPorts = [],
-  micAllowed = false,
-  arcEnabled = false,
-  bruschettaInstalled = false,
-}: PrefParams = {}): void {
-  subpage.prefs = {
-    arc: {
-      enabled: {value: arcEnabled},
-    },
-    bruschetta: {
-      installed: {
-        value: bruschettaInstalled,
-      },
-    },
-    crostini: {
-      enabled: {value: enabled},
-      mic_allowed: {value: micAllowed},
-      port_forwarding: {ports: {value: forwardedPorts}},
-    },
-    guest_os: {
-      paths_shared_to_vms: {value: sharedPaths},
-    },
-  };
-  flush();
-}
-
-function selectContainerByIndex(
-    select: ContainerSelectElement, index: number): void {
-  const mdSelect = select.shadowRoot!.querySelector<HTMLSelectElement>(
-      'select#selectContainer.md-select');
-  assertTrue(!!mdSelect);
-  mdSelect.selectedIndex = index;
-  mdSelect.dispatchEvent(new CustomEvent('change'));
-  flush();
-}
-
 suite('<settings-crostini-export-import>', () => {
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-  });
+  let subpage: SettingsCrostiniExportImportElement;
+  let guestOsBrowserProxy: TestGuestOsBrowserProxy;
+  let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+
+  const multipleContainers: ContainerInfo[] = [
+    {
+      id: {
+        vm_name: 'termina',
+        container_name: 'penguin',
+      },
+      ipv4: '1.2.3.4',
+    },
+    {
+      id: {
+        vm_name: 'not-termina',
+        container_name: 'not-penguin',
+
+      },
+      ipv4: '1.2.3.5',
+    },
+  ];
+  const singleContainer: ContainerInfo[] = [
+    {
+      id: {
+        vm_name: 'termina',
+        container_name: 'penguin',
+      },
+      ipv4: '1.2.3.4',
+    },
+  ];
+
+  function setCrostiniPrefs(enabled: boolean, {
+    sharedPaths = {},
+    forwardedPorts = [],
+    micAllowed = false,
+    arcEnabled = false,
+    bruschettaInstalled = false,
+  }: PrefParams = {}): void {
+    subpage.prefs = {
+      arc: {
+        enabled: {value: arcEnabled},
+      },
+      bruschetta: {
+        installed: {
+          value: bruschettaInstalled,
+        },
+      },
+      crostini: {
+        enabled: {value: enabled},
+        mic_allowed: {value: micAllowed},
+        port_forwarding: {ports: {value: forwardedPorts}},
+      },
+      guest_os: {
+        paths_shared_to_vms: {value: sharedPaths},
+      },
+    };
+    flush();
+  }
+
+  function selectContainerByIndex(
+      select: ContainerSelectElement, index: number): void {
+    const mdSelect = select.shadowRoot!.querySelector<HTMLSelectElement>(
+        'select#selectContainer.md-select');
+    assertTrue(!!mdSelect);
+    mdSelect.selectedIndex = index;
+    mdSelect.dispatchEvent(new CustomEvent('change'));
+    flush();
+  }
 
   setup(async () => {
     loadTimeData.overrideValues({
@@ -113,7 +108,6 @@
       arcAdbSideloadingSupported: true,
       showCrostiniExtraContainers: true,
     });
-
     crostiniBrowserProxy = new TestCrostiniBrowserProxy();
     crostiniBrowserProxy.containerInfo = singleContainer;
     CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
@@ -121,6 +115,8 @@
     GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
 
     Router.getInstance().navigateTo(routes.CROSTINI_EXPORT_IMPORT);
+
+    clearBody();
     subpage = document.createElement('settings-crostini-export-import');
     document.body.appendChild(subpage);
     setCrostiniPrefs(true, {arcEnabled: true});
@@ -136,10 +132,7 @@
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
-    guestOsBrowserProxy.reset();
   });
 
   test('Deep link to backup linux', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts
index 5379dbb..af36452 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts
@@ -10,7 +10,8 @@
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
+
+import {clearBody} from '../utils.js';
 
 import {SharedVmDevices, TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
@@ -18,10 +19,6 @@
   let crostiniBrowserProxy: TestCrostiniBrowserProxy;
   let subpage: ExtraContainersElement;
 
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-  });
-
   setup(async () => {
     const allContainers: ContainerInfo[] = [
       {
@@ -54,12 +51,13 @@
     ];
 
     crostiniBrowserProxy = new TestCrostiniBrowserProxy();
-    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
     crostiniBrowserProxy.containerInfo = allContainers;
     crostiniBrowserProxy.sharedVmDevices = sharedVmDevices;
+    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
 
     Router.getInstance().navigateTo(routes.CROSTINI_EXTRA_CONTAINERS);
 
+    clearBody();
     subpage = document.createElement('settings-crostini-extra-containers');
     subpage.prefs = {
       crostini: {
@@ -75,9 +73,7 @@
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
   });
 
   suite('CreateContainerDialog', () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts
index dfcac79c..1cc925cc 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts
@@ -12,14 +12,15 @@
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
 
 import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
 import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
-let crostiniPage: SettingsCrostiniPageElement;
-let guestOsBrowserProxy: TestGuestOsBrowserProxy;
-let crostiniBrowserProxy: TestCrostiniBrowserProxy;
-
 suite('<settings-crostini-page>', () => {
+  let crostiniPage: SettingsCrostiniPageElement;
+  let guestOsBrowserProxy: TestGuestOsBrowserProxy;
+  let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+
   function setCrostiniPrefs(enabled: boolean, {
     sharedPaths = {},
     forwardedPorts = [],
@@ -59,13 +60,14 @@
     GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
 
     Router.getInstance().navigateTo(routes.CROSTINI);
+
+    clearBody();
     crostiniPage = document.createElement('settings-crostini-page');
     document.body.appendChild(crostiniPage);
     flush();
   });
 
   teardown(() => {
-    crostiniPage.remove();
     Router.getInstance().resetRouteForTesting();
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts
index b48a25b..e0d4552 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts
@@ -12,10 +12,10 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
 import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
@@ -66,22 +66,13 @@
   }
 
   async function createCrostiniSettingsCard(): Promise<void> {
+    clearBody();
     crostiniSettingsCard = document.createElement('crostini-settings-card');
     document.body.appendChild(crostiniSettingsCard);
-    disableAnimationsAndTransitions();
-
     setCrostiniPrefs(false);
     await flushTasks();
   }
 
-  suiteSetup(() => {
-    crostiniBrowserProxy = new TestCrostiniBrowserProxy();
-    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
-
-    guestOsBrowserProxy = new TestGuestOsBrowserProxy();
-    GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
-  });
-
   setup(() => {
     loadTimeData.overrideValues({
       isCrostiniAllowed: true,
@@ -89,14 +80,17 @@
       showBruschetta: false,
     });
 
+    crostiniBrowserProxy = new TestCrostiniBrowserProxy();
+    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
+
+    guestOsBrowserProxy = new TestGuestOsBrowserProxy();
+    GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
+
     Router.getInstance().navigateTo(hostRoute);
   });
 
   teardown(() => {
-    crostiniSettingsCard.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
-    guestOsBrowserProxy.reset();
   });
 
   test('NotSupported', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts
index d385372..cc5402ee 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts
@@ -9,64 +9,58 @@
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 
 import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
 import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
-let subpage: CrostiniSharedUsbDevicesElement;
-let guestOsBrowserProxy: TestGuestOsBrowserProxy;
-let crostiniBrowserProxy: TestCrostiniBrowserProxy;
-
-const multipleContainers: ContainerInfo[] = [
-  {
-    id: {
-      vm_name: 'termina',
-      container_name: 'penguin',
-    },
-    ipv4: '1.2.3.4',
-  },
-  {
-    id: {
-      vm_name: 'not-termina',
-      container_name: 'not-penguin',
-
-    },
-    ipv4: '1.2.3.5',
-  },
-];
-
 suite('<settings-crostini-shared-usb-devices>', () => {
+  let subpage: CrostiniSharedUsbDevicesElement;
+  let guestOsBrowserProxy: TestGuestOsBrowserProxy;
+  let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+
+  const multipleContainers: ContainerInfo[] = [
+    {
+      id: {
+        vm_name: 'termina',
+        container_name: 'penguin',
+      },
+      ipv4: '1.2.3.4',
+    },
+    {
+      id: {
+        vm_name: 'not-termina',
+        container_name: 'not-penguin',
+
+      },
+      ipv4: '1.2.3.5',
+    },
+  ];
+
   async function initSubpage(): Promise<void> {
+    clearBody();
     subpage = document.createElement('settings-crostini-shared-usb-devices');
     document.body.appendChild(subpage);
     await flushTasks();
   }
 
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-
-    crostiniBrowserProxy = new TestCrostiniBrowserProxy();
-    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
-    guestOsBrowserProxy = new TestGuestOsBrowserProxy();
-    GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
-  });
-
   setup(() => {
     loadTimeData.overrideValues({
       isCrostiniAllowed: true,
       isCrostiniSupported: true,
     });
 
+    crostiniBrowserProxy = new TestCrostiniBrowserProxy();
+    CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy);
+    guestOsBrowserProxy = new TestGuestOsBrowserProxy();
+    GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
+
     Router.getInstance().navigateTo(routes.CROSTINI_SHARED_USB_DEVICES);
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
-    guestOsBrowserProxy.reset();
   });
 
   // Functionality is already tested in OSSettingsGuestOsSharedUsbDevicesTest,
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts
index b99cc92..a94bd4d 100644
--- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts
@@ -11,19 +11,13 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertGE, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
 import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';
 
 import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js';
+import {clearBody} from '../utils.js';
 
 import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js';
 
-let subpage: SettingsCrostiniSubpageElement;
-let guestOsBrowserProxy: TestGuestOsBrowserProxy;
-let crostiniBrowserProxy: TestCrostiniBrowserProxy;
-
-const MIC_ALLOWED_PREF_PATH = 'prefs.crostini.mic_allowed.value';
-
 interface PrefParams {
   sharedPaths?: {[key: string]: string[]};
   forwardedPorts?: CrostiniPortSetting[];
@@ -32,38 +26,40 @@
   bruschettaInstalled?: boolean;
 }
 
-function setCrostiniPrefs(enabled: boolean, {
-  sharedPaths = {},
-  forwardedPorts = [],
-  micAllowed = false,
-  arcEnabled = false,
-  bruschettaInstalled = false,
-}: PrefParams = {}): void {
-  subpage.prefs = {
-    arc: {
-      enabled: {value: arcEnabled},
-    },
-    bruschetta: {
-      installed: {
-        value: bruschettaInstalled,
-      },
-    },
-    crostini: {
-      enabled: {value: enabled},
-      mic_allowed: {value: micAllowed},
-      port_forwarding: {ports: {value: forwardedPorts}},
-    },
-    guest_os: {
-      paths_shared_to_vms: {value: sharedPaths},
-    },
-  };
-  flush();
-}
-
 suite('<settings-crostini-subpage>', () => {
-  suiteSetup(() => {
-    disableAnimationsAndTransitions();
-  });
+  let subpage: SettingsCrostiniSubpageElement;
+  let guestOsBrowserProxy: TestGuestOsBrowserProxy;
+  let crostiniBrowserProxy: TestCrostiniBrowserProxy;
+
+  const MIC_ALLOWED_PREF_PATH = 'prefs.crostini.mic_allowed.value';
+
+  function setCrostiniPrefs(enabled: boolean, {
+    sharedPaths = {},
+    forwardedPorts = [],
+    micAllowed = false,
+    arcEnabled = false,
+    bruschettaInstalled = false,
+  }: PrefParams = {}): void {
+    subpage.prefs = {
+      arc: {
+        enabled: {value: arcEnabled},
+      },
+      bruschetta: {
+        installed: {
+          value: bruschettaInstalled,
+        },
+      },
+      crostini: {
+        enabled: {value: enabled},
+        mic_allowed: {value: micAllowed},
+        port_forwarding: {ports: {value: forwardedPorts}},
+      },
+      guest_os: {
+        paths_shared_to_vms: {value: sharedPaths},
+      },
+    };
+    flush();
+  }
 
   setup(async () => {
     loadTimeData.overrideValues({
@@ -83,6 +79,8 @@
     GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy);
 
     Router.getInstance().navigateTo(routes.CROSTINI_DETAILS);
+
+    clearBody();
     subpage = document.createElement('settings-crostini-subpage');
     document.body.appendChild(subpage);
     setCrostiniPrefs(true, {arcEnabled: true});
@@ -90,10 +88,7 @@
   });
 
   teardown(() => {
-    subpage.remove();
     Router.getInstance().resetRouteForTesting();
-    crostiniBrowserProxy.reset();
-    guestOsBrowserProxy.reset();
   });
 
   suite('Subpage default', () => {
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts
index ce0f386..f9c0e6bb 100644
--- a/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts
@@ -919,6 +919,10 @@
     });
 
     test('simulate noise cancellation', async () => {
+      const mockController = new MockController();
+      const setNoiseCancellationEnabled = mockController.createFunctionMock(
+          crosAudioConfig, 'setNoiseCancellationEnabled');
+
       const noiseCancellationSubsection = audioPage.shadowRoot!.querySelector(
           '#audioInputNoiseCancellationSubsection');
       const noiseCancellationToggle =
@@ -934,6 +938,9 @@
 
       assertTrue(isVisible(noiseCancellationSubsection));
       assertTrue(noiseCancellationToggle.checked);
+      assertEquals(
+          /* expected_call_count */ 1,
+          setNoiseCancellationEnabled['calls_'].length);
 
       crosAudioConfig.setAudioSystemProperties(
           noiseCancellationNotSupportedAudioSystemProperties);
@@ -991,7 +998,9 @@
       assertTrue(outputSlider.disabled);
     });
 
-    test('noise cancellation called twice with same value', async () => {
+    test('noise cancellation after system properties change', async () => {
+      // System properties change should not trigger setNoiseCancellationEnabled
+      // to be called.
       const mockController = new MockController();
       const setNoiseCancellationEnabled = mockController.createFunctionMock(
           crosAudioConfig, 'setNoiseCancellationEnabled');
@@ -1013,7 +1022,7 @@
       await flushTasks();
 
       assertEquals(
-          /* expected_call_count */ 1,
+          /* expected_call_count */ 0,
           setNoiseCancellationEnabled['calls_'].length);
     });
 
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts
index 93140c2f..ce1d561b 100644
--- a/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts
@@ -6,8 +6,8 @@
 
 import {CrLinkRowElement, DevicePageBrowserProxyImpl, displaySettingsProviderMojom, Router, routes, setDisplayApiForTesting, setDisplaySettingsProviderForTesting, SettingsDisplayElement, SettingsDropdownMenuElement, SettingsSliderElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js';
 import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js';
-import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js';
 import {assert} from 'chrome://resources/js/assert.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {flush, microTask} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
@@ -23,6 +23,8 @@
 const kDisplayIdPrefix = '123456789';
 
 suite('<settings-display>', () => {
+  const isRevampWayfindingEnabled =
+      loadTimeData.getBoolean('isRevampWayfindingEnabled');
   let displayPage: SettingsDisplayElement;
   let fakeSystemDisplay: FakeSystemDisplay;
   let browserProxy: any;
@@ -476,10 +478,12 @@
           assertEquals(90, displayPage.displays[1]!.rotation);
 
           // Mirror the displays.
-          const displayMirrorCheckbox = strictQuery(
-              '#displayMirrorCheckbox', displayPage.shadowRoot, HTMLElement);
-          assertTrue(!!displayMirrorCheckbox);
-          displayMirrorCheckbox.click();
+          const mirrorDisplayControl = strictQuery(
+              isRevampWayfindingEnabled ? '#mirrorDisplayToggle' :
+                                          '#displayMirrorCheckbox',
+              displayPage.shadowRoot, HTMLElement);
+          assertTrue(!!mirrorDisplayControl);
+          mirrorDisplayControl.click();
           flush();
 
           fakeSystemDisplay.onDisplayChanged.callListeners();
@@ -559,12 +563,13 @@
     assertEquals(2, displayPage.displays.length);
     assertTrue(displayPage.shouldShowArrangementSection());
 
-    const deepLinkElement =
-        displayPage.shadowRoot!.querySelector('#displayMirrorCheckbox')!
-            .shadowRoot!.querySelector('#checkbox');
-    await waitAfterNextRender(deepLinkElement as HTMLElement);
+    const deepLinkElement = displayPage.shadowRoot!.querySelector<HTMLElement>(
+        isRevampWayfindingEnabled ? '#mirrorDisplayToggle' :
+                                    '#displayMirrorCheckbox');
+    assertTrue(!!deepLinkElement);
+    await waitAfterNextRender(deepLinkElement);
     assertEquals(
-        deepLinkElement, getDeepActiveElement(),
+        deepLinkElement, displayPage.shadowRoot!.activeElement,
         'Display mirroring checkbox should be focused for settingId=428.');
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index 488a90d..ece5fab 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -537,7 +537,24 @@
      ]
    }
  ],
- ['DevicePageDisplayPage', 'device_page/display_page_test.js'],
+ [
+   'DevicePageDisplayPage',
+   'device_page/display_page_test.js',
+   {
+     disabled: [
+       'ash::features::kOsSettingsRevampWayfinding',
+     ],
+   },
+ ],
+ [
+   'DevicePageDisplayPageRevamp',
+   'device_page/display_page_test.js',
+   {
+     enabled: [
+       'ash::features::kOsSettingsRevampWayfinding',
+     ],
+   },
+ ],
  [
    'DevicePageDisplaySettingsMojoInterfaceProvider',
    'device_page/display_settings_mojo_interface_provider_test.js'
diff --git a/chrome/test/data/webui/settings/chromeos/utils.ts b/chrome/test/data/webui/settings/chromeos/utils.ts
index e89e5ef..5acff50 100644
--- a/chrome/test/data/webui/settings/chromeos/utils.ts
+++ b/chrome/test/data/webui/settings/chromeos/utils.ts
@@ -109,3 +109,10 @@
   }
   return root.querySelector(lastSelector);
 }
+
+/**
+ * Clears the document body HTML.
+ */
+export function clearBody() {
+  document.body.innerHTML = window.trustedTypes!.emptyHTML;
+}
diff --git a/chrome/updater/util/unit_test_util_win.cc b/chrome/updater/util/unit_test_util_win.cc
index 8003962..6e1a8b8 100644
--- a/chrome/updater/util/unit_test_util_win.cc
+++ b/chrome/updater/util/unit_test_util_win.cc
@@ -14,8 +14,12 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/win/atl.h"
 #include "base/win/registry.h"
 #include "chrome/updater/updater_scope.h"
+#include "chrome/updater/util/unit_test_util.h"
 #include "chrome/updater/util/win_util.h"
 #include "chrome/updater/win/win_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -145,4 +149,26 @@
   return service.IsValid() || ::GetLastError() == ERROR_SERVICE_EXISTS;
 }
 
+CSecurityDesc GetEveryoneDaclSecurityDescriptor(ACCESS_MASK accessmask) {
+  CSecurityDesc sd;
+  CDacl dacl;
+  dacl.AddAllowedAce(Sids::System(), accessmask);
+  dacl.AddAllowedAce(Sids::Admins(), accessmask);
+  dacl.AddAllowedAce(Sids::Interactive(), accessmask);
+
+  sd.SetDacl(dacl);
+  sd.MakeAbsolute();
+  return sd;
+}
+
+test::EventHolder CreateEveryoneWaitableEventForTest() {
+  const std::wstring event_name =
+      base::StrCat({base::UTF8ToWide(test::GetTestName()),
+                    base::NumberToWString(::GetCurrentProcessId())});
+  CSecurityAttributes sa(GetEveryoneDaclSecurityDescriptor(GENERIC_ALL));
+  return {base::WaitableEvent(base::win::ScopedHandle(
+              ::CreateEvent(&sa, FALSE, FALSE, event_name.c_str()))),
+          event_name};
+}
+
 }  // namespace updater
diff --git a/chrome/updater/util/unit_test_util_win.h b/chrome/updater/util/unit_test_util_win.h
index 6a94b07..63c9dd2 100644
--- a/chrome/updater/util/unit_test_util_win.h
+++ b/chrome/updater/util/unit_test_util_win.h
@@ -9,8 +9,10 @@
 
 #include "base/command_line.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/win/atl.h"
 #include "base/win/registry.h"
 #include "chrome/updater/updater_scope.h"
+#include "chrome/updater/util/unit_test_util.h"
 
 namespace updater {
 
@@ -68,6 +70,10 @@
 [[nodiscard]] bool CreateService(const std::wstring& service_name,
                                  const std::wstring& display_name,
                                  const std::wstring& command_line);
+
+// Creates an event accessible to all authenticated users on the machine.
+test::EventHolder CreateEveryoneWaitableEventForTest();
+
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_UTIL_UNIT_TEST_UTIL_WIN_H_
diff --git a/chrome/updater/util/win_util_unittest.cc b/chrome/updater/util/win_util_unittest.cc
index 74d6c89..a8ab2f0 100644
--- a/chrome/updater/util/win_util_unittest.cc
+++ b/chrome/updater/util/win_util_unittest.cc
@@ -59,19 +59,6 @@
 
 constexpr char kTestAppID[] = "{D07D2B56-F583-4631-9E8E-9942F63765BE}";
 
-// Allows access to all authenticated users on the machine.
-CSecurityDesc GetEveryoneDaclSecurityDescriptor(ACCESS_MASK accessmask) {
-  CSecurityDesc sd;
-  CDacl dacl;
-  dacl.AddAllowedAce(Sids::System(), accessmask);
-  dacl.AddAllowedAce(Sids::Admins(), accessmask);
-  dacl.AddAllowedAce(Sids::Interactive(), accessmask);
-
-  sd.SetDacl(dacl);
-  sd.MakeAbsolute();
-  return sd;
-}
-
 }  // namespace
 
 TEST(WinUtil, GetDownloadProgress) {
@@ -177,22 +164,17 @@
   // integrity.
   // The event is created with a security descriptor that allows the medium
   // integrity process to signal it.
-  const std::wstring event_name =
-      base::StrCat({L"WinUtil.RunDeElevated-",
-                    base::NumberToWString(::GetCurrentProcessId())});
-  CSecurityAttributes sa(GetEveryoneDaclSecurityDescriptor(GENERIC_ALL));
-  base::WaitableEvent event(base::win::ScopedHandle(
-      ::CreateEvent(&sa, FALSE, FALSE, event_name.c_str())));
-  ASSERT_NE(event.handle(), nullptr);
+  test::EventHolder event_holder(CreateEveryoneWaitableEventForTest());
+  ASSERT_NE(event_holder.event.handle(), nullptr);
 
   base::CommandLine test_process_cmd_line =
       GetTestProcessCommandLine(GetTestScope(), test::GetTestName());
   test_process_cmd_line.AppendSwitchNative(kTestEventToSignalIfMediumIntegrity,
-                                           event_name);
+                                           event_holder.name);
   EXPECT_HRESULT_SUCCEEDED(
       RunDeElevated(test_process_cmd_line.GetProgram().value(),
                     test_process_cmd_line.GetArgumentsString()));
-  EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
+  EXPECT_TRUE(event_holder.event.TimedWait(TestTimeouts::action_max_timeout()));
 
   EXPECT_TRUE(test::WaitFor(
       [&] { return test::FindProcesses(kTestProcessExecutableName).empty(); }));
diff --git a/chrome/updater/win/ui/progress_wnd.cc b/chrome/updater/win/ui/progress_wnd.cc
index 9971aedc..baf3f2b 100644
--- a/chrome/updater/win/ui/progress_wnd.cc
+++ b/chrome/updater/win/ui/progress_wnd.cc
@@ -9,13 +9,16 @@
 
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/logging.h"
 #include "base/notreached.h"
 #include "base/process/launch.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions_win.h"
+#include "base/strings/string_util.h"
 #include "base/strings/string_util_win.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "base/win/scoped_localalloc.h"
 #include "chrome/updater/app/app_install_progress.h"
 #include "chrome/updater/util/win_util.h"
 #include "chrome/updater/win/ui/l10n_util.h"
@@ -651,9 +654,31 @@
   CHECK(SUCCEEDED(app_info.error_code));
   CHECK(!app_info.is_noupdate);
 
-  auto process = base::LaunchProcess(
-      base::UTF8ToWide(app_info.post_install_launch_command_line), {});
-  return process.IsValid() ? S_OK : HRESULTFromLastError();
+  if (!IsElevatedWithUACOn()) {
+    auto process = base::LaunchProcess(
+        base::UTF8ToWide(app_info.post_install_launch_command_line), {});
+    return process.IsValid() ? S_OK : HRESULTFromLastError();
+  }
+
+  std::wstring command_format =
+      base::UTF8ToWide(app_info.post_install_launch_command_line);
+  int num_args = 0;
+  base::win::ScopedLocalAllocTyped<wchar_t*> argv(
+      ::CommandLineToArgvW(&command_format[0], &num_args));
+  if (!argv || num_args < 1) {
+    LOG(ERROR) << __func__ << "!argv || num_args < 1: " << num_args;
+    return E_INVALIDARG;
+  }
+
+  return RunDeElevated(argv.get()[0],
+                       base::JoinString(
+                           [&]() -> std::vector<std::wstring> {
+                             if (num_args <= 1) {
+                               return {};
+                             }
+                             return {argv.get() + 1, argv.get() + num_args};
+                           }(),
+                           L" "));
 }
 
 bool ProgressWnd::LaunchCmdLines(const ObserverCompletionInfo& info) {
diff --git a/chrome/updater/win/ui/progress_wnd.h b/chrome/updater/win/ui/progress_wnd.h
index 48e70581..ed79416 100644
--- a/chrome/updater/win/ui/progress_wnd.h
+++ b/chrome/updater/win/ui/progress_wnd.h
@@ -124,6 +124,7 @@
   FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnWaitingRetryDownload);
   FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnPause);
   FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnComplete);
+  FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, LaunchCmdLine);
 
   enum class States {
     STATE_INIT = 0,
diff --git a/chrome/updater/win/ui/progress_wnd_unittest.cc b/chrome/updater/win/ui/progress_wnd_unittest.cc
index da30cbd..2066f9f 100644
--- a/chrome/updater/win/ui/progress_wnd_unittest.cc
+++ b/chrome/updater/win/ui/progress_wnd_unittest.cc
@@ -6,8 +6,18 @@
 #include <string>
 #include <vector>
 
+#include "base/command_line.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/test_timeouts.h"
 #include "base/time/time.h"
+#include "chrome/updater/test_scope.h"
+#include "chrome/updater/util/unit_test_util.h"
+#include "chrome/updater/util/unit_test_util_win.h"
+#include "chrome/updater/util/win_util.h"
+#include "chrome/updater/win/test/test_executables.h"
+#include "chrome/updater/win/test/test_strings.h"
 #include "chrome/updater/win/ui/progress_wnd.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -341,4 +351,43 @@
   }
 }
 
+TEST_F(ProgressWndTest, LaunchCmdLine) {
+  using ::testing::AnyNumber;
+  EXPECT_CALL(*mock_progress_wnd_events_, DoExit()).Times(AnyNumber());
+  EXPECT_CALL(*mock_progress_wnd_events_, DoClose()).Times(AnyNumber());
+
+  // Create a shared event to be waited for in this process and signaled in the
+  // test process. If the test is running elevated with UAC on, the test will
+  // also confirm that the test process is launched at medium integrity, by
+  // creating an event with a security descriptor that allows the medium
+  // integrity process to signal it.
+  test::EventHolder event_holder(IsElevatedWithUACOn()
+                                     ? CreateEveryoneWaitableEventForTest()
+                                     : test::CreateWaitableEventForTest());
+  ASSERT_NE(event_holder.event.handle(), nullptr);
+
+  base::CommandLine test_process_cmd_line =
+      GetTestProcessCommandLine(GetTestScope(), test::GetTestName());
+  test_process_cmd_line.AppendSwitchNative(
+      IsElevatedWithUACOn() ? kTestEventToSignalIfMediumIntegrity
+                            : kTestEventToSignal,
+      event_holder.name);
+  WTL::CMessageLoop ui_message_loop;
+  std::unique_ptr<ProgressWnd> progress_wnd =
+      MakeProgressWindow(&ui_message_loop);
+  AppCompletionInfo app_completion_info;
+  app_completion_info.completion_code =
+      CompletionCodes::COMPLETION_CODE_EXIT_SILENTLY_ON_LAUNCH_COMMAND;
+  app_completion_info.post_install_launch_command_line =
+      base::WideToUTF8(test_process_cmd_line.GetCommandLineString());
+  ObserverCompletionInfo observer_completion_info;
+  observer_completion_info.completion_text = u"text";
+  observer_completion_info.apps_info.push_back(app_completion_info);
+  progress_wnd->OnComplete(observer_completion_info);
+
+  EXPECT_TRUE(event_holder.event.TimedWait(TestTimeouts::action_max_timeout()));
+  EXPECT_TRUE(test::WaitFor(
+      [] { return test::FindProcesses(kTestProcessExecutableName).empty(); }));
+}
+
 }  // namespace updater::ui
diff --git a/chromeos/ash/components/mojo_service_manager/OWNERS b/chromeos/ash/components/mojo_service_manager/OWNERS
index 7bd7ce6c3..1b233df9 100644
--- a/chromeos/ash/components/mojo_service_manager/OWNERS
+++ b/chromeos/ash/components/mojo_service_manager/OWNERS
@@ -1,2 +1,2 @@
-chungsheng@chromium.org
+chungsheng@google.com
 hashimoto@chromium.org
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index a0e30555..5287d2b 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -186,6 +186,11 @@
              "RoundedWindows",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Enables a content cache for FileSystemProvider extensions.
+BASE_FEATURE(kFileSystemProviderContentCache,
+             "FileSystemProviderContentCache",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 const char kRoundedWindowsRadius[] = "window_radius";
 
 bool IsAppInstallServiceUriEnabled() {
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index ebe6669..0d33e0ed 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -78,6 +78,8 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kRoundedWindows);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 BASE_DECLARE_FEATURE(kMicrosoftOneDriveIntegrationForEnterprise);
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+BASE_DECLARE_FEATURE(kFileSystemProviderContentCache);
 
 // Keep alphabetized.
 
diff --git a/clank b/clank
index 93f4094..e1d0bc7 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 93f409484e269c3df9017ba14dc28a6ccd84bf2d
+Subproject commit e1d0bc7ff99b302fe11d5a7563481e3fb42c14e2
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index e247c05..5cf6a830 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -424,7 +424,9 @@
   if (!queryable_forms.empty() && client().GetCrowdsourcingManager()) {
     NotifyObservers(&Observer::OnBeforeLoadedServerPredictions);
     if (!client().GetCrowdsourcingManager()->StartQueryRequest(
-            queryable_forms, driver().IsolationInfo(), GetWeakPtr())) {
+            queryable_forms, driver().IsolationInfo(),
+            base::BindOnce(&AutofillManager::OnLoadedServerPredictions,
+                           GetWeakPtr()))) {
       NotifyObservers(&Observer::OnAfterLoadedServerPredictions);
     }
   }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 7523aaa..948a455 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -61,8 +61,7 @@
 //
 // It is owned by the AutofillDriver.
 class AutofillManager
-    : public AutofillCrowdsourcingManager::Observer,
-      public translate::TranslateDriver::LanguageDetectionObserver {
+    : public translate::TranslateDriver::LanguageDetectionObserver {
  public:
   // Observer of AutofillManager events.
   //
@@ -499,10 +498,10 @@
  private:
   friend class AutofillManagerTestApi;
 
-  // AutofillCrowdsourcingManager::Observer:
+  // Invoked by `AutofillCrowdsourcingManager`.
   void OnLoadedServerPredictions(
       std::string response,
-      const std::vector<FormSignature>& queried_form_signatures) override;
+      const std::vector<FormSignature>& queried_form_signatures);
 
   // Invoked when forms from OnFormsSeen() have been parsed to
   // |form_structures|.
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 8e488679..c3176ff 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -2066,7 +2066,7 @@
           non_empty_types, was_autofilled,
           /*login_form_signature=*/{}, observed_submission),
       submitted_form->submission_source(), submitted_form->active_field_count(),
-      client().GetPrefs(), GetWeakPtr());
+      client().GetPrefs());
 }
 
 const gfx::Image& BrowserAutofillManager::GetCardImage(
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 2cde89d8..1ad542b 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -10619,7 +10619,7 @@
     BrowserAutofillManagerTest::SetUp();
 
     // All uploads should be expected explicitly.
-    EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest(_, _, _, _, _))
+    EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest(_, _, _, _))
         .Times(0);
 
     form_.name = u"MyForm";
@@ -10657,7 +10657,7 @@
                                      FieldType::CREDIT_CARD_NAME_FIRST}),
                                 FieldAutofillTypeIs({FieldType::EMPTY_TYPE})),
                       ObservedSubmissionIs(true))),
-                  _, _, _, _));
+                  _, _, _));
   FormSubmitted(form_);
 }
 
@@ -10690,7 +10690,7 @@
                                        FieldType::CREDIT_CARD_NAME_LAST,
                                        FieldType::NAME_LAST_SECOND})),
               ObservedSubmissionIs(false))),
-          _, _, _, _));
+          _, _, _));
   browser_autofill_manager_->OnFocusNoLongerOnForm(true);
 
   // 5. Grow the form by one field, which changes the form signature.
@@ -10714,7 +10714,7 @@
                                              FieldType::NAME_LAST_SECOND}),
                         FieldAutofillTypeIs({FieldType::EMPTY_TYPE})),
               ObservedSubmissionIs(true))),
-          _, _, _, _));
+          _, _, _));
   FormSubmitted(form_);
 }
 
@@ -10732,7 +10732,7 @@
                                      FieldType::CREDIT_CARD_NAME_FIRST}),
                                 FieldAutofillTypeIs({FieldType::EMPTY_TYPE})),
                       ObservedSubmissionIs(false))),
-                  _, _, _, _));
+                  _, _, _));
   browser_autofill_manager_->OnFocusNoLongerOnForm(true);
 
   // Simulate a navigation. This is when the vote is sent.
@@ -10756,7 +10756,7 @@
                                      FieldType::CREDIT_CARD_NAME_FIRST}),
                                 FieldAutofillTypeIs({FieldType::EMPTY_TYPE})),
                       ObservedSubmissionIs(true))),
-                  _, _, _, _));
+                  _, _, _));
   FormSubmitted(form_);
 }
 
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc
index cadb8c93..e48bfae 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc
@@ -121,6 +121,11 @@
     "max-attempts",
     5);
 
+enum class RequestType {
+  kRequestQuery,
+  kRequestUpload,
+};
+
 // Returns the base URL for the autofill server.
 GURL GetAutofillServerURL() {
   // If a valid autofill server URL is specified on the command line, then the
@@ -172,15 +177,12 @@
   });
 }
 
-std::string GetMetricName(
-  AutofillCrowdsourcingManager::RequestType request_type,
-                          std::string_view suffix) {
-  auto TypeToName =
-      [](AutofillCrowdsourcingManager::RequestType type) -> std::string_view {
+std::string GetMetricName(RequestType request_type, std::string_view suffix) {
+  auto TypeToName = [](RequestType type) -> std::string_view {
     switch (type) {
-      case AutofillCrowdsourcingManager::REQUEST_QUERY:
+      case RequestType::kRequestQuery:
         return "Query";
-      case AutofillCrowdsourcingManager::REQUEST_UPLOAD:
+      case RequestType::kRequestUpload:
         return "Upload";
     }
     NOTREACHED_NORETURN();
@@ -189,9 +191,10 @@
 }
 
 net::NetworkTrafficAnnotationTag GetNetworkTrafficAnnotation(
-    const AutofillCrowdsourcingManager::RequestType& request_type) {
-  if (request_type == AutofillCrowdsourcingManager::REQUEST_QUERY) {
-    return net::DefineNetworkTrafficAnnotation("autofill_query", R"(
+    RequestType request_type) {
+  switch (request_type) {
+    case RequestType::kRequestQuery:
+      return net::DefineNetworkTrafficAnnotation("autofill_query", R"(
         semantics {
           sender: "Autofill"
           description:
@@ -241,10 +244,8 @@
             }
           }
         })");
-  }
-
-  DCHECK_EQ(request_type, AutofillCrowdsourcingManager::REQUEST_UPLOAD);
-  return net::DefineNetworkTrafficAnnotation("autofill_upload", R"(
+    case RequestType::kRequestUpload:
+      return net::DefineNetworkTrafficAnnotation("autofill_upload", R"(
       semantics {
         sender: "Autofill"
         description:
@@ -290,6 +291,8 @@
           }
         }
       })");
+  }
+  NOTREACHED_NORETURN();
 }
 
 size_t CountActiveFieldsInForms(const std::vector<FormStructure*>& forms) {
@@ -470,17 +473,20 @@
 // Gets an API method URL given its type (query or upload), an optional
 // resource ID, and the HTTP method to be used.
 // Example usage:
-// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "GET") will return "/v1/pages/1234".
-// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "POST") will return "/v1/pages:get".
-// * GetAPIMethodUrl(REQUEST_UPLOAD, "", "POST") will return "/v1/forms:vote".
-std::string GetAPIMethodUrl(AutofillCrowdsourcingManager::RequestType type,
+// * GetAPIMethodUrl(RequestType::kRequestQuery, "1234", "GET") will return
+//   "/v1/pages/1234".
+// * GetAPIMethodUrl(RequestType::kRequestQuery, "1234", "POST") will return
+//   "/v1/pages:get".
+// * GetAPIMethodUrl(RequestType::kRequestUpload, "", "POST") will return
+//   "/v1/forms:vote".
+std::string GetAPIMethodUrl(RequestType type,
                             std::string_view resource_id,
                             std::string_view method) {
   const char* api_method_url = [&] {
     switch (type) {
-      case AutofillCrowdsourcingManager::REQUEST_QUERY:
+      case RequestType::kRequestQuery:
         return method == "POST" ? "/v1/pages:get" : "/v1/pages";
-      case AutofillCrowdsourcingManager::REQUEST_UPLOAD:
+      case RequestType::kRequestUpload:
         return "/v1/forms:vote";
     }
     NOTREACHED_NORETURN();
@@ -492,11 +498,10 @@
 }
 
 // Gets HTTP body payload for API POST request.
-std::optional<std::string> GetAPIBodyPayload(
-    std::string payload,
-    AutofillCrowdsourcingManager::RequestType type) {
+std::optional<std::string> GetAPIBodyPayload(std::string payload,
+                                             RequestType type) {
   // Don't do anything for payloads not related to Query.
-  if (type != AutofillCrowdsourcingManager::REQUEST_QUERY) {
+  if (type != RequestType::kRequestQuery) {
     return std::move(payload);
   }
   // Wrap query payload in a request proto to interface with API Query method.
@@ -573,7 +578,7 @@
 }  // namespace
 
 struct AutofillCrowdsourcingManager::FormRequestData {
-  base::WeakPtr<Observer> observer;
+  std::optional<QueryRequestCompleteCallback> callback = std::nullopt;
   std::vector<FormSignature> form_signatures;
   RequestType request_type;
   std::optional<net::IsolationInfo> isolation_info;
@@ -618,7 +623,7 @@
 bool AutofillCrowdsourcingManager::StartQueryRequest(
     const std::vector<FormStructure*>& forms,
     net::IsolationInfo isolation_info,
-    base::WeakPtr<Observer> observer) {
+    QueryRequestCompleteCallback callback) {
   if (!IsEnabled())
     return false;
 
@@ -654,9 +659,9 @@
   }
 
   FormRequestData request_data = {
-      .observer = observer,
+      .callback = std::move(callback),
       .form_signatures = std::move(queried_form_signatures),
-      .request_type = AutofillCrowdsourcingManager::REQUEST_QUERY,
+      .request_type = RequestType::kRequestQuery,
       .isolation_info = std::move(isolation_info),
       .payload = std::move(payload).value(),
   };
@@ -666,9 +671,9 @@
   if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) {
     LOG_AF(log_manager_) << LoggingScope::kAutofillServer
                          << LogMessage::kCachedAutofillQuery << Br{} << query;
-    if (request_data.observer) {
-      request_data.observer->OnLoadedServerPredictions(
-          std::move(query_data), request_data.form_signatures);
+    if (request_data.callback && *request_data.callback) {
+      std::move(*request_data.callback)
+          .Run(std::move(query_data), request_data.form_signatures);
     }
     return true;
   }
@@ -683,8 +688,7 @@
     std::vector<AutofillUploadContents> upload_contents,
     mojom::SubmissionSource form_submission_source,
     int form_active_field_count,
-    PrefService* prefs,
-    base::WeakPtr<Observer> observer) {
+    PrefService* prefs) {
   if (!IsEnabled()) {
     return false;
   }
@@ -727,9 +731,8 @@
     }
 
     FormRequestData request_data = {
-        .observer = observer,
         .form_signatures = {form_signature},
-        .request_type = AutofillCrowdsourcingManager::REQUEST_UPLOAD,
+        .request_type = RequestType::kRequestUpload,
         .isolation_info = std::nullopt,
         .payload = std::move(payload).value(),
     };
@@ -772,7 +775,7 @@
   std::string resource_id;
   std::string method = "POST";
 
-  if (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_QUERY) {
+  if (request_data.request_type == RequestType::kRequestQuery) {
     if (GetPayloadLength(request_data.payload) <= kMaxQueryGetSize) {
       resource_id = request_data.payload;
       method = "GET";
@@ -795,22 +798,21 @@
 }
 
 bool AutofillCrowdsourcingManager::StartRequest(FormRequestData request_data) {
-  // REQUEST_UPLOADs take no IsolationInfo because Password Manager uploads when
+  // kRequestUploads take no IsolationInfo because Password Manager uploads when
   // RenderFrameHostImpl::DidCommitNavigation() is called, in which case
   // AutofillDriver::IsolationInfo() may crash because there is no committing
   // NavigationRequest. Not setting an IsolationInfo is safe because no
   // information about the response is passed to the renderer, or is otherwise
   // visible to a page. See crbug/1176635#c22.
-  DCHECK(
-      (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_UPLOAD) ==
-      !request_data.isolation_info);
+  DCHECK((request_data.request_type == RequestType::kRequestUpload) ==
+         !request_data.isolation_info);
 
   // Get the URL and method to use for this request.
   auto [request_url, method] = GetRequestURLAndMethod(request_data);
 
   // Track the URL length for GET queries because the URL length can be in the
   // thousands when rich metadata is enabled.
-  if (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_QUERY &&
+  if (request_data.request_type == RequestType::kRequestQuery &&
       method == "GET") {
     base::UmaHistogramCounts100000(kUmaGetUrlLength,
                                    request_url.spec().length());
@@ -991,15 +993,15 @@
     return;
   }
 
-  if (request_data.request_type != REQUEST_QUERY) {
+  if (request_data.request_type != RequestType::kRequestQuery) {
     return;
   }
 
   CacheQueryRequest(request_data.form_signatures, *response_body);
   base::UmaHistogramBoolean(kUmaWasInCache, simple_loader->LoadedFromCache());
-  if (request_data.observer) {
-    request_data.observer->OnLoadedServerPredictions(
-        std::move(*response_body), request_data.form_signatures);
+  if (request_data.callback && *request_data.callback) {
+    std::move(*request_data.callback)
+        .Run(std::move(*response_body), request_data.form_signatures);
   }
 }
 
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h
index 5296ea2..6180911 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h
@@ -45,11 +45,6 @@
 // Obtains Autofill server predictions and upload votes for generating them.
 class AutofillCrowdsourcingManager {
  public:
-  enum RequestType {
-    REQUEST_QUERY,
-    REQUEST_UPLOAD,
-  };
-
   // Names of UMA metrics recorded in this class.
   static constexpr char kUmaApiUrlIsTooLong[] =
       "Autofill.Query.ApiUrlIsTooLong";
@@ -57,20 +52,6 @@
   static constexpr char kUmaMethod[] = "Autofill.Query.Method";
   static constexpr char kUmaWasInCache[] = "Autofill.Query.WasInCache";
 
-  // An interface used to notify clients of AutofillCrowdsourcingManager.
-  class Observer {
-   public:
-    // Called when field type predictions are successfully received from the
-    // server. |response| contains the server response for the forms
-    // represented by |queried_form_signatures|.
-    virtual void OnLoadedServerPredictions(
-        std::string response,
-        const std::vector<FormSignature>& queried_form_signatures) = 0;
-
-   protected:
-    virtual ~Observer() = default;
-  };
-
   // `client` owns (and hence survives) this AutofillCrowdsourcingManager.
   // `channel` determines the value for the the Google-API-key HTTP header and
   // whether raw metadata uploading is enabled.
@@ -80,12 +61,18 @@
 
   virtual ~AutofillCrowdsourcingManager();
 
+  // The callback executed on successful completion of a query request. The
+  // first parameter contains the server response and the second parameter the
+  // queried form signatures.
+  using QueryRequestCompleteCallback =
+      base::OnceCallback<void(std::string, const std::vector<FormSignature>&)>;
+
   // Starts a query request to Autofill servers. The observer is called with the
   // list of the fields of all requested forms.
-  // |forms| - array of forms aggregated in this request.
+  // `forms` - array of forms aggregated in this request.
   virtual bool StartQueryRequest(const std::vector<FormStructure*>& forms,
                                  net::IsolationInfo isolation_info,
-                                 base::WeakPtr<Observer> observer);
+                                 QueryRequestCompleteCallback callback);
 
   // Starts an upload request for `upload_contents`. If `upload_contents` has
   // more than one element, then `upload_contents[0]` is expected to correspond
@@ -97,8 +84,7 @@
       std::vector<AutofillUploadContents> upload_contents,
       mojom::SubmissionSource form_submission_source,
       int form_active_field_count,
-      PrefService* prefs,
-      base::WeakPtr<Observer> observer);
+      PrefService* prefs);
 
   // Returns true if the autofill server communication is enabled.
   bool IsEnabled() const;
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
index d6aad23..dcce417 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
@@ -198,9 +198,7 @@
 // go over the wire, but allow calling back HTTP responses directly.
 // The responses in test are out of order and verify: successful query request,
 // successful upload request, failed upload request.
-class AutofillCrowdsourcingManagerTest
-    : public AutofillCrowdsourcingManager::Observer,
-      public ::testing::Test {
+class AutofillCrowdsourcingManagerTest : public ::testing::Test {
  public:
   enum class ResponseType {
     kQuerySuccessful,
@@ -232,13 +230,14 @@
       const std::vector<std::unique_ptr<FormStructure>>& form_structures) {
     return crowdsourcing_manager().StartQueryRequest(
         ToRawPointerVector(form_structures), driver().IsolationInfo(),
-        weak_ptr_factory_.GetWeakPtr());
+        base::BindOnce(
+            &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+            weak_ptr_factory_.GetWeakPtr()));
   }
 
-  // AutofillCrowdsourcingManager::Observer implementation.
   void OnLoadedServerPredictions(
       std::string response_xml,
-      const std::vector<FormSignature>& form_signatures) override {
+      const std::vector<FormSignature>& form_signatures) {
     ResponseData response;
     response.response = std::move(response_xml);
     response.type_of_response = ResponseType::kQuerySuccessful;
@@ -305,7 +304,9 @@
   base::HistogramTester histogram;
   EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest(
       ToRawPointerVector(form_structures), driver().IsolationInfo(),
-      GetWeakPtr()));
+      base::BindOnce(
+          &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+          GetWeakPtr())));
   histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
                                AutofillMetrics::QUERY_SENT, 1);
   histogram.ExpectUniqueSample(AutofillCrowdsourcingManager::kUmaMethod,
@@ -325,7 +326,7 @@
                                               std::string(), true);
   EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest(
       std::move(upload_contents_1), form_structures[0]->submission_source(),
-      form_structures[0]->active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structures[0]->active_field_count(), &pref_service()));
 
   // Request with id 2.
   std::vector<AutofillUploadContents> upload_contents_2 =
@@ -333,7 +334,7 @@
                                               std::string(), true);
   EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest(
       std::move(upload_contents_2), form_structures[1]->submission_source(),
-      form_structures[1]->active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structures[1]->active_field_count(), &pref_service()));
   // Request with id 3. Upload request with a non-empty additional password form
   // signature.
   std::vector<AutofillUploadContents> upload_contents_3 =
@@ -341,7 +342,7 @@
                                               true);
   EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest(
       std::move(upload_contents_3), form_structures[1]->submission_source(),
-      form_structures[1]->active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structures[1]->active_field_count(), &pref_service()));
 
   // Server responseses - returned  out of sequence.
   const char* response_contents[] = {
@@ -397,7 +398,9 @@
   // Request with id 4, not successful.
   EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest(
       ToRawPointerVector(form_structures), driver().IsolationInfo(),
-      GetWeakPtr()));
+      base::BindOnce(
+          &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+          GetWeakPtr())));
   request = url_loader_factory().GetPendingRequest(4);
   histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
                                AutofillMetrics::QUERY_SENT, 2);
@@ -412,7 +415,9 @@
   // Request with id 5. Let's pretend we hit the cache.
   EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest(
       ToRawPointerVector(form_structures), driver().IsolationInfo(),
-      GetWeakPtr()));
+      base::BindOnce(
+          &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+          GetWeakPtr())));
   histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
                               AutofillMetrics::QUERY_SENT, 3);
   histogram.ExpectBucketCount(AutofillCrowdsourcingManager::kUmaMethod,
@@ -447,7 +452,9 @@
   base::HistogramTester histogram;
   EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest(
       ToRawPointerVector(form_structures), driver().IsolationInfo(),
-      GetWeakPtr()));
+      base::BindOnce(
+          &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+          GetWeakPtr())));
 
   // Verify if histograms are right.
   histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
@@ -538,7 +545,9 @@
   base::HistogramTester histogram;
   EXPECT_TRUE(crowdsourcing_manager.StartQueryRequest(
       ToRawPointerVector(form_structures), driver().IsolationInfo(),
-      GetWeakPtr()));
+      base::BindOnce(
+          &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions,
+          GetWeakPtr())));
 
   // Verify request.
   // Verify if histograms are right.
@@ -643,7 +652,7 @@
                                          true);
   EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest(
       std::move(upload_contents), form_structure.submission_source(),
-      form_structure.active_field_count(), pref_service.get(), GetWeakPtr()));
+      form_structure.active_field_count(), pref_service.get()));
 
   // Inspect the request that the test URL loader sent.
   network::TestURLLoaderFactory::PendingRequest* request =
@@ -738,7 +747,7 @@
                                          true);
   EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest(
       std::move(upload_contents), form_structure.submission_source(),
-      form_structure.active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structure.active_field_count(), &pref_service()));
 
   auto* request = url_loader_factory().GetPendingRequest(0);
 
@@ -764,7 +773,7 @@
                                          true);
   EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest(
       std::move(upload_contents_2), form_structure.submission_source(),
-      form_structure.active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structure.active_field_count(), &pref_service()));
 
   request = url_loader_factory().GetPendingRequest(2);
   url_loader_factory().SimulateResponseWithoutRemovingFromPendingList(
@@ -839,7 +848,7 @@
                                          true);
   EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest(
       std::move(upload_contents), form_structure.submission_source(),
-      form_structure.active_field_count(), &pref_service(), GetWeakPtr()));
+      form_structure.active_field_count(), &pref_service()));
 
   constexpr auto kTimeDeltaMargin = base::Milliseconds(100);
   const int max_attempts = crowdsourcing_manager().GetMaxServerAttempts();
@@ -1046,8 +1055,7 @@
 };
 
 class AutofillServerCommunicationTest
-    : public AutofillCrowdsourcingManager::Observer,
-      public testing::TestWithParam<ServerCommunicationMode> {
+    : public testing::TestWithParam<ServerCommunicationMode> {
  protected:
   void SetUp() override {
     testing::TestWithParam<ServerCommunicationMode>::SetUp();
@@ -1113,7 +1121,7 @@
   // AutofillCrowdsourcingManager::Observer implementation.
   void OnLoadedServerPredictions(
       std::string /* response_xml */,
-      const std::vector<FormSignature>& /*form_signatures */) override {
+      const std::vector<FormSignature>& /*form_signatures */) {
     ASSERT_TRUE(run_loop_);
     run_loop_->QuitWhenIdle();
   }
@@ -1179,7 +1187,9 @@
         &client(), version_info::Channel::UNKNOWN, nullptr);
     bool succeeded = crowdsourcing_manager.StartQueryRequest(
         ToRawPointerVector(form_structures), driver_.IsolationInfo(),
-        weak_ptr_factory_.GetWeakPtr());
+        base::BindOnce(
+            &AutofillServerCommunicationTest::OnLoadedServerPredictions,
+            weak_ptr_factory_.GetWeakPtr()));
     if (succeeded)
       run_loop_->Run();
     run_loop_.reset();
@@ -1203,8 +1213,7 @@
                                  login_form_signature, observed_submission);
     bool succeeded = crowdsourcing_manager.StartUploadRequest(
         std::move(upload_contents), form.submission_source(),
-        form.active_field_count(), &pref_service(),
-        weak_ptr_factory_.GetWeakPtr());
+        form.active_field_count(), &pref_service());
     if (succeeded)
       run_loop_->Run();
     run_loop_.reset();
diff --git a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h
index 77b576d2..57acdb4 100644
--- a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h
+++ b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h
@@ -29,7 +29,7 @@
               StartQueryRequest,
               (const std::vector<FormStructure*>&,
                net::IsolationInfo,
-               base::WeakPtr<Observer>),
+               QueryRequestCompleteCallback),
               (override));
 
   MOCK_METHOD(bool,
@@ -37,8 +37,7 @@
               (std::vector<AutofillUploadContents>,
                mojom::SubmissionSource,
                int,
-               PrefService*,
-               base::WeakPtr<Observer>),
+               PrefService*),
               (override));
 };
 
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index ebd95ae1..7260091a 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -158,26 +158,6 @@
   return MAX_VALID_FIELD_TYPE;
 }
 
-// Encode password attributes and length into |upload|.
-void EncodePasswordAttributesVote(
-    const std::pair<PasswordAttribute, bool>& password_attributes_vote,
-    const size_t password_length_vote,
-    const int password_symbol_vote,
-    AutofillUploadContents* upload) {
-  switch (password_attributes_vote.first) {
-    case PasswordAttribute::kHasLetter:
-      upload->set_password_has_letter(password_attributes_vote.second);
-      break;
-    case PasswordAttribute::kHasSpecialSymbol:
-      upload->set_password_has_special_symbol(password_attributes_vote.second);
-      if (password_attributes_vote.second)
-        upload->set_password_special_symbol(password_symbol_vote);
-      break;
-    case PasswordAttribute::kPasswordAttributesCount:
-      NOTREACHED();
-  }
-  upload->set_password_length(password_length_vote);
-}
 
 void EncodeRandomizedValue(const RandomizedEncoder& encoder,
                            FormSignature form_signature,
@@ -561,7 +541,6 @@
   upload.set_form_signature(form_signature().value());
   upload.set_autofill_used(form_was_autofilled);
   upload.set_data_present(data_present);
-  upload.set_passwords_revealed(passwords_were_revealed_);
   upload.set_has_form_tag(is_form_tag_);
   if (!current_page_language_->empty() && randomized_encoder_ != nullptr) {
     upload.set_language(current_page_language_.value());
@@ -594,12 +573,6 @@
       static_cast<AutofillUploadContents_SubmissionIndicatorEvent>(
           triggering_event));
 
-  if (password_attributes_vote_) {
-    EncodePasswordAttributesVote(*password_attributes_vote_,
-                                 password_length_vote_, password_symbol_vote_,
-                                 &upload);
-  }
-
   if (!login_form_signature.empty()) {
     uint64_t login_sig;
     if (base::StringToUint64(login_form_signature, &login_sig))
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 9b563fd..da959af 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -372,49 +372,6 @@
   // Returns the possible form types.
   DenseSet<FormType> GetFormTypes() const;
 
-  bool passwords_were_revealed() const { return passwords_were_revealed_; }
-  void set_passwords_were_revealed(bool passwords_were_revealed) {
-    passwords_were_revealed_ = passwords_were_revealed;
-  }
-
-  void set_password_attributes_vote(
-      const std::pair<PasswordAttribute, bool>& vote) {
-    password_attributes_vote_ = vote;
-  }
-
-  std::optional<std::pair<PasswordAttribute, bool>>
-  get_password_attributes_vote() const {
-    return password_attributes_vote_;
-  }
-
-  void set_password_length_vote(const size_t noisified_password_length) {
-    DCHECK(password_attributes_vote_.has_value())
-        << "|password_length_vote_| doesn't make sense if "
-           "|password_attributes_vote_| has no value.";
-    password_length_vote_ = noisified_password_length;
-  }
-
-  size_t get_password_length_vote() const {
-    DCHECK(password_attributes_vote_.has_value())
-        << "|password_length_vote_| doesn't make sense if "
-           "|password_attributes_vote_| has no value.";
-    return password_length_vote_;
-  }
-
-  void set_password_symbol_vote(int noisified_symbol) {
-    DCHECK(password_attributes_vote_.has_value())
-        << "password_symbol_vote_| doesn't make sense if "
-           "|password_attributes_vote_| has no value.";
-    password_symbol_vote_ = noisified_symbol;
-  }
-
-  int get_password_symbol_vote() const {
-    DCHECK(password_attributes_vote_.has_value())
-        << "|password_symbol_vote_| doesn't make sense if "
-           "|password_attributes_vote_| has no value";
-    return password_symbol_vote_;
-  }
-
   mojom::SubmissionSource submission_source() const {
     return submission_source_;
   }
@@ -631,24 +588,6 @@
   // If phone number rationalization has been performed for a given section.
   std::set<Section> phone_rationalized_;
 
-  // True iff the form is a password form and the user has seen the password
-  // value before accepting the prompt to save. Used for crowdsourcing.
-  bool passwords_were_revealed_ = false;
-
-  // The vote about password attributes (e.g. whether the password has a numeric
-  // character).
-  std::optional<std::pair<PasswordAttribute, bool>> password_attributes_vote_;
-
-  // If |password_attribute_vote_| contains (kHasSpecialSymbol, true), this
-  // field contains noisified information about a special symbol in a
-  // user-created password stored as ASCII code. The default value of 0
-  // indicates that no symbol was set.
-  int password_symbol_vote_ = 0;
-
-  // Noisified password length for crowdsourcing. If |password_attributes_vote_|
-  // has no value, |password_length_vote_| should be ignored.
-  size_t password_length_vote_;
-
   // Used to record whether developer has used autocomplete markup or
   // UPI-VPA hints, This is a bitmask of DeveloperEngagementMetric and set in
   // DetermineHeuristicTypes().
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index efe868e..aa2ca46 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -2536,9 +2536,6 @@
   form.fields.push_back(checkable_field);
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
 
@@ -2568,9 +2565,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
-  upload.set_passwords_revealed(false);
-  upload.set_password_has_letter(true);
-  upload.set_password_length(10u);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -2611,9 +2605,6 @@
   }
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
 
@@ -2708,9 +2699,6 @@
   form.fields.push_back(checkable_field);
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
 
@@ -2740,9 +2728,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
-  upload.set_passwords_revealed(false);
-  upload.set_password_has_letter(true);
-  upload.set_password_length(10u);
 
   test::FillUploadField(upload.add_field(), 3763331450U, 3U, 0);
   test::FillUploadField(upload.add_field(), 3494530716U, 5U, 0);
@@ -2827,9 +2812,6 @@
   form.fields.push_back(checkable_field);
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
 
@@ -2859,9 +2841,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
-  upload.set_passwords_revealed(false);
-  upload.set_password_has_letter(true);
-  upload.set_password_length(10u);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -2941,9 +2920,6 @@
   form.fields.push_back(checkable_field);
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   form_structure->set_submission_event(
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
   for (auto& fs_field : *form_structure)
@@ -2976,9 +2952,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
-  upload.set_passwords_revealed(false);
-  upload.set_password_has_letter(true);
-  upload.set_password_length(10u);
   upload.set_has_form_tag(true);
 
   test::FillUploadField(upload.add_field(), 3763331450U, 3U);
@@ -3009,9 +2982,6 @@
   }
 
   form_structure = std::make_unique<FormStructure>(form);
-  form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLetter, true));
-  form_structure->set_password_length_vote(10u);
   form_structure->set_submission_event(
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -3143,7 +3113,6 @@
   upload.set_autofill_used(true);
   upload.set_data_present("1440000000000000000802");
   upload.set_login_form_signature(42);
-  upload.set_passwords_revealed(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -3244,7 +3213,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(true);
   upload.set_data_present("1440");
-  upload.set_passwords_revealed(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -3326,7 +3294,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(true);
   upload.set_data_present("1440");
-  upload.set_passwords_revealed(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -3397,7 +3364,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(true);
   upload.set_data_present("1440");
-  upload.set_passwords_revealed(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_NONE);
   upload.set_has_form_tag(true);
@@ -3499,7 +3465,6 @@
     upload.set_form_signature(form_structure->form_signature().value());
     upload.set_autofill_used(false);
     upload.set_data_present("0000000000001850");
-    upload.set_passwords_revealed(false);
     upload.set_has_form_tag(true);
     test::FillUploadField(upload.add_field(), 3340391946, 51);
     test::FillUploadField(upload.add_field(), 1415886167, 52);
@@ -3605,7 +3570,6 @@
   upload.set_form_signature(form_structure.form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("");
-  upload.set_passwords_revealed(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_HTML_FORM_SUBMISSION);
   upload.set_has_form_tag(true);
@@ -3863,7 +3827,6 @@
   upload.set_form_signature(form_structure->form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present("1440000360000008");
-  upload.set_passwords_revealed(false);
   upload.set_has_form_tag(false);
   upload.set_submission_event(
       AutofillUploadContents_SubmissionIndicatorEvent_XHR_SUCCEEDED);
@@ -3949,7 +3912,6 @@
   form.fields.push_back(field);
 
   FormStructure form_structure(form);
-  form_structure.set_passwords_were_revealed(true);
   for (auto& fs_field : form_structure)
     fs_field->host_form_signature = form_structure.form_signature();
 
@@ -3959,7 +3921,6 @@
           std::string() /* login_form_signature */,
           true /* observed_submission */);
   ASSERT_EQ(1u, uploads.size());
-  EXPECT_EQ(true, uploads.front().passwords_revealed());
 }
 
 TEST_F(FormStructureTestImpl, EncodeUploadRequest_IsFormTag) {
@@ -3978,7 +3939,6 @@
     FormStructure form_structure(form);
     for (auto& fs_field : form_structure)
       fs_field->host_form_signature = form_structure.form_signature();
-    form_structure.set_passwords_were_revealed(true);
     std::vector<AutofillUploadContents> uploads =
         form_structure.EncodeUploadRequest(
             {{}} /* available_field_types */, false /* form_was_autofilled */,
diff --git a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h
index 7a2aa65..a745bf70 100644
--- a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h
+++ b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h
@@ -99,6 +99,22 @@
                              signature.value());
 }
 
+inline ::testing::Matcher<AutofillUploadContents> PasswordLengthIsPositive() {
+  return ::testing::Property("password_length",
+                             &AutofillUploadContents::password_length,
+                             ::testing::Gt(0u));
+}
+
+inline ::testing::Matcher<AutofillUploadContents> HasPasswordAttribute() {
+  return ::testing::AnyOf(
+      ::testing::Property("has_password_has_letter",
+                          &AutofillUploadContents::has_password_has_letter,
+                          true),
+      ::testing::Property(
+          "has_password_has_special_symbol",
+          &AutofillUploadContents::has_password_has_special_symbol, true));
+}
+
 }  // namespace upload_contents_matchers
 
 }  // namespace autofill
diff --git a/components/exo/wayland/wl_data_device_manager.cc b/components/exo/wayland/wl_data_device_manager.cc
index 167b96c1..bb05f5d8 100644
--- a/components/exo/wayland/wl_data_device_manager.cc
+++ b/components/exo/wayland/wl_data_device_manager.cc
@@ -319,7 +319,7 @@
       if (serial_tracker_->GetPointerDownSerial() != serial) {
         LOG(ERROR)
             << "The serial passed to StartDrag for pointer does not match its "
-               "expected types. serial="
+               "expected types. tracker_id="
             << serial << ", " << serial_tracker_->ToString();
         source->Cancelled();
         return;
@@ -331,7 +331,7 @@
       if (serial_tracker_->GetTouchDownSerial() != serial) {
         LOG(ERROR)
             << "The serial passed to StartDrag for touch does not match its "
-               "expected types. serial="
+               "expected types. tracker_id="
             << serial << ", " << serial_tracker_->ToString();
         source->Cancelled();
         return;
@@ -341,7 +341,7 @@
                              ui::mojom::DragEventSource::kTouch);
     } else {
       LOG(ERROR) << "Invalid event type for StartDrag:" << (int)*event_type
-                 << ", serial=" << serial << ", "
+                 << ", tracker_id=" << serial << ", "
                  << serial_tracker_->ToString();
       source->Cancelled();
       return;
diff --git a/components/eye_dropper/eye_dropper_view_aura.cc b/components/eye_dropper/eye_dropper_view_aura.cc
index 39036ab..2e79acb 100644
--- a/components/eye_dropper/eye_dropper_view_aura.cc
+++ b/components/eye_dropper/eye_dropper_view_aura.cc
@@ -127,11 +127,24 @@
 void EyeDropperView::PreEventDispatchHandler::OnTouchEvent(
     ui::TouchEvent* event) {
   if (event->type() == ui::ET_TOUCH_PRESSED) {
+    // For touch-move, we don't move the center of the EyeDropper to be at the
+    // touch point, but rather maintain the offset from the first press.
     touch_offset_ = event->root_location() -
                     view_->GetWidget()->GetWindowBoundsInScreen().CenterPoint();
   }
   if (event->type() == ui::ET_TOUCH_MOVED) {
-    view_->UpdatePosition(event->root_location() - touch_offset_);
+    // Keep EyeDropper always inside a display, but adjust offset if it is
+    // pushing up against the bounds.
+    gfx::Point position = event->root_location() - touch_offset_;
+    display::Display display =
+        display::Screen::GetScreen()->GetDisplayNearestPoint(position);
+    if (display.bounds().Contains(position)) {
+      view_->UpdatePosition(std::move(position));
+    } else {
+      touch_offset_ =
+          event->root_location() -
+          view_->GetWidget()->GetWindowBoundsInScreen().CenterPoint();
+    }
   }
 }
 
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn
index e200835..31a8008 100644
--- a/components/optimization_guide/core/BUILD.gn
+++ b/components/optimization_guide/core/BUILD.gn
@@ -263,6 +263,8 @@
       "model_execution/on_device_model_service_controller.h",
       "model_execution/optimization_guide_model_execution_error.cc",
       "model_execution/optimization_guide_model_execution_error.h",
+      "model_execution/redactor.cc",
+      "model_execution/redactor.h",
       "model_execution/session_impl.cc",
       "model_execution/session_impl.h",
       "model_execution/settings_enabled_observer.cc",
@@ -336,6 +338,7 @@
     deps += [
       ":on_device_model_execution_proto_generator",
       "//components/version_info",
+      "//third_party/re2",
     ]
   }
 
@@ -501,6 +504,7 @@
       "model_execution/on_device_model_execution_proto_value_utils_unittest.cc",
       "model_execution/on_device_model_service_controller_unittest.cc",
       "model_execution/optimization_guide_model_execution_error_unittest.cc",
+      "model_execution/redactor_unittest.cc",
       "model_execution/test_on_device_model_component.cc",
       "model_execution/test_on_device_model_component.h",
     ]
diff --git a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc
index 05c1d45..e5cbebb 100644
--- a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc
+++ b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc
@@ -13,6 +13,7 @@
 #include "base/task/thread_pool.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_execution_proto_descriptors.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_execution_proto_value_utils.h"
+#include "components/optimization_guide/core/model_execution/redactor.h"
 #include "components/optimization_guide/core/optimization_guide_constants.h"
 
 namespace optimization_guide {
@@ -39,6 +40,23 @@
   return std::make_unique<proto::OnDeviceModelExecutionConfig>(config);
 }
 
+std::vector<Rule> ExtractRedactRules(const proto::RedactRules& proto_rules) {
+  std::vector<Rule> rules;
+  if (proto_rules.rules_size()) {
+    for (const auto& rule : proto_rules.rules()) {
+      if (rule.has_regex() && rule.has_behavior()) {
+        rules.push_back(Rule());
+        rules.back().regex = rule.regex();
+        rules.back().behavior = rule.behavior();
+        if (rule.has_replacement_string()) {
+          rules.back().replacement_string = rule.replacement_string();
+        }
+      }
+    }
+  }
+  return rules;
+}
+
 std::string StringPrintfVector(const std::string& string_template,
                                std::vector<std::string> args) {
   CHECK(args.size() <= kMaxArgs);
@@ -129,7 +147,56 @@
     proto::ModelExecutionFeature feature) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  return base::Contains(feature_configs_, feature);
+  return base::Contains(feature_to_data_, feature);
+}
+
+std::string
+OnDeviceModelExecutionConfigInterpreter::GetStringToCheckForRedacting(
+    proto::ModelExecutionFeature feature,
+    const google::protobuf::MessageLite& message) const {
+  auto feature_iter = feature_to_data_.find(feature);
+  if (feature_iter == feature_to_data_.end() ||
+      !feature_iter->second->redactor) {
+    return std::string();
+  }
+  const auto& feature_config = feature_iter->second->config;
+  for (const auto& proto_field :
+       feature_config.output_config().redact_rules().fields_to_check()) {
+    std::optional<proto::Value> value = GetProtoValue(message, proto_field);
+    if (value.has_value()) {
+      const std::string string_value = GetStringFromValue(*value);
+      if (!string_value.empty()) {
+        return string_value;
+      }
+    }
+  }
+  return std::string();
+}
+
+const Redactor* OnDeviceModelExecutionConfigInterpreter::GetRedactorForFeature(
+    proto::ModelExecutionFeature feature) const {
+  const auto feature_iter = feature_to_data_.find(feature);
+  return feature_iter != feature_to_data_.end()
+             ? feature_iter->second->redactor.get()
+             : nullptr;
+}
+
+void OnDeviceModelExecutionConfigInterpreter::OverrideFeatureConfigForTesting(
+    const proto::OnDeviceModelExecutionFeatureConfig& config) {
+  RegisterFeature(config);
+}
+
+void OnDeviceModelExecutionConfigInterpreter::RegisterFeature(
+    const proto::OnDeviceModelExecutionFeatureConfig& config) {
+  std::unique_ptr<FeatureData> feature_data = std::make_unique<FeatureData>();
+  feature_data->config = config;
+  if (config.has_output_config() && config.output_config().has_redact_rules() &&
+      config.output_config().redact_rules().fields_to_check_size() &&
+      !config.output_config().redact_rules().rules().empty()) {
+    feature_data->redactor = std::make_unique<Redactor>(
+        ExtractRedactRules(config.output_config().redact_rules()));
+  }
+  feature_to_data_[config.feature()] = std::move(feature_data);
 }
 
 void OnDeviceModelExecutionConfigInterpreter::PopulateFeatureConfigs(
@@ -141,14 +208,14 @@
   }
 
   for (const auto& feature_config : config->feature_configs()) {
-    feature_configs_[feature_config.feature()] = feature_config;
+    RegisterFeature(feature_config);
   }
 }
 
 void OnDeviceModelExecutionConfigInterpreter::ClearState() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  feature_configs_.clear();
+  feature_to_data_.clear();
 }
 
 std::optional<
@@ -160,10 +227,11 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Get the config to construct the input string.
-  if (!HasConfigForFeature(feature)) {
+  auto feature_iter = feature_to_data_.find(feature);
+  if (feature_iter == feature_to_data_.end()) {
     return std::nullopt;
   }
-  auto feature_config = feature_configs_.at(feature);
+  const auto& feature_config = feature_iter->second->config;
   if (!feature_config.has_input_config()) {
     return std::nullopt;
   }
@@ -225,11 +293,11 @@
     const std::string& output) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (!HasConfigForFeature(feature)) {
+  auto iter = feature_to_data_.find(feature);
+  if (iter == feature_to_data_.end()) {
     return std::nullopt;
   }
-
-  auto feature_config = feature_configs_.at(feature);
+  const auto& feature_config = iter->second->config;
   if (!feature_config.has_output_config()) {
     return std::nullopt;
   }
@@ -239,4 +307,7 @@
                        output);
 }
 
+OnDeviceModelExecutionConfigInterpreter::FeatureData::FeatureData() = default;
+OnDeviceModelExecutionConfigInterpreter::FeatureData::~FeatureData() = default;
+
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h
index f3cf437..0fbd12e7 100644
--- a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h
+++ b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h
@@ -18,6 +18,8 @@
 
 namespace optimization_guide {
 
+class Redactor;
+
 class OnDeviceModelExecutionConfigInterpreter {
  public:
   OnDeviceModelExecutionConfigInterpreter();
@@ -54,13 +56,32 @@
       proto::ModelExecutionFeature feature,
       const std::string& output) const;
 
+  // Returns the string that is used for checking redaction against.
+  std::string GetStringToCheckForRedacting(
+      proto::ModelExecutionFeature feature,
+      const google::protobuf::MessageLite& message) const;
+
+  // Returns the Redactor for the specified feature. Return value is owned by
+  // this and may be null.
+  const Redactor* GetRedactorForFeature(
+      proto::ModelExecutionFeature feature) const;
+
   void OverrideFeatureConfigForTesting(
-      const proto::OnDeviceModelExecutionFeatureConfig& config) {
-    feature_configs_[config.feature()] = config;
-  }
+      const proto::OnDeviceModelExecutionFeatureConfig& config);
 
  private:
-  // Populates `feature_configs_` based on `config`.
+  // Contains the state applicable to a feature.
+  struct FeatureData {
+    FeatureData();
+    ~FeatureData();
+    proto::OnDeviceModelExecutionFeatureConfig config;
+    std::unique_ptr<Redactor> redactor;
+  };
+
+  void RegisterFeature(
+      const proto::OnDeviceModelExecutionFeatureConfig& config);
+
+  // Populates `feature_to_data_` based on `config`.
   void PopulateFeatureConfigs(
       std::unique_ptr<proto::OnDeviceModelExecutionConfig> config);
 
@@ -71,10 +92,9 @@
   // The task runner to process new config files on.
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
 
-  // Map from feature to its model execution feature config.
-  base::flat_map<proto::ModelExecutionFeature,
-                 proto::OnDeviceModelExecutionFeatureConfig>
-      feature_configs_;
+  // Map from feature to associated state.
+  base::flat_map<proto::ModelExecutionFeature, std::unique_ptr<FeatureData>>
+      feature_to_data_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller.h b/components/optimization_guide/core/model_execution/on_device_model_service_controller.h
index 6f80b3f..c38b0245 100644
--- a/components/optimization_guide/core/model_execution/on_device_model_service_controller.h
+++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller.h
@@ -105,6 +105,10 @@
   // OnDeviceModelComponentStateManager::Observer.
   void StateChanged(const OnDeviceModelComponentState* state) override;
 
+  OnDeviceModelExecutionConfigInterpreter& ConfigInterpreterForTesting() {
+    return *config_interpreter_;
+  }
+
  protected:
   ~OnDeviceModelServiceController() override;
 
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
index 927f98a..f574f79 100644
--- a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
+++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
@@ -44,6 +44,9 @@
 on_device_model::mojom::ResponseStatus g_on_complete_response_type =
     on_device_model::mojom::ResponseStatus::kOk;
 
+// If non-empty, used as the output from Execute().
+std::string g_model_execute_result;
+
 }  // namespace
 
 std::vector<std::string> ConcatResponses(
@@ -97,7 +100,11 @@
     for (const std::string& context : context_) {
       remote->OnResponse("Context: " + context + "\n");
     }
-    remote->OnResponse("Input: " + input->text + "\n");
+    remote->OnResponse("Input: " +
+                       (g_model_execute_result.empty()
+                            ? input->text
+                            : g_model_execute_result) +
+                       "\n");
     remote->OnComplete(g_on_complete_response_type);
   }
 
@@ -229,6 +236,7 @@
  public:
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    g_model_execute_result.clear();
     g_execute_delay = base::TimeDelta();
     g_on_complete_response_type = on_device_model::mojom::ResponseStatus::kOk;
     feature_list_.InitAndEnableFeatureWithParameters(
@@ -259,18 +267,8 @@
         });
   }
 
-  void RecreateServiceController() {
-    access_controller_ = nullptr;
-    test_controller_ = nullptr;
-
-    auto access_controller =
-        std::make_unique<OnDeviceModelAccessController>(pref_service_);
-    access_controller_ = access_controller.get();
-    test_controller_ = base::MakeRefCounted<FakeOnDeviceModelServiceController>(
-        std::move(access_controller),
-        on_device_component_state_manager_.get()->GetWeakPtr());
-
-    proto::OnDeviceModelExecutionFeatureConfig config;
+  void PopulateConfigForFeature(
+      proto::OnDeviceModelExecutionFeatureConfig& config) {
     config.set_feature(kFeature);
     auto& input_config = *config.mutable_input_config();
     input_config.set_request_base_name(proto::ComposeRequest().GetTypeName());
@@ -304,13 +302,49 @@
     output_config.mutable_proto_field()
         ->add_proto_descriptors()
         ->set_tag_number(1);
+  }
 
+  proto::RedactRule& PopulateConfigForFeatureWithRedactRule(
+      proto::OnDeviceModelExecutionFeatureConfig& config,
+      const std::string& regex,
+      proto::RedactBehavior behavior =
+          proto::RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT) {
+    PopulateConfigForFeature(config);
+    auto& output_config = *config.mutable_output_config();
+    auto& redact_rules = *output_config.mutable_redact_rules();
+    auto& field = *redact_rules.add_fields_to_check();
+    field.add_proto_descriptors()->set_tag_number(7);
+    field.add_proto_descriptors()->set_tag_number(1);
+    auto& redact_rule = *redact_rules.add_rules();
+    redact_rule.set_regex(regex);
+    redact_rule.set_behavior(behavior);
+    return redact_rule;
+  }
+
+  void RecreateServiceController() {
+    access_controller_ = nullptr;
+    test_controller_ = nullptr;
+
+    auto access_controller =
+        std::make_unique<OnDeviceModelAccessController>(pref_service_);
+    access_controller_ = access_controller.get();
+    test_controller_ = base::MakeRefCounted<FakeOnDeviceModelServiceController>(
+        std::move(access_controller),
+        on_device_component_state_manager_.get()->GetWeakPtr());
+
+    proto::OnDeviceModelExecutionFeatureConfig config;
+    PopulateConfigForFeature(config);
     auto config_interpreter =
         std::make_unique<OnDeviceModelExecutionConfigInterpreter>();
-    auto* config_interpreter_raw = config_interpreter.get();
     test_controller_->Init(base::FilePath::FromASCII("/foo"),
                            std::move(config_interpreter));
-    config_interpreter_raw->OverrideFeatureConfigForTesting(config);
+    OverrideFeatureConfigForTesting(config);
+  }
+
+  void OverrideFeatureConfigForTesting(
+      const proto::OnDeviceModelExecutionFeatureConfig& config) {
+    test_controller_->ConfigInterpreterForTesting()
+        .OverrideFeatureConfigForTesting(config);
   }
 
   void AddContext(OptimizationGuideModelExecutor::Session& session,
@@ -320,6 +354,7 @@
     session.AddContext(request);
   }
 
+  // Calls Execute() after setting `input` as the page-url.
   void ExecuteModel(OptimizationGuideModelExecutor::Session& session,
                     std::string_view input) {
     proto::ComposeRequest request;
@@ -330,6 +365,29 @@
                             base::Unretained(this)));
   }
 
+  // Calls Execute() after setting `input` as the user_input.
+  void ExecuteModelUsingInput(OptimizationGuideModelExecutor::Session& session,
+                              std::string_view input) {
+    proto::ComposeRequest request;
+    request.mutable_generate_params()->set_user_input(std::string(input));
+    session.ExecuteModel(
+        request,
+        base::BindRepeating(&OnDeviceModelServiceControllerTest::OnResponse,
+                            base::Unretained(this)));
+  }
+
+  void ExecuteModelWithRewrite(
+      OptimizationGuideModelExecutor::Session& session) {
+    proto::ComposeRequest request;
+    auto& rewrite_params = *request.mutable_rewrite_params();
+    rewrite_params.set_previous_response("bar");
+    rewrite_params.set_tone(proto::COMPOSE_FORMAL);
+    session.ExecuteModel(
+        request,
+        base::BindRepeating(&OnDeviceModelServiceControllerTest::OnResponse,
+                            base::Unretained(this)));
+  }
+
   base::FilePath temp_dir() const { return temp_dir_.GetPath(); }
 
  protected:
@@ -909,10 +967,9 @@
   config.set_feature(kFeature);
   auto config_interpreter =
       std::make_unique<OnDeviceModelExecutionConfigInterpreter>();
-  auto* config_interpreter_raw = config_interpreter.get();
   test_controller_->Init(base::FilePath::FromASCII("/foo"),
                          std::move(config_interpreter));
-  config_interpreter_raw->OverrideFeatureConfigForTesting(config);
+  OverrideFeatureConfigForTesting(config);
 
   auto session = test_controller_->CreateSession(
       kFeature, CreateExecuteRemoteFn(), &logger_);
@@ -953,10 +1010,9 @@
   config.set_feature(kFeature);
   auto config_interpreter =
       std::make_unique<OnDeviceModelExecutionConfigInterpreter>();
-  auto* config_interpreter_raw = config_interpreter.get();
   test_controller_->Init(base::FilePath::FromASCII("/foo"),
                          std::move(config_interpreter));
-  config_interpreter_raw->OverrideFeatureConfigForTesting(config);
+  OverrideFeatureConfigForTesting(config);
 
   auto session = test_controller_->CreateSession(
       kFeature, CreateExecuteRemoteFn(), &logger_);
@@ -1120,4 +1176,106 @@
       OptimizationGuideModelExecutionError::ModelExecutionError::kFiltered);
 }
 
+TEST_F(OnDeviceModelServiceControllerTest, RedactedField) {
+  proto::OnDeviceModelExecutionFeatureConfig config;
+  PopulateConfigForFeatureWithRedactRule(config, "bar");
+  OverrideFeatureConfigForTesting(config);
+
+  // `foo` doesn't match the redaction, so should be returned.
+  auto session1 =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session1);
+  ExecuteModelUsingInput(*session1, "foo");
+  task_environment_.RunUntilIdle();
+  const std::string expected_response1 = "Input: execute:foo\n";
+  EXPECT_EQ(*response_received_, expected_response1);
+  EXPECT_THAT(streamed_responses_, ElementsAre(expected_response1));
+
+  // Input and output contain text matching redact, so should not be redacted.
+  response_received_.reset();
+  streamed_responses_.clear();
+  auto session2 =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session2);
+  ExecuteModelUsingInput(*session2, "abarx");
+  task_environment_.RunUntilIdle();
+  const std::string expected_response2 = "Input: execute:abarx\n";
+  EXPECT_EQ(*response_received_, expected_response2);
+  EXPECT_THAT(streamed_responses_, ElementsAre(expected_response2));
+
+  // Output contains redacted text (and  input doesn't), so redact.
+  g_model_execute_result = "abarx";
+  response_received_.reset();
+  streamed_responses_.clear();
+  auto session3 =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session3);
+  ExecuteModelUsingInput(*session3, "foo");
+  task_environment_.RunUntilIdle();
+  const std::string expected_response3 = "Input: a[###]x\n";
+  EXPECT_EQ(*response_received_, expected_response3);
+  EXPECT_THAT(streamed_responses_, ElementsAre(expected_response3));
+}
+
+TEST_F(OnDeviceModelServiceControllerTest, RejectedField) {
+  proto::OnDeviceModelExecutionFeatureConfig config;
+  PopulateConfigForFeatureWithRedactRule(config, "bar",
+                                         proto::RedactBehavior::REJECT);
+  OverrideFeatureConfigForTesting(config);
+
+  auto session1 =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session1);
+  ExecuteModelUsingInput(*session1, "bar");
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(response_received_);
+  ASSERT_TRUE(response_error_);
+  EXPECT_EQ(
+      *response_error_,
+      OptimizationGuideModelExecutionError::ModelExecutionError::kFiltered);
+}
+
+TEST_F(OnDeviceModelServiceControllerTest, UsePreviousResponseForRewrite) {
+  proto::OnDeviceModelExecutionFeatureConfig config;
+  PopulateConfigForFeatureWithRedactRule(config, "bar");
+  // Add a rule that identifies `previous_response` of `rewrite_params`.
+  auto& output_config = *config.mutable_output_config();
+  auto& redact_rules = *output_config.mutable_redact_rules();
+  auto& field = *redact_rules.add_fields_to_check();
+  field.add_proto_descriptors()->set_tag_number(8);
+  field.add_proto_descriptors()->set_tag_number(1);
+  OverrideFeatureConfigForTesting(config);
+
+  // Force 'bar' to be returned from model.
+  g_model_execute_result = "bar";
+
+  auto session =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session);
+  ExecuteModelWithRewrite(*session);
+  task_environment_.RunUntilIdle();
+  // `bar` shouldn't be rewritten as it's in the input.
+  const std::string expected_response = "Input: bar\n";
+  EXPECT_EQ(*response_received_, expected_response);
+  EXPECT_THAT(streamed_responses_, ElementsAre(expected_response));
+}
+
+TEST_F(OnDeviceModelServiceControllerTest, ReplacementText) {
+  proto::OnDeviceModelExecutionFeatureConfig config;
+  PopulateConfigForFeatureWithRedactRule(config, "bar")
+      .set_replacement_string("[redacted]");
+  OverrideFeatureConfigForTesting(config);
+
+  // Output contains redacted text (and  input doesn't), so redact.
+  g_model_execute_result = "abarx";
+  auto session =
+      test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_);
+  ASSERT_TRUE(session);
+  ExecuteModelUsingInput(*session, "foo");
+  task_environment_.RunUntilIdle();
+  const std::string expected_response = "Input: a[redacted]x\n";
+  EXPECT_EQ(*response_received_, expected_response);
+  EXPECT_THAT(streamed_responses_, ElementsAre(expected_response));
+}
+
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/redactor.cc b/components/optimization_guide/core/model_execution/redactor.cc
new file mode 100644
index 0000000..4347f61
--- /dev/null
+++ b/components/optimization_guide/core/model_execution/redactor.cc
@@ -0,0 +1,103 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/optimization_guide/core/model_execution/redactor.h"
+
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
+#include "third_party/re2/src/re2/re2.h"
+
+namespace optimization_guide {
+
+Rule::Rule() = default;
+Rule::Rule(const Rule& r) = default;
+Rule::~Rule() = default;
+
+Redactor::RuleImpl::RuleImpl() = default;
+
+Redactor::RuleImpl::~RuleImpl() = default;
+
+Redactor::Redactor(const std::vector<Rule>& rules) {
+  for (const auto& rule : rules) {
+    if (rule.behavior == proto::RedactBehavior::REDACT_BEHAVIOR_UNSPECIFIED) {
+      continue;
+    }
+    auto rule_impl = std::make_unique<RuleImpl>();
+    rule_impl->re = std::make_unique<re2::RE2>(rule.regex);
+    rule_impl->behavior = rule.behavior;
+    rule_impl->replacement_string = rule.replacement_string;
+    rules_.push_back(std::move(rule_impl));
+  }
+}
+
+Redactor::~Redactor() = default;
+
+RedactResult Redactor::Redact(const std::string& input,
+                              std::string& output) const {
+  for (auto& rule : rules_) {
+    if (ProcessRule(*rule, input, output) == RedactResult::kReject) {
+      return RedactResult::kReject;
+    }
+  }
+  return RedactResult::kContinue;
+}
+
+RedactResult Redactor::ProcessRule(const RuleImpl& rule,
+                                   const std::string& input,
+                                   std::string& output) const {
+  // This is rather expensive, only enter the main loop if there is at least one
+  // match.
+  absl::string_view output_view(output);
+  absl::string_view match;
+  if (!rule.re->Match(output_view, 0, output_view.length(),
+                      re2::RE2::UNANCHORED, &match, 1)) {
+    return RedactResult::kContinue;
+  }
+
+  if (rule.behavior == proto::RedactBehavior::REJECT) {
+    return RedactResult::kReject;
+  }
+
+  size_t last_match_start = 0;
+  std::string new_output;
+  size_t next_start_offset;
+  do {
+    next_start_offset = match.data() - output_view.data() + match.length();
+    if (rule.behavior == proto::RedactBehavior::REDACT_ALWAYS ||
+        input.find(match) == std::string::npos) {
+      const size_t match_start_offset_in_output =
+          match.data() - output_view.data();
+      new_output +=
+          base::StrCat({std::string_view(output).substr(
+                            last_match_start,
+                            match_start_offset_in_output - last_match_start),
+                        GetReplacementString(rule, match)});
+      last_match_start = match_start_offset_in_output + match.length();
+    }
+  } while (next_start_offset < output_view.length() &&
+           rule.re->Match(output_view, next_start_offset, output_view.length(),
+                          re2::RE2::UNANCHORED, &match, 1));
+  if (last_match_start == 0) {
+    // No replacement happened, nothing to do.
+    return RedactResult::kContinue;
+  }
+  if (last_match_start != output.length()) {
+    new_output += output.substr(last_match_start);
+  }
+  std::swap(output, new_output);
+  return RedactResult::kContinue;
+}
+
+std::string Redactor::GetReplacementString(const RuleImpl& rule,
+                                           absl::string_view match) const {
+  if (rule.replacement_string.has_value()) {
+    return *rule.replacement_string;
+  }
+  std::string replacement(match.length() + 2, '#');
+  replacement[0] = '[';
+  replacement.back() = ']';
+  return replacement;
+}
+
+}  // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/redactor.h b/components/optimization_guide/core/model_execution/redactor.h
new file mode 100644
index 0000000..3ddddf11
--- /dev/null
+++ b/components/optimization_guide/core/model_execution/redactor.h
@@ -0,0 +1,72 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_
+#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "components/optimization_guide/proto/model_execution.pb.h"
+
+namespace re2 {
+class RE2;
+}  // namespace re2
+
+namespace optimization_guide {
+
+struct Rule {
+  Rule();
+  Rule(const Rule& r);
+  ~Rule();
+
+  std::string regex;
+  proto::RedactBehavior behavior;
+  // If supplied, replaces the matching string.
+  std::optional<std::string> replacement_string;
+};
+
+enum RedactResult {
+  // Used if there was at least one rule that matched with a behavior of reject.
+  kReject,
+
+  // No rules with reject matched.
+  kContinue,
+};
+
+// Used to redact (or reject) text.
+class Redactor {
+ public:
+  explicit Redactor(const std::vector<Rule>& rules);
+  ~Redactor();
+
+  // Redacts (or rejects) the applicable text in`output`. `input` is the string
+  // regexes of type REDACT_IF_ONLY_IN_OUTPUT checks.
+  RedactResult Redact(const std::string& input, std::string& output) const;
+
+ private:
+  struct RuleImpl {
+    RuleImpl();
+    ~RuleImpl();
+    std::unique_ptr<re2::RE2> re;
+    proto::RedactBehavior behavior;
+    std::optional<std::string> replacement_string;
+  };
+
+  std::string GetReplacementString(const RuleImpl& rule,
+                                   std::string_view match) const;
+
+  // Processes a single regex, applying any redactions to `output`.
+  RedactResult ProcessRule(const RuleImpl& rule,
+                           const std::string& input,
+                           std::string& output) const;
+
+  std::vector<std::unique_ptr<RuleImpl>> rules_;
+};
+
+}  // namespace optimization_guide
+
+#endif  // COMPONENTS_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_
diff --git a/components/optimization_guide/core/model_execution/redactor_unittest.cc b/components/optimization_guide/core/model_execution/redactor_unittest.cc
new file mode 100644
index 0000000..1235410
--- /dev/null
+++ b/components/optimization_guide/core/model_execution/redactor_unittest.cc
@@ -0,0 +1,73 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/optimization_guide/core/model_execution/redactor.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace optimization_guide {
+
+using proto::RedactBehavior;
+
+Rule CreateRule(
+    const std::string& regex,
+    RedactBehavior behavior = RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT,
+    std::optional<std::string> replacement_string = std::nullopt) {
+  Rule rule;
+  rule.regex = regex;
+  rule.behavior = behavior;
+  rule.replacement_string = std::move(replacement_string);
+  return rule;
+}
+
+TEST(RedactorTest, RedactMultipleHitsNotPresentInInput) {
+  Redactor redactor({CreateRule("ab")});
+  std::string output("ab cab");
+  EXPECT_EQ(RedactResult::kContinue, redactor.Redact(std::string(), output));
+  EXPECT_EQ("[##] c[##]", output);
+}
+
+TEST(RedactorTest, RedactMultipleHits) {
+  Redactor redactor({CreateRule("ab")});
+  std::string output("ab cab");
+  redactor.Redact("zabq", output);
+  EXPECT_EQ("ab cab", output);
+}
+
+TEST(RedactorTest, RedactMultipleHitsMultipleRegex) {
+  Redactor redactor({CreateRule("ab"), CreateRule("z")});
+  std::string output("ab zcab");
+  redactor.Redact(std::string(), output);
+  EXPECT_EQ("[##] [#]c[##]", output);
+}
+
+TEST(RedactorTest, RedactNotAtEnd) {
+  Redactor redactor({CreateRule("ab")});
+  std::string output("abc");
+  redactor.Redact(std::string(), output);
+  EXPECT_EQ("[##]c", output);
+}
+
+TEST(RedactorTest, RedactAlways) {
+  Redactor redactor({CreateRule("ab", RedactBehavior::REDACT_ALWAYS)});
+  std::string output("abc");
+  redactor.Redact("ab", output);
+  EXPECT_EQ("[##]c", output);
+}
+
+TEST(RedactorTest, Reject) {
+  Redactor redactor({CreateRule("ab", RedactBehavior::REJECT)});
+  std::string output("abc");
+  EXPECT_EQ(RedactResult::kReject, redactor.Redact(std::string(), output));
+}
+
+TEST(RedactorTest, RedactWithReplacmentText) {
+  Redactor redactor({CreateRule("ab", RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT,
+                                "|redacted)")});
+  std::string output("ab cab");
+  EXPECT_EQ(RedactResult::kContinue, redactor.Redact(std::string(), output));
+  EXPECT_EQ("|redacted) c|redacted)", output);
+}
+
+}  // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/session_impl.cc b/components/optimization_guide/core/model_execution/session_impl.cc
index e76c0295..d0d2e265 100644
--- a/components/optimization_guide/core/model_execution/session_impl.cc
+++ b/components/optimization_guide/core/model_execution/session_impl.cc
@@ -10,6 +10,7 @@
 #include "components/optimization_guide/core/model_execution/on_device_model_access_controller.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_service_controller.h"
+#include "components/optimization_guide/core/model_execution/redactor.h"
 #include "components/optimization_guide/core/optimization_guide_features.h"
 #include "components/optimization_guide/core/optimization_guide_logger.h"
 #include "components/optimization_guide/core/optimization_guide_util.h"
@@ -354,8 +355,28 @@
     return;
   }
 
+  std::string current_response = on_device_state_->current_response;
+  if (auto* redactor =
+          on_device_state_->config_interpreter->GetRedactorForFeature(
+              feature_)) {
+    auto redact_string_input =
+        on_device_state_->config_interpreter->GetStringToCheckForRedacting(
+            feature_, *last_message_);
+    if (redactor->Redact(redact_string_input, current_response) ==
+        RedactResult::kReject) {
+      if (on_device_state_->histogram_logger) {
+        on_device_state_->histogram_logger->set_result(
+            ExecuteModelResult::kContainedPII);
+        on_device_state_->histogram_logger.reset();
+      }
+      CancelPendingResponse(ExecuteModelResult::kUsedOnDeviceOutputUnsafe,
+                            ModelExecutionError::kFiltered);
+      return;
+    }
+  }
+
   auto output = on_device_state_->config_interpreter->ConstructOutputMetadata(
-      feature_, on_device_state_->current_response);
+      feature_, current_response);
   if (!output) {
     if (on_device_state_->histogram_logger) {
       on_device_state_->histogram_logger->set_result(
diff --git a/components/optimization_guide/core/model_execution/session_impl.h b/components/optimization_guide/core/model_execution/session_impl.h
index dd36209f..27876215 100644
--- a/components/optimization_guide/core/model_execution/session_impl.h
+++ b/components/optimization_guide/core/model_execution/session_impl.h
@@ -74,7 +74,9 @@
     // On-device was used, it completed successfully, but the output is
     // considered unsafe.
     kUsedOnDeviceOutputUnsafe = 9,
-    kMaxValue = kUsedOnDeviceOutputUnsafe,
+    // On-device was used, but the output was rejected (because contained PII).
+    kContainedPII = 10,
+    kMaxValue = kContainedPII,
   };
 
   SessionImpl(StartSessionFn start_session_fn,
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal
index 2e8649b..d6d170d 160000
--- a/components/optimization_guide/internal
+++ b/components/optimization_guide/internal
@@ -1 +1 @@
-Subproject commit 2e8649b36bd3e4e0ae00efabffc0e5a512316a2c
+Subproject commit d6d170dc380770ce81ad2f7ea55435c98fe4083a
diff --git a/components/optimization_guide/proto/model_execution.proto b/components/optimization_guide/proto/model_execution.proto
index 2962e64..e3a50296 100644
--- a/components/optimization_guide/proto/model_execution.proto
+++ b/components/optimization_guide/proto/model_execution.proto
@@ -67,6 +67,41 @@
   repeated OnDeviceModelExecutionFeatureConfig feature_configs = 1;
 }
 
+enum RedactBehavior {
+  // No redaction.
+  REDACT_BEHAVIOR_UNSPECIFIED = 0;
+
+  // Results in rejecting the output entirely.
+  REJECT = 1;
+
+  // Redacts the text if only in the output (not in the redact input string).
+  REDACT_IF_ONLY_IN_OUTPUT = 2;
+
+  // Redacts regardless of whether it occurs in the input or not.
+  REDACT_ALWAYS = 3;
+}
+
+message RedactRule {
+  optional RedactBehavior behavior = 1;
+  optional string regex = 2;
+  // If supplied, replaces the matching string.
+  optional string replacement_string = 3;
+  // TODO: add support for replacement character.
+}
+
+// Applies a set of rules to a field.
+message RedactRules {
+  // Identifies the field to be checked for redaction (see
+  // REDACT_IF_ONLY_IN_OUTPUT). The first ProtoField that identifies a
+  // non-empty string is used.
+  repeated ProtoField fields_to_check = 1;
+
+  // The set of regular exrepssions to check. When checking the regular
+  // expressions all are checked, unless one matches with a behavior of REJECT,
+  // in which case no need to continue.
+  repeated RedactRule rules = 2;
+}
+
 message OnDeviceModelExecutionFeatureConfig {
   // The feature this configuration is for.
   optional ModelExecutionFeature feature = 1;
@@ -201,4 +236,7 @@
 
   // The proto field to populate the output string with.
   optional ProtoField proto_field = 2;
+
+  // Rules that result in redacting the output.
+  optional RedactRules redact_rules = 3;
 }
diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h
index df935aa5..e61981b 100644
--- a/components/page_info/page_info.h
+++ b/components/page_info/page_info.h
@@ -447,7 +447,7 @@
   // specific data (local stored objects like cookies), site-specific
   // permissions (location, pop-up, plugin, etc. permissions) and site-specific
   // information (identity, connection status, etc.).
-  raw_ptr<PageInfoUI, DanglingUntriaged> ui_ = nullptr;
+  raw_ptr<PageInfoUI> ui_ = nullptr;
 
   // A web contents getter used to retrieve the associated WebContents object.
   base::WeakPtr<content::WebContents> web_contents_;
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
index b6faeba..81b4db2 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger.cc
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -4,6 +4,7 @@
 
 #include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
 
+#include <optional>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -26,6 +27,7 @@
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_form_metrics_recorder.h"
 #include "components/password_manager/core/browser/password_manager.h"
+#include "components/password_manager/core/browser/votes_uploader.h"
 
 using autofill::AutofillType;
 using autofill::AutofillUploadContents;
@@ -216,7 +218,8 @@
 
 void BrowserSavePasswordProgressLogger::LogFormStructure(
     StringID label,
-    const FormStructure& form_structure) {
+    const FormStructure& form_structure,
+    std::optional<PasswordAttributesMetadata> password_attributes) {
   std::string message = GetStringFromID(label) + ": {\n";
   message += GetStringFromID(STRING_FORM_SIGNATURE) + ": " +
              FormSignatureToDebugString(form_structure.form_signature()) + "\n";
@@ -229,7 +232,7 @@
   message += GetStringFromID(STRING_ACTION) + ": " +
              ScrubURL(form_structure.target_url()) + "\n";
   message += FormStructureToFieldsLogString(form_structure);
-  message += FormStructurePasswordAttributesLogString(form_structure);
+  message += VotesPasswordAttributesLogString(password_attributes);
   message += "}";
   SendLog(message);
 }
@@ -247,16 +250,15 @@
   SendLog(message);
 }
 
-std::string
-BrowserSavePasswordProgressLogger::FormStructurePasswordAttributesLogString(
-    const FormStructure& form) {
-  const std::optional<std::pair<PasswordAttribute, bool>> attribute_vote =
-      form.get_password_attributes_vote();
-  if (!attribute_vote.has_value())
+std::string BrowserSavePasswordProgressLogger::VotesPasswordAttributesLogString(
+    std::optional<PasswordAttributesMetadata> password_attributes) {
+  if (!password_attributes.has_value()) {
     return std::string();
+  }
+  const std::pair<PasswordAttribute, bool> attribute_vote =
+      password_attributes->password_attributes_vote;
   std::string message;
-  const PasswordAttribute attribute = std::get<0>(attribute_vote.value());
-  const bool attribute_value = std::get<1>(attribute_vote.value());
+  const auto [attribute, attribute_value] = attribute_vote;
 
   switch (attribute) {
     case PasswordAttribute::kHasLetter:
@@ -270,7 +272,7 @@
           attribute_value);
       if (attribute_value) {
         std::string voted_symbol(
-            1, static_cast<char>(form.get_password_symbol_vote()));
+            1, static_cast<char>(password_attributes->password_symbol_vote));
         message += PasswordAttributeLogString(
             STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIFIC_SPECIAL_SYMBOL,
             voted_symbol);
@@ -281,7 +283,7 @@
       break;
   }
   std::string password_length =
-      base::NumberToString(form.get_password_length_vote());
+      base::NumberToString(password_attributes->password_length_vote);
   message += PasswordAttributeLogString(
       STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_PASSWORD_LENGTH, password_length);
 
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.h b/components/password_manager/core/browser/browser_save_password_progress_logger.h
index b56e5d9..a5eecb8 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger.h
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_BROWSER_SAVE_PASSWORD_PROGRESS_LOGGER_H_
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_BROWSER_SAVE_PASSWORD_PROGRESS_LOGGER_H_
 
+#include <optional>
 #include <string>
 
 #include "base/containers/flat_map.h"
@@ -13,6 +14,7 @@
 #include "components/autofill/core/browser/proto/password_requirements.pb.h"
 #include "components/autofill/core/common/mojom/autofill_types.mojom.h"
 #include "components/autofill/core/common/save_password_progress_logger.h"
+#include "components/password_manager/core/browser/votes_uploader.h"
 #include "url/gurl.h"
 
 namespace autofill {
@@ -48,7 +50,10 @@
 
   // Browser-specific addition to the base class' Log* methods. The input is
   // sanitized and passed to SendLog for display.
-  void LogFormStructure(StringID label, const autofill::FormStructure& form);
+  void LogFormStructure(
+      StringID label,
+      const autofill::FormStructure& form,
+      std::optional<PasswordAttributesMetadata> password_attributes);
 
   // Browser-specific addition to the base class' Log* methods. The input is
   // sanitized and passed to SendLog for display.
@@ -88,10 +93,10 @@
   static std::string FormStructureToFieldsLogString(
       const autofill::FormStructure& form);
 
-  // Returns the string representation of password attributes for
-  // `FormStructure`.
-  static std::string FormStructurePasswordAttributesLogString(
-      const autofill::FormStructure& form);
+  // Returns the string representation of votes related password attributes from
+  // the `password_attributes`.
+  static std::string VotesPasswordAttributesLogString(
+      std::optional<PasswordAttributesMetadata> password_attributes);
 
   // Returns the string representation of a password attribute.
   static std::string PasswordAttributeLogString(
diff --git a/components/password_manager/core/browser/credential_cache.cc b/components/password_manager/core/browser/credential_cache.cc
index ffe7211..66628e8 100644
--- a/components/password_manager/core/browser/credential_cache.cc
+++ b/components/password_manager/core/browser/credential_cache.cc
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "components/autofill/core/common/autofill_features.h"
+#include "components/password_manager/core/browser/features/password_features.h"
 #include "components/password_manager/core/browser/origin_credential_store.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "url/origin.h"
@@ -49,7 +50,13 @@
   for (const PasswordForm* form : best_matches) {
     if (form->type == PasswordForm::Type::kReceivedViaSharing &&
         !form->sharing_notification_displayed) {
-      unnotified_shared_credentials.push_back(*form);
+      // The cache is only useful when the sharing notification UI is displayed
+      // since it is used to mark those credentials as notified after the user
+      // interacts with the UI.
+      if (base::FeatureList::IsEnabled(
+              password_manager::features::kSharedPasswordNotificationUI)) {
+        unnotified_shared_credentials.push_back(*form);
+      }
     }
   }
   GetOrCreateCredentialStore(origin).SaveUnnotifiedSharedCredentials(
diff --git a/components/password_manager/core/browser/credential_cache_unittest.cc b/components/password_manager/core/browser/credential_cache_unittest.cc
index 023a0a7..7d5ebfc6 100644
--- a/components/password_manager/core/browser/credential_cache_unittest.cc
+++ b/components/password_manager/core/browser/credential_cache_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "components/password_manager/core/browser/origin_credential_store.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
@@ -118,6 +119,9 @@
 }
 
 TEST_F(CredentialCacheTest, StoresUnnotifiedSharedCredentialsCredentials) {
+  base::test::ScopedFeatureList feature_list(
+      password_manager::features::kSharedPasswordNotificationUI);
+
   Origin origin = Origin::Create(GURL(kExampleSite));
 
   std::unique_ptr<PasswordForm> non_shared_credentials =
@@ -146,6 +150,30 @@
       testing::ElementsAre(*shared_unnotified_credentials));
 }
 
+TEST_F(
+    CredentialCacheTest,
+    DoesNotStoreUnnotifiedSharedCredentialsCredentialsWhenFeatureIsDisabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(
+      password_manager::features::kSharedPasswordNotificationUI);
+
+  Origin origin = Origin::Create(GURL(kExampleSite));
+
+  std::unique_ptr<PasswordForm> shared_unnotified_credentials =
+      CreateEntry("shared_unnotified", "pass", GURL(kExampleSite),
+                  PasswordForm::MatchType::kExact);
+  shared_unnotified_credentials->type = PasswordForm::Type::kReceivedViaSharing;
+  shared_unnotified_credentials->sharing_notification_displayed = false;
+
+  cache()->SaveCredentialsAndBlocklistedForOrigin(
+      {shared_unnotified_credentials.get()}, IsOriginBlocklisted(false),
+      origin);
+
+  EXPECT_THAT(
+      cache()->GetCredentialStore(origin).GetUnnotifiedSharedCredentials(),
+      testing::IsEmpty());
+}
+
 TEST_F(CredentialCacheTest, StoresCredentialsForIndependentOrigins) {
   Origin origin = Origin::Create(GURL(kExampleSite));
   Origin origin2 = Origin::Create(GURL(kExampleSite2));
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 619aa04..2f895a4 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -583,7 +583,7 @@
                   FieldSingleUsernameVoteTypeIs(vote_type),
                   FieldIsMostRecentSingleUsernameCandidateIs(most_recent))));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _));
+                StartUploadRequest(upload_contents_matcher, _, _, _));
   }
 
   // Creates LRU cache simulating user modifying non-password field outside of
@@ -1271,7 +1271,7 @@
         UploadFieldIs(submitted_form.fields[0], FieldType::PASSWORD),
         UploadFieldIs(submitted_form.fields[1], expected_vote)));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _));
+                StartUploadRequest(upload_contents_matcher, _, _, _));
     if (expected_vote == autofill::NEW_PASSWORD) {
       // An unrelated |FIRST_USE| vote.
       EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest);
@@ -1359,7 +1359,7 @@
               FieldVoteTypeIs(Field::USERNAME_OVERWRITTEN)),
           UploadFieldIs(password_field, FieldType::ACCOUNT_CREATION_PASSWORD)));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   form_manager_->Save();
 }
@@ -1413,7 +1413,7 @@
                     saved_match_.form_data.fields[kPasswordFieldIndex])),
                 FieldVoteTypeIs(Field::CREDENTIALS_REUSED))));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Saved credentials from the signup form were used for the first time on a
   // submitted form. The vote applies to the new form being submitted.
@@ -1426,7 +1426,7 @@
                               submitted_form_.fields[kPasswordFieldIndex])),
                           FieldVoteTypeIs(Field::FIRST_USE))));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   form_manager_->Save();
 }
@@ -1470,7 +1470,7 @@
                     FieldType::PASSWORD,
                     FieldGenerationTypeIs(Field::NO_GENERATION))));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
   form_manager_->Save();
 }
 
@@ -1555,7 +1555,7 @@
                               submitted_form_.fields[kPasswordFieldIndex])),
                           FieldGenerationTypeIs(Field::NO_GENERATION))));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
   form_manager_->Save();
 }
 
@@ -1589,7 +1589,7 @@
   auto upload_contents_matcher = IsPasswordUpload(FieldsContain(UploadFieldIs(
       submitted_form_.fields[kPasswordFieldIndex], FieldType::PASSWORD)));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Check that the password which was chosen by the user is saved.
   MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
@@ -2294,10 +2294,10 @@
     if (password_revealed)
       form_manager_->OnPasswordsRevealed();
 
-    EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(
-                    IsPasswordUpload(PasswordsRevealedIs(password_revealed)), _,
-                    _, _, _));
+    EXPECT_CALL(
+        crowdsourcing_manager(),
+        StartUploadRequest(
+            IsPasswordUpload(PasswordsRevealedIs(password_revealed)), _, _, _));
     form_manager_->Save();
     Mock::VerifyAndClearExpectations(&crowdsourcing_manager());
   }
@@ -2323,7 +2323,7 @@
                   submitted_form_.fields[kPasswordFieldIndex])),
               FieldGenerationTypeIs(Field::IGNORED_GENERATION_POPUP))));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _))
+                StartUploadRequest(upload_contents_matcher, _, _, _))
         .Times(generation_popup_shown ? 1 : 0);
     form_manager_->OnNoInteraction(false /*is_update */);
     Mock::VerifyAndClearExpectations(&crowdsourcing_manager());
@@ -2350,7 +2350,7 @@
                   submitted_form_.fields[kPasswordFieldIndex])),
               FieldGenerationTypeIs(Field::IGNORED_GENERATION_POPUP))));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _))
+                StartUploadRequest(upload_contents_matcher, _, _, _))
         .Times(generation_popup_shown ? 1 : 0);
 
     form_manager_->OnNeverClicked();
@@ -2736,7 +2736,7 @@
           UploadFieldIs(submitted_form.fields[1], FieldType::UNKNOWN_TYPE),
           UploadFieldIs(submitted_form.fields[2], FieldType::PASSWORD)));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
   form_manager_->Save();
 }
 
@@ -2790,7 +2790,7 @@
     // Upload username first flow votes on the username form.
     if constexpr (!BUILDFLAG(IS_ANDROID)) {
       EXPECT_CALL(crowdsourcing_manager(),
-                  StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _));
+                  StartUploadRequest(IsSingleUsernameUpload(), _, _, _));
     }
 
     // Upload username first flow votes on the password form.
@@ -2809,13 +2809,13 @@
         SingleUsernameDataIs(
             EqualsSingleUsernameDataVector({expected_single_username_data})));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _));
+                StartUploadRequest(upload_contents_matcher, _, _, _));
 
     if (is_password_update) {
       EXPECT_CALL(
           crowdsourcing_manager(),
           StartUploadRequest(IsPasswordUpload(SingleUsernameDataIs(IsEmpty())),
-                             _, _, _, _));
+                             _, _, _));
     }
 
     base::HistogramTester histogram_tester;
@@ -2868,7 +2868,7 @@
   // Upload username first flow vote on the single username form.
   if constexpr (!BUILDFLAG(IS_ANDROID)) {
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _));
+                StartUploadRequest(IsSingleUsernameUpload(), _, _, _));
   }
 
   // Upload username first flow vote on the sign-up form.
@@ -2886,7 +2886,7 @@
       SingleUsernameDataIs(
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Simulate showing the prompt and saving the suggested value.
   form_manager_->SaveSuggestedUsernameValueToVotesUploader();
@@ -2955,7 +2955,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form_))),
-                                 _, _, _, _));
+                                 _, _, _));
   form_manager_->Save();
 }
 
@@ -3015,7 +3015,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form_))),
-                                 _, _, _, _));
+                                 _, _, _));
   form_manager_->Save();
 }
 
@@ -3062,7 +3062,7 @@
       crowdsourcing_manager(),
       StartUploadRequest(
           IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _,
-          _, _))
+          _))
       .Times(0);
 
   // Expect upload for the password form. This upload is unrelated to UFF: it
@@ -3070,7 +3070,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form_))),
-                                 _, _, _, _));
+                                 _, _, _));
   form_manager_->Save();
 }
 
@@ -3126,7 +3126,7 @@
   // Upload username first flow vote on the single username form.
   if constexpr (!BUILDFLAG(IS_ANDROID)) {
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _));
+                StartUploadRequest(IsSingleUsernameUpload(), _, _, _));
   }
 
   // Upload username first flow vote on the sign-up form.
@@ -3144,7 +3144,7 @@
       SingleUsernameDataIs(
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Simulate showing the prompt and saving the suggested value.
   form_manager_->SaveSuggestedUsernameValueToVotesUploader();
@@ -3246,7 +3246,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form))),
-                                 _, _, _, _));
+                                 _, _, _));
 
   form_manager_->Save();
 }
@@ -3369,7 +3369,7 @@
         FieldsContain(AllOf(FieldSignatureIs(kUsernameFieldSignature),
                             FieldAutofillTypeIs({FieldType::NOT_USERNAME}))));
     EXPECT_CALL(crowdsourcing_manager(),
-                StartUploadRequest(upload_contents_matcher, _, _, _, _));
+                StartUploadRequest(upload_contents_matcher, _, _, _));
   } else {
     EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest).Times(0);
   }
@@ -3389,7 +3389,7 @@
       SingleUsernameDataIs(
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
   base::HistogramTester histogram_tester;
   form_manager_->Save();
 
@@ -3438,7 +3438,7 @@
       crowdsourcing_manager(),
       StartUploadRequest(
           IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _,
-          _, _))
+          _))
       .Times(0);
 
   // Upload single username data for the password form.
@@ -3450,7 +3450,7 @@
       SingleUsernameDataIs(
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
   form_manager_->Save();
 }
 
@@ -3869,7 +3869,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form))),
-                                 _, _, _, _));
+                                 _, _, _));
 
   form_manager_->Save();
 }
@@ -3921,7 +3921,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form))),
-                                 _, _, _, _));
+                                 _, _, _));
 
   form_manager_->Save();
 }
@@ -3967,7 +3967,7 @@
   EXPECT_CALL(
       crowdsourcing_manager(),
       StartUploadRequest(IsPasswordUpload(FormSignatureIs(kOtherFormSignature)),
-                         _, _, _, _))
+                         _, _, _))
       .Times(0);
 
   // Expect upload for the password form. This upload is unrelated to FPF: it
@@ -3975,7 +3975,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form))),
-                                 _, _, _, _));
+                                 _, _, _));
 
   form_manager_->Save();
 }
@@ -4028,7 +4028,7 @@
   EXPECT_CALL(
       crowdsourcing_manager(),
       StartUploadRequest(IsPasswordUpload(FormSignatureIs(kOtherFormSignature)),
-                         _, _, _, _))
+                         _, _, _))
       .Times(0);
 
   // Expect upload for the password form. This upload is unrelated to FPF: it
@@ -4036,7 +4036,7 @@
   EXPECT_CALL(crowdsourcing_manager(),
               StartUploadRequest(IsPasswordUpload(FormSignatureIs(
                                      CalculateFormSignature(submitted_form))),
-                                 _, _, _, _));
+                                 _, _, _));
 
   form_manager_->Save();
 }
diff --git a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
index 331fd8cb..2355fa2 100644
--- a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
@@ -990,7 +990,7 @@
   auto upload_contents_matcher = IsPasswordUpload(FieldsContain(
       UploadFieldIs(submitted_form.fields[0], FieldType::PASSWORD)));
   EXPECT_CALL(*mock_autofill_crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Check that the password which was chosen by the user is saved.
   PasswordForm saved_form;
@@ -1336,14 +1336,14 @@
   auto upload_contents_matcher = IsPasswordUpload(FieldsContain(UploadFieldIs(
       submitted_form_.fields[kPasswordFieldIndex], FieldType::PASSWORD)));
   EXPECT_CALL(*mock_autofill_crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   // Check that a correction vote is sent for the earlier saved form.
   upload_contents_matcher = IsPasswordUpload(FieldsContain(
       UploadFieldIs(field1, FieldType::USERNAME),
       UploadFieldIs(field3, FieldType::ACCOUNT_CREATION_PASSWORD)));
   EXPECT_CALL(*mock_autofill_crowdsourcing_manager(),
-              StartUploadRequest(upload_contents_matcher, _, _, _, _));
+              StartUploadRequest(upload_contents_matcher, _, _, _));
 
   password_save_manager_impl()->Save(&observed_form_, parsed_submitted_form);
 }
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc
index 3d12b33..9b874080 100644
--- a/components/password_manager/core/browser/votes_uploader.cc
+++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -5,6 +5,7 @@
 #include "components/password_manager/core/browser/votes_uploader.h"
 
 #include <iostream>
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -306,6 +307,29 @@
       });
 }
 
+// Encode password attributes and length into `upload`.
+void EncodePasswordAttributesMetadata(
+    const PasswordAttributesMetadata& password_attributes,
+    AutofillUploadContents& upload) {
+  switch (password_attributes.password_attributes_vote.first) {
+    case autofill::PasswordAttribute::kHasLetter:
+      upload.set_password_has_letter(
+          password_attributes.password_attributes_vote.second);
+      break;
+    case autofill::PasswordAttribute::kHasSpecialSymbol:
+      upload.set_password_has_special_symbol(
+          password_attributes.password_attributes_vote.second);
+      if (password_attributes.password_attributes_vote.second) {
+        upload.set_password_special_symbol(
+            password_attributes.password_symbol_vote);
+      }
+      break;
+    case autofill::PasswordAttribute::kPasswordAttributesCount:
+      NOTREACHED();
+  }
+  upload.set_password_length(password_attributes.password_length_vote);
+}
+
 }  // namespace
 
 SingleUsernameVoteData::SingleUsernameVoteData()
@@ -441,7 +465,9 @@
     return false;
   }
 
-  if (!client_->GetAutofillCrowdsourcingManager()) {
+  AutofillCrowdsourcingManager* crowdsourcing_manager =
+      client_->GetAutofillCrowdsourcingManager();
+  if (!crowdsourcing_manager) {
     return false;
   }
 
@@ -451,6 +477,13 @@
   FormStructure form_structure(form_to_upload.form_data);
   form_structure.set_submission_event(submitted_form.submission_event);
 
+  // Annotate the form with the source language of the page.
+  form_structure.set_current_page_language(client_->GetPageLanguage());
+
+  // Attach the Randomized Encoder.
+  form_structure.set_randomized_encoder(
+      RandomizedEncoder::Create(client_->GetPrefs()));
+
   FieldTypeSet available_field_types;
   // A map from field names to field types.
   FieldTypeMap field_types;
@@ -458,6 +491,8 @@
   // names.
   bool field_name_collision = false;
   auto username_vote_type = AutofillUploadContents::Field::NO_INFORMATION;
+  bool should_set_passwords_were_revealed = false;
+  std::optional<PasswordAttributesMetadata> password_attributes;
   if (autofill_type != autofill::USERNAME) {
     if (has_autofill_vote) {
       bool is_update = autofill_type == autofill::NEW_PASSWORD ||
@@ -481,8 +516,7 @@
         SetFieldType(submitted_form.confirmation_password_element_renderer_id,
                      autofill::CONFIRMATION_PASSWORD, field_types,
                      field_name_collision);
-        form_structure.set_passwords_were_revealed(
-            has_passwords_revealed_vote_);
+        should_set_passwords_were_revealed = true;
       }
       // If a user accepts a save or update prompt, send a single username vote.
       if (autofill_type == autofill::PASSWORD ||
@@ -522,10 +556,10 @@
       // The password attributes should be uploaded only on the first save or an
       // update.
       DCHECK_EQ(form_to_upload.times_used_in_html_form, 0);
-      GeneratePasswordAttributesVote(autofill_type == autofill::PASSWORD
-                                         ? form_to_upload.password_value
-                                         : form_to_upload.new_password_value,
-                                     &form_structure);
+      password_attributes = GeneratePasswordAttributesMetadata(
+          autofill_type == autofill::PASSWORD
+              ? form_to_upload.password_value
+              : form_to_upload.new_password_value);
     }
   } else {  // User overwrites username.
     SetFieldType(form_to_upload.username_element_renderer_id,
@@ -542,13 +576,26 @@
 
   if (password_manager_util::IsLoggingActive(client_)) {
     BrowserSavePasswordProgressLogger logger(client_->GetLogManager());
-    logger.LogFormStructure(Logger::STRING_PASSWORD_FORM_VOTE, form_structure);
+    logger.LogFormStructure(Logger::STRING_PASSWORD_FORM_VOTE, form_structure,
+                            password_attributes);
   }
 
-  // Annotate the form with the source language of the page.
-  form_structure.set_current_page_language(client_->GetPageLanguage());
-  return StartUploadRequest(form_structure, available_field_types,
-                            login_form_signature);
+  std::vector<AutofillUploadContents> upload_contents =
+      form_structure.EncodeUploadRequest(
+          available_field_types, /*form_was_autofilled=*/false,
+          login_form_signature, /*observed_submission=*/true);
+  CHECK(!upload_contents.empty());
+  upload_contents[0].set_passwords_revealed(
+      should_set_passwords_were_revealed && has_passwords_revealed_vote_);
+
+  if (password_attributes) {
+    EncodePasswordAttributesMetadata(*password_attributes, upload_contents[0]);
+  }
+
+  return crowdsourcing_manager->StartUploadRequest(
+      std::move(upload_contents), form_structure.submission_source(),
+      form_structure.active_field_count(), /* prefs=*/nullptr,
+      /*observer=*/nullptr);
 }
 
 // TODO(crbug.com/840384): Share common code with UploadPasswordVote.
@@ -596,7 +643,8 @@
 
   if (password_manager_util::IsLoggingActive(client_)) {
     BrowserSavePasswordProgressLogger logger(client_->GetLogManager());
-    logger.LogFormStructure(Logger::STRING_FIRSTUSE_FORM_VOTE, form_structure);
+    logger.LogFormStructure(Logger::STRING_FIRSTUSE_FORM_VOTE, form_structure,
+                            std::nullopt);
   }
 
   StartUploadRequest(form_structure, available_field_types);
@@ -821,13 +869,13 @@
   return false;
 }
 
-void VotesUploader::GeneratePasswordAttributesVote(
-    const std::u16string& password_value,
-    FormStructure* form_structure) {
+std::optional<PasswordAttributesMetadata>
+VotesUploader::GeneratePasswordAttributesMetadata(
+    const std::u16string& password_value) {
   if (password_value.empty()) {
-    NOTREACHED() << "GeneratePasswordAttributesVote cannot take an empty "
-                    "password value.";
-    return;
+    NOTREACHED_NORETURN()
+        << "GeneratePasswordAttributesMetadata cannot take an empty "
+           "password value.";
   }
 
   // Don't crowdsource password attributes for non-ascii passwords.
@@ -835,7 +883,7 @@
     if (!(password_manager_util::IsLetter(e) ||
           password_manager_util::IsNumeric(e) ||
           password_manager_util::IsSpecialSymbol(e))) {
-      return;
+      return std::nullopt;
     }
   }
 
@@ -858,23 +906,24 @@
   bool randomized_value_for_character_class =
       respond_randomly ? base::RandGenerator(2)
                        : base::ranges::any_of(password_value, predicate);
-  form_structure->set_password_attributes_vote(std::make_pair(
-      character_class_attribute, randomized_value_for_character_class));
+  PasswordAttributesMetadata password_attributes;
+  password_attributes.password_attributes_vote = std::make_pair(
+      character_class_attribute, randomized_value_for_character_class);
 
   if (character_class_attribute ==
           autofill::PasswordAttribute::kHasSpecialSymbol &&
       randomized_value_for_character_class) {
-    form_structure->set_password_symbol_vote(
+    password_attributes.password_symbol_vote =
         respond_randomly ? GetRandomSpecialSymbol()
-                         : GetRandomSpecialSymbolFromPassword(password_value));
+                         : GetRandomSpecialSymbolFromPassword(password_value);
   }
 
   size_t actual_length = password_value.size();
-  size_t randomized_length = actual_length <= 1 || base::RandGenerator(5) == 0
-                                 ? actual_length
-                                 : base::RandGenerator(actual_length - 1) + 1;
-
-  form_structure->set_password_length_vote(randomized_length);
+  password_attributes.password_length_vote =
+      actual_length <= 1 || base::RandGenerator(5) == 0
+          ? actual_length
+          : base::RandGenerator(actual_length - 1) + 1;
+  return password_attributes;
 }
 
 void VotesUploader::StoreInitialFieldValues(
@@ -904,8 +953,7 @@
           available_field_types, /*form_was_autofilled=*/false,
           login_form_signature, /*observed_submission=*/true),
       form_to_upload.submission_source(), form_to_upload.active_field_count(),
-      /*pref_service=*/nullptr,
-      /*observer=*/nullptr);
+      /*pref_service=*/nullptr);
 }
 
 bool VotesUploader::SetSingleUsernameVoteOnUsernameForm(
@@ -1081,7 +1129,7 @@
     if (password_manager_util::IsLoggingActive(client_)) {
       BrowserSavePasswordProgressLogger logger(client_->GetLogManager());
       logger.LogFormStructure(Logger::STRING_USERNAME_FIRST_FLOW_VOTE,
-                              *form_to_upload);
+                              *form_to_upload, std::nullopt);
     }
 
     if (StartUploadRequest(*form_to_upload, available_field_types)) {
diff --git a/components/password_manager/core/browser/votes_uploader.h b/components/password_manager/core/browser/votes_uploader.h
index 5b84432..8fe2545 100644
--- a/components/password_manager/core/browser/votes_uploader.h
+++ b/components/password_manager/core/browser/votes_uploader.h
@@ -14,6 +14,7 @@
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/proto/server.pb.h"
 #include "components/autofill/core/common/signatures.h"
 #include "components/autofill/core/common/unique_ids.h"
@@ -83,6 +84,21 @@
   bool is_form_overrule;
 };
 
+struct PasswordAttributesMetadata {
+  // The vote about password attributes (e.g. whether the password has a
+  // numeric character).
+  std::pair<autofill::PasswordAttribute, bool> password_attributes_vote;
+
+  // If `password_attribute_vote` contains (kHasSpecialSymbol, true), this
+  // field contains noisified information about a special symbol in a
+  // user-created password stored as ASCII code. The default value of 0
+  // indicates that no symbol was set.
+  int password_symbol_vote = 0;
+
+  // Noisified password length for crowdsourcing.
+  int password_length_vote = 0;
+};
+
 // This class manages vote uploads for password forms.
 class VotesUploader {
  public:
@@ -161,10 +177,10 @@
       const std::u16string& username,
       const std::u16string& password);
 
-  // Generates a password attributes vote based on |password_value| and saves it
-  // to |form_structure|. Declared as public for testing.
-  void GeneratePasswordAttributesVote(const std::u16string& password_value,
-                                      autofill::FormStructure* form_structure);
+  // Returns a password attributes vote based on `password_value` . Declared as
+  // public for testing.
+  std::optional<PasswordAttributesMetadata> GeneratePasswordAttributesMetadata(
+      const std::u16string& password_value);
 
   // Stores the |unique_renderer_id| and |values| of the fields in
   // |observed_form| to |initial_field_values_|.
@@ -222,6 +238,7 @@
     username_change_state_ = username_change_state;
   }
 
+  bool passwords_revealed_vote() const { return has_passwords_revealed_vote_; }
   void set_has_passwords_revealed_vote(bool has_passwords_revealed_vote) {
     has_passwords_revealed_vote_ = has_passwords_revealed_vote;
   }
@@ -371,10 +388,10 @@
   UsernameChangeState username_change_state_ = UsernameChangeState::kUnchanged;
 
   // If the user typed username that doesn't match any saved credentials, but
-  // matches an entry from |all_alternative_usernames| of a saved credential,
-  // |username_correction_vote_| stores the credential with matched username.
-  // The matched credential is copied to |username_correction_vote_|, but
-  // |username_correction_vote_.username_element| is set to the name of the
+  // matches an entry from `all_alternative_usernames` of a saved credential,
+  // `username_correction_vote_` stores the credential with matched username.
+  // The matched credential is copied to `username_correction_vote_`, but
+  // `username_correction_vote_.username_element` is set to the name of the
   // field where the matched username was found.
   std::optional<PasswordForm> username_correction_vote_;
 
diff --git a/components/password_manager/core/browser/votes_uploader_unittest.cc b/components/password_manager/core/browser/votes_uploader_unittest.cc
index f46631c..3bca2724 100644
--- a/components/password_manager/core/browser/votes_uploader_unittest.cc
+++ b/components/password_manager/core/browser/votes_uploader_unittest.cc
@@ -52,7 +52,9 @@
 using ::autofill::upload_contents_matchers::FieldsContain;
 using ::autofill::upload_contents_matchers::FieldSignatureIs;
 using ::autofill::upload_contents_matchers::FormSignatureIs;
+using ::autofill::upload_contents_matchers::HasPasswordAttribute;
 using ::autofill::upload_contents_matchers::ObservedSubmissionIs;
+using ::autofill::upload_contents_matchers::PasswordLengthIsPositive;
 using ::autofill::upload_contents_matchers::SubmissionIndicatorEventIs;
 using ::testing::_;
 using ::testing::AllOf;
@@ -183,6 +185,7 @@
 
   auto upload_contents_matcher = IsPasswordUpload(
       FormSignatureIs(CalculateFormSignature(form_to_upload_.form_data)),
+      PasswordLengthIsPositive(), HasPasswordAttribute(),
       SubmissionIndicatorEventIs(
           SubmissionIndicatorEvent::HTML_FORM_SUBMISSION),
       LoginFormSignatureIs(login_form_signature_),
@@ -190,8 +193,7 @@
                     UploadField(11, FieldType::CONFIRMATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::NEW_PASSWORD,
       login_form_signature_));
@@ -210,6 +212,7 @@
 
   auto upload_contents_matcher = IsPasswordUpload(
       FormSignatureIs(CalculateFormSignature(form_to_upload_.form_data)),
+      PasswordLengthIsPositive(), HasPasswordAttribute(),
       SubmissionIndicatorEventIs(
           SubmissionIndicatorEvent::HTML_FORM_SUBMISSION),
       LoginFormSignatureIs(login_form_signature_),
@@ -217,8 +220,7 @@
                     UploadField(12, FieldType::CONFIRMATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::PASSWORD,
       login_form_signature_));
@@ -241,8 +243,7 @@
                     UploadField(5, FieldType::ACCOUNT_CREATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::USERNAME,
       login_form_signature_));
@@ -282,8 +283,7 @@
       6, FieldType::USERNAME, FieldVoteTypeIs(Field::USERNAME_OVERWRITTEN))));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()))
+                                 /*pref_service=*/IsNull()))
       .After(first_call);
   votes_uploader.SendVotesOnSave(form_to_upload_.form_data, submitted_form_,
                                  matches, &form_to_upload_);
@@ -307,8 +307,7 @@
                     UploadField(5, FieldType::ACCOUNT_CREATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::ACCOUNT_CREATION_PASSWORD,
       login_form_signature_));
@@ -335,8 +334,7 @@
       6, FieldType::USERNAME, FieldVoteTypeIs(Field::CREDENTIALS_REUSED))));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.SendVoteOnCredentialsReuse(form_to_upload_.form_data,
                                             submitted_form_, &pending);
 }
@@ -362,8 +360,7 @@
                     UploadField(5, FieldType::PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::PASSWORD,
       login_form_signature_));
@@ -394,8 +391,7 @@
                     UploadField(5, FieldType::PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.SendVotesOnSave(form_to_upload_.form_data, submitted_form_, {},
                                  &form_to_upload_);
 }
@@ -474,8 +470,7 @@
                                    : Not(HasPasswordLength()));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
     EXPECT_TRUE(votes_uploader.UploadPasswordVote(
         form_to_upload_, submitted_form_, autofill_type,
         login_form_signature_));
@@ -484,8 +479,7 @@
   }
 }
 
-TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote) {
-  VotesUploader votes_uploader(&client_, true);
+TEST_F(VotesUploaderTest, GeneratePasswordAttributesMetadata) {
   // Checks that randomization distorts information about present and missed
   // character classes, but a true value is still restorable with aggregation
   // of many distorted reports.
@@ -501,8 +495,6 @@
     if (password_value.empty())
       continue;
 
-    FormData form;
-    FormStructure form_structure(form);
     int reported_false[kNumberOfPasswordAttributes] = {0, 0};
     int reported_true[kNumberOfPasswordAttributes] = {0, 0};
 
@@ -512,16 +504,18 @@
     int kNumberOfRuns = 1000;
 
     for (int i = 0; i < kNumberOfRuns; ++i) {
-      votes_uploader.GeneratePasswordAttributesVote(password_value,
-                                                    &form_structure);
-      std::optional<std::pair<PasswordAttribute, bool>> vote =
-          form_structure.get_password_attributes_vote();
-      int attribute_index = static_cast<int>(vote->first);
-      if (vote->second)
+      VotesUploader votes_uploader(&client_, true);
+      std::optional<PasswordAttributesMetadata> password_attributes =
+          votes_uploader.GeneratePasswordAttributesMetadata(password_value);
+      std::pair<PasswordAttribute, bool> vote =
+          password_attributes->password_attributes_vote;
+      int attribute_index = static_cast<int>(vote.first);
+      if (vote.second) {
         reported_true[attribute_index]++;
-      else
+      } else {
         reported_false[attribute_index]++;
-      size_t reported_length = form_structure.get_password_length_vote();
+      }
+      size_t reported_length = password_attributes->password_length_vote;
       if (reported_length == password_value.size()) {
         reported_actual_length++;
       } else {
@@ -553,38 +547,34 @@
 }
 
 TEST_F(VotesUploaderTest, GeneratePasswordSpecialSymbolVote) {
-  VotesUploader votes_uploader(&client_, true);
 
   const std::u16string password_value = u"password-withsymbols!";
   const int kNumberOfRuns = 2000;
   const int kSpecialSymbolsAttribute =
       static_cast<int>(PasswordAttribute::kHasSpecialSymbol);
 
-  FormData form;
-
   int correct_symbol_reported = 0;
   int wrong_symbol_reported = 0;
   int number_of_symbol_votes = 0;
 
   for (int i = 0; i < kNumberOfRuns; ++i) {
-    FormStructure form_structure(form);
-
-    votes_uploader.GeneratePasswordAttributesVote(password_value,
-                                                  &form_structure);
-    std::optional<std::pair<PasswordAttribute, bool>> vote =
-        form_structure.get_password_attributes_vote();
+    VotesUploader votes_uploader(&client_, true);
+    std::optional<PasswordAttributesMetadata> password_attributes =
+        votes_uploader.GeneratePasswordAttributesMetadata(password_value);
+    std::pair<PasswordAttribute, bool> vote =
+        password_attributes->password_attributes_vote;
 
     // Continue if the vote is not about special symbols or implies that no
     // special symbols are used.
-    if (static_cast<int>(vote->first) != kSpecialSymbolsAttribute ||
-        !vote->second) {
-      EXPECT_EQ(form_structure.get_password_symbol_vote(), 0);
+    if (static_cast<int>(vote.first) != kSpecialSymbolsAttribute ||
+        !vote.second) {
+      EXPECT_EQ(password_attributes->password_symbol_vote, 0);
       continue;
     }
 
     number_of_symbol_votes += 1;
 
-    int symbol = form_structure.get_password_symbol_vote();
+    int symbol = password_attributes->password_symbol_vote;
     if (symbol == '-' || symbol == '!')
       correct_symbol_reported += 1;
     else
@@ -594,48 +584,40 @@
   EXPECT_LT(0.15 * number_of_symbol_votes, wrong_symbol_reported);
 }
 
-TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_OneCharacterPassword) {
-  // |VotesUploader::GeneratePasswordAttributesVote| shouldn't crash if a
+TEST_F(VotesUploaderTest,
+       GeneratePasswordAttributesMetadata_OneCharacterPassword) {
+  // `VotesUploader::GeneratePasswordAttributesMetadata` shouldn't crash if a
   // password has only one character.
-  FormData form;
-  FormStructure form_structure(form);
   VotesUploader votes_uploader(&client_, true);
-  votes_uploader.GeneratePasswordAttributesVote(u"1", &form_structure);
-  std::optional<std::pair<PasswordAttribute, bool>> vote =
-      form_structure.get_password_attributes_vote();
-  EXPECT_TRUE(vote.has_value());
-  size_t reported_length = form_structure.get_password_length_vote();
+  std::optional<PasswordAttributesMetadata> password_attributes =
+      votes_uploader.GeneratePasswordAttributesMetadata(u"1");
+  EXPECT_TRUE(password_attributes.has_value());
+
+  size_t reported_length = password_attributes->password_length_vote;
   EXPECT_EQ(1u, reported_length);
 }
 
-TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_AllAsciiCharacters) {
-  FormData form;
-  FormStructure form_structure(form);
+TEST_F(VotesUploaderTest,
+       GeneratePasswordAttributesMetadata_AllAsciiCharacters) {
   VotesUploader votes_uploader(&client_, true);
-  votes_uploader.GeneratePasswordAttributesVote(
-      u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr"
-      u"stuvwxyz!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
-      &form_structure);
-  std::optional<std::pair<PasswordAttribute, bool>> vote =
-      form_structure.get_password_attributes_vote();
-  EXPECT_TRUE(vote.has_value());
+  std::optional<PasswordAttributesMetadata> password_attributes =
+      votes_uploader.GeneratePasswordAttributesMetadata(
+          u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr"
+          u"stuvwxyz!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
+  EXPECT_TRUE(password_attributes.has_value());
 }
 
-TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_NonAsciiPassword) {
+TEST_F(VotesUploaderTest, GeneratePasswordAttributesMetadata_NonAsciiPassword) {
   // Checks that password attributes vote is not generated if the password has
   // non-ascii characters.
   for (const auto* password :
        {u"пароль1", u"パスワード", u"münchen", u"סיסמה-A", u"Σ-12345",
         u"գաղտնաբառըTTT", u"Slaptažodis", u"密碼", u"كلمهالسر", u"mậtkhẩu!",
         u"ລະຫັດຜ່ານ-l", u"စကားဝှက်ကို3", u"პაროლი", u"पारण शब्द"}) {
-    FormData form;
-    FormStructure form_structure(form);
     VotesUploader votes_uploader(&client_, true);
-    votes_uploader.GeneratePasswordAttributesVote(password, &form_structure);
-    std::optional<std::pair<PasswordAttribute, bool>> vote =
-        form_structure.get_password_attributes_vote();
-
-    EXPECT_FALSE(vote.has_value()) << password;
+    std::optional<PasswordAttributesMetadata> password_attributes =
+        votes_uploader.GeneratePasswordAttributesMetadata(password);
+    EXPECT_FALSE(password_attributes.has_value()) << password;
   }
 }
 
@@ -690,8 +672,7 @@
                              FieldType::SINGLE_USERNAME, Field::WEAK)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -732,8 +713,7 @@
                              FieldType::NOT_USERNAME, Field::STRONG)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -754,8 +734,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     FieldType::PASSWORD, std::string());
 }
@@ -787,8 +766,7 @@
                              FieldType::SINGLE_USERNAME, Field::WEAK)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -807,8 +785,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -841,8 +818,7 @@
                              FieldType::NOT_USERNAME, Field::WEAK)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -860,8 +836,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -895,8 +870,7 @@
                              FieldType::SINGLE_USERNAME, Field::STRONG)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -914,8 +888,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -947,8 +920,7 @@
                              FieldType::NOT_USERNAME, Field::STRONG)));
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
                 StartUploadRequest(upload_contents_matcher, _, _,
-                                   /*pref_service=*/IsNull(),
-                                   /*observer=*/IsNull()));
+                                   /*pref_service=*/IsNull()));
   } else {
     EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest)
         .Times(0);
@@ -966,8 +938,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -997,7 +968,7 @@
       mock_autofill_crowdsourcing_manager_,
       StartUploadRequest(
           IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _,
-          _, _))
+          _))
       .Times(0);
   votes_uploader.MaybeSendSingleUsernameVotes();
 
@@ -1012,8 +983,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -1047,8 +1017,7 @@
           EqualsSingleUsernameDataVector({expected_single_username_data})));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_,
                                     autofill::PASSWORD, std::string());
 }
@@ -1076,8 +1045,7 @@
                     UploadField(11, FieldType::CONFIRMATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   base::HistogramTester histogram_tester;
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::PASSWORD,
@@ -1105,8 +1073,7 @@
                     UploadField(12, FieldType::CONFIRMATION_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
   base::HistogramTester histogram_tester;
   EXPECT_TRUE(votes_uploader.UploadPasswordVote(
       form_to_upload_, submitted_form_, FieldType::PASSWORD,
@@ -1136,8 +1103,7 @@
                            Field::WEAK_FORGOT_PASSWORD)));
   EXPECT_CALL(mock_autofill_crowdsourcing_manager_,
               StartUploadRequest(upload_contents_matcher, _, _,
-                                 /*pref_service=*/IsNull(),
-                                 /*observer=*/IsNull()));
+                                 /*pref_service=*/IsNull()));
 
   base::HistogramTester histogram_tester;
   votes_uploader.MaybeSendSingleUsernameVotes();
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
index 0752d42..bbc5f68a 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
@@ -201,18 +201,13 @@
         }
     }
 
-    /**
-     * Records that the Payment Request was not shown to the user and for what reason.
-     *
-     * @param reason An int indicating why the payment request was not shown.
-     */
-    public void setNotShown(int reason) {
-        assert reason < NotShownReason.MAX;
+    /** Records that the Payment Request was not shown to the user. */
+    public void setNotShown() {
         assert !mHasRecorded;
 
         if (!mHasRecorded) {
             mHasRecorded = true;
-            JourneyLoggerJni.get().setNotShown(mJourneyLoggerAndroid, JourneyLogger.this, reason);
+            JourneyLoggerJni.get().setNotShown(mJourneyLoggerAndroid, JourneyLogger.this);
         }
     }
 
@@ -292,7 +287,7 @@
 
         void setAborted(long nativeJourneyLoggerAndroid, JourneyLogger caller, int reason);
 
-        void setNotShown(long nativeJourneyLoggerAndroid, JourneyLogger caller, int reason);
+        void setNotShown(long nativeJourneyLoggerAndroid, JourneyLogger caller);
 
         void setNoMatchingCredentialsShown(long nativeJourneyLoggerAndroid, JourneyLogger caller);
 
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java
index e798e7b3..84970eeca 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java
@@ -8,32 +8,23 @@
 
 /** The error of payment UIs not being shown. */
 public class PaymentNotShownError {
-    private final int mNotShownReason;
     private final String mErrorMessage;
     private final int mReason;
 
     /**
      * Creates an instance with the error details.
-     * @param notShownReason The reason of not showing UI, defined in {@link NotShownReason}.
+     *
      * @param errorMessage The error message for informing the web developer.
      * @param paymentErrorReason The reason of the payment error, defined in {@link
-     *         PaymentErrorReason}.
+     *     PaymentErrorReason}.
      */
-    /* package */ PaymentNotShownError(
-            int notShownReason, String errorMessage, int paymentErrorReason) {
-        assert notShownReason <= NotShownReason.MAX;
+    /* package */ PaymentNotShownError(String errorMessage, int paymentErrorReason) {
         assert paymentErrorReason >= PaymentErrorReason.MIN_VALUE;
         assert paymentErrorReason <= PaymentErrorReason.MAX_VALUE;
-        mNotShownReason = notShownReason;
         mErrorMessage = errorMessage;
         mReason = paymentErrorReason;
     }
 
-    /** @return The reason of not showing UI, defined in {@link NotShownReason}. */
-    public int getNotShownReason() {
-        return mNotShownReason;
-    }
-
     /** @return The error message for informing the web developer. */
     public String getErrorMessage() {
         return mErrorMessage;
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
index 3d66d40..73162b5 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
@@ -976,15 +976,13 @@
                 mBrowserPaymentRequest.showOrSkipAppSelector(
                         mIsShowWaitingForUpdatedDetails, mSpec.getRawTotal(), shouldSkip);
         if (showError != null) {
-            return new PaymentNotShownError(
-                    NotShownReason.OTHER, showError, PaymentErrorReason.NOT_SUPPORTED);
+            return new PaymentNotShownError(showError, PaymentErrorReason.NOT_SUPPORTED);
         }
 
         if (mIsShowWaitingForUpdatedDetails) return null;
         String error = onShowCalledAndAppsQueriedAndDetailsFinalized();
         if (error != null) {
-            return new PaymentNotShownError(
-                    NotShownReason.OTHER, error, PaymentErrorReason.NOT_SUPPORTED);
+            return new PaymentNotShownError(error, PaymentErrorReason.NOT_SUPPORTED);
         }
 
         return null;
@@ -1079,18 +1077,16 @@
     }
 
     private void onShowFailed(String error) {
-        onShowFailed(NotShownReason.OTHER, error, PaymentErrorReason.USER_CANCEL);
+        onShowFailed(error, PaymentErrorReason.USER_CANCEL);
     }
 
     private void onShowFailed(PaymentNotShownError error) {
-        onShowFailed(
-                error.getNotShownReason(), error.getErrorMessage(), error.getPaymentErrorReason());
+        onShowFailed(error.getErrorMessage(), error.getPaymentErrorReason());
     }
 
-    // notShowReason is defined in NotShownReason.
     // paymentErrorReason is defined in PaymentErrorReason.
-    private void onShowFailed(int notShowReason, String error, int paymentErrorReason) {
-        mJourneyLogger.setNotShown(notShowReason);
+    private void onShowFailed(String error, int paymentErrorReason) {
+        mJourneyLogger.setNotShown();
         disconnectFromClientWithDebugMessage(error, paymentErrorReason);
         if (sObserverForTest != null) sObserverForTest.onPaymentRequestServiceShowFailed();
     }
@@ -1107,10 +1103,6 @@
             // All factories have responded, but none of them have apps. It's possible to add credit
             // cards, but the merchant does not support them either. The payment request must be
             // rejected.
-            int notShowReason =
-                    mCanMakePayment
-                            ? NotShownReason.NO_MATCHING_PAYMENT_METHOD
-                            : NotShownReason.NO_SUPPORTED_PAYMENT_METHOD;
             String debugMessage;
             int paymentErrorReason;
             if (mDelegate.isOffTheRecord()) {
@@ -1135,7 +1127,7 @@
                                         : " " + mRejectShowErrorMessage);
                 paymentErrorReason = PaymentErrorReason.NOT_SUPPORTED;
             }
-            return new PaymentNotShownError(notShowReason, debugMessage, paymentErrorReason);
+            return new PaymentNotShownError(debugMessage, paymentErrorReason);
         }
         return null;
     }
@@ -1321,7 +1313,6 @@
             // one. Only the first one will be shown. This also prevents multiple tabs and windows
             // from showing PaymentRequest UI at the same time.
             onShowFailed(
-                    NotShownReason.CONCURRENT_REQUESTS,
                     ErrorStrings.ANOTHER_UI_SHOWING,
                     PaymentErrorReason.ALREADY_SHOWING);
             return;
@@ -1334,7 +1325,6 @@
                 // page.
                 mRejectShowForUserActivation = true;
                 onShowFailed(
-                        NotShownReason.OTHER,
                         ErrorStrings.CANNOT_SHOW_WITHOUT_USER_ACTIVATION,
                         PaymentErrorReason.USER_ACTIVATION_REQUIRED);
                 return;
diff --git a/components/payments/content/android/journey_logger_android.cc b/components/payments/content/android/journey_logger_android.cc
index 025ff6c..ced68d6 100644
--- a/components/payments/content/android/journey_logger_android.cc
+++ b/components/payments/content/android/journey_logger_android.cc
@@ -160,12 +160,8 @@
 
 void JourneyLoggerAndroid::SetNotShown(
     JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& jcaller,
-    jint jreason) {
-  DCHECK_GE(jreason, 0);
-  DCHECK_LT(jreason, JourneyLogger::NotShownReason::NOT_SHOWN_REASON_MAX);
-  journey_logger_.SetNotShown(
-      static_cast<JourneyLogger::NotShownReason>(jreason));
+    const base::android::JavaParamRef<jobject>& jcaller) {
+  journey_logger_.SetNotShown();
 }
 
 void JourneyLoggerAndroid::SetNoMatchingCredentialsShown(
diff --git a/components/payments/content/android/journey_logger_android.h b/components/payments/content/android/journey_logger_android.h
index bba1afa..850a492 100644
--- a/components/payments/content/android/journey_logger_android.h
+++ b/components/payments/content/android/journey_logger_android.h
@@ -76,8 +76,7 @@
                   const base::android::JavaParamRef<jobject>& jcaller,
                   jint jreason);
   void SetNotShown(JNIEnv* env,
-                   const base::android::JavaParamRef<jobject>& jcaller,
-                   jint jreason);
+                   const base::android::JavaParamRef<jobject>& jcaller);
   void SetNoMatchingCredentialsShown(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& jcaller);
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc
index f21b47d7..7221e48b 100644
--- a/components/payments/content/payment_request.cc
+++ b/components/payments/content/payment_request.cc
@@ -294,8 +294,7 @@
     log_.Error(errors::kAnotherUiShowing);
     DCHECK(!has_recorded_completion_);
     has_recorded_completion_ = true;
-    journey_logger_.SetNotShown(
-        JourneyLogger::NOT_SHOWN_REASON_CONCURRENT_REQUESTS);
+    journey_logger_.SetNotShown();
     client_->OnError(mojom::PaymentErrorReason::ALREADY_SHOWING,
                      errors::kAnotherUiShowing);
     ResetAndDeleteThis();
@@ -310,7 +309,7 @@
       log_.Error(errors::kCannotShowWithoutUserActivation);
       DCHECK(!has_recorded_completion_);
       has_recorded_completion_ = true;
-      journey_logger_.SetNotShown(JourneyLogger::NOT_SHOWN_REASON_OTHER);
+      journey_logger_.SetNotShown();
       client_->OnError(mojom::PaymentErrorReason::USER_ACTIVATION_REQUIRED,
                        errors::kCannotShowWithoutUserActivation);
       ResetAndDeleteThis();
@@ -325,7 +324,7 @@
     log_.Error(errors::kCannotShowInBackgroundTab);
     DCHECK(!has_recorded_completion_);
     has_recorded_completion_ = true;
-    journey_logger_.SetNotShown(JourneyLogger::NOT_SHOWN_REASON_OTHER);
+    journey_logger_.SetNotShown();
     client_->OnError(mojom::PaymentErrorReason::USER_CANCEL,
                      errors::kCannotShowInBackgroundTab);
     ResetAndDeleteThis();
@@ -684,8 +683,7 @@
             << "): requested method not supported.";
     DCHECK(!has_recorded_completion_);
     has_recorded_completion_ = true;
-    journey_logger_.SetNotShown(
-        JourneyLogger::NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD);
+    journey_logger_.SetNotShown();
     client_->OnError(mojom::PaymentErrorReason::NOT_SUPPORTED,
                      GetNotSupportedErrorMessage(
                          spec_ ? spec_->payment_method_identifiers_set()
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc
index 8acf469..113ea9a 100644
--- a/components/payments/core/journey_logger.cc
+++ b/components/payments/core/journey_logger.cc
@@ -290,7 +290,7 @@
     RecordJourneyStatsHistograms(COMPLETION_STATUS_OTHER_ABORTED);
 }
 
-void JourneyLogger::SetNotShown(NotShownReason reason) {
+void JourneyLogger::SetNotShown() {
   DCHECK(!WasPaymentRequestTriggered());
   RecordJourneyStatsHistograms(COMPLETION_STATUS_COULD_NOT_SHOW);
 }
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h
index b89652c1..6055b46 100644
--- a/components/payments/core/journey_logger.h
+++ b/components/payments/core/journey_logger.h
@@ -208,17 +208,6 @@
     ABORT_REASON_MAX,
   };
 
-  // The reason why the Payment Request was not shown to the user.
-  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.payments
-  // GENERATED_JAVA_CLASS_NAME_OVERRIDE: NotShownReason
-  enum NotShownReason {
-    NOT_SHOWN_REASON_NO_MATCHING_PAYMENT_METHOD = 0,
-    NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD = 1,
-    NOT_SHOWN_REASON_CONCURRENT_REQUESTS = 2,
-    NOT_SHOWN_REASON_OTHER = 3,
-    NOT_SHOWN_REASON_MAX = 4,
-  };
-
   // The categories of the payment methods.
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.payments
   // GENERATED_JAVA_CLASS_NAME_OVERRIDE: PaymentMethodCategory
@@ -324,9 +313,8 @@
   // starting the logging of all the journey metrics.
   void SetAborted(AbortReason reason);
 
-  // Records that the Payment Request was not shown to the user, along with the
-  // reason.
-  void SetNotShown(NotShownReason reason);
+  // Records that the Payment Request was not shown to the user.
+  void SetNotShown();
 
   // Records that the SPC No Matching Credentials UX was shown to the user.
   void SetNoMatchingCredentialsShown();
diff --git a/components/permissions_strings.grdp b/components/permissions_strings.grdp
index 54778c8..6a69b78 100644
--- a/components/permissions_strings.grdp
+++ b/components/permissions_strings.grdp
@@ -343,7 +343,7 @@
   </if>
   <if expr="is_chromeos">
     <message name="IDS_SMART_CARD_PERMISSION_PROMPT" desc="Text on dialog that asks the user for permission to access a smart card reader device and the card inserted in it (or presented to it, if contactless).">
-      Control <ph name="ReaderName">$1<ex>HID Omnikey</ex></ph> and gain access to the smart card accessible to it?
+      Control <ph name="ReaderName">$1<ex>HID Omnikey</ex></ph> and gain access to the smart card accessible to it.
     </message>
     <message name="IDS_SMART_CARD_PERMISSION_ALWAYS_ALLOW" desc="Label on button to always allow access to this smart card reader and any card inserted in (or presented to) it.">
       Always allow, with any card
diff --git a/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1 b/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1
index b504d85e..1456bb26 100644
--- a/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1
+++ b/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1
@@ -1 +1 @@
-867df8149907fdd937ec80f6c78f9becec1071c5
\ No newline at end of file
+c7a637c5aea552ca968ce1e2feacc875119585dd
\ No newline at end of file
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.cc b/components/privacy_sandbox/tracking_protection_onboarding.cc
index ac06659..ccf8c83 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding.cc
+++ b/components/privacy_sandbox/tracking_protection_onboarding.cc
@@ -310,7 +310,8 @@
                            static_cast<int>(ToInternalAckAction(action)));
 }
 
-void MaybeSetStartAndEndSurveyTime(PrefService* pref_service) {
+void MaybeSetStartAndEndSurveyTime(PrefService* pref_service,
+                                   bool is_silent_onboarding_enabled) {
   if (pref_service->HasPrefPath(
           prefs::kTrackingProtectionSentimentSurveyStartTime)) {
     return;
@@ -319,15 +320,30 @@
   auto group = GetSurveyGroup(pref_service);
   // Setting the start and end time when applicable.
   // First, start by determining the anchor time. Control should be the first
-  // time this function runs. Treatment should be when the notice was acked.
-  // If the anchor time isn't year ready, return early.
+  // time this function runs (unless silent onbaording is enabled, in which
+  // case, we'd wait for the profile to get silentl Onboarded). Treatment should
+  // be when the notice was acked. If the anchor time isn't year ready, return
+  // early.
   base::Time anchor_time;
   switch (group) {
     case SentimentSurveyGroup::kNotSet:
       return;
     case SentimentSurveyGroup::kControlImmediate:
     case SentimentSurveyGroup::kControlDelayed:
-      anchor_time = base::Time::Now();
+      // If Silent Onboarding is enabled, we use the Onboarding time to
+      // determine when the survey anchor time (Used to calculate the survey
+      // start and end time). If it is not enabled, we use "Now" as the anchor
+      // time.
+      if (is_silent_onboarding_enabled) {
+        if (!pref_service->HasPrefPath(
+                prefs::kTrackingProtectionSilentOnboardedSince)) {
+          return;
+        }
+        anchor_time = pref_service->GetTime(
+            prefs::kTrackingProtectionSilentOnboardedSince);
+      } else {
+        anchor_time = base::Time::Now();
+      }
       break;
     case SentimentSurveyGroup::kTreatmentImmediate:
     case SentimentSurveyGroup::kTreatmentDelayed:
@@ -399,8 +415,11 @@
 
 TrackingProtectionOnboarding::TrackingProtectionOnboarding(
     PrefService* pref_service,
-    version_info::Channel channel)
-    : pref_service_(pref_service), channel_(channel) {
+    version_info::Channel channel,
+    bool is_silent_onboarding_enabled)
+    : pref_service_(pref_service),
+      channel_(channel),
+      is_silent_onboarding_enabled_(is_silent_onboarding_enabled) {
   CHECK(pref_service_);
 
   pref_change_registrar_.Init(pref_service_);
@@ -451,7 +470,7 @@
 
 void TrackingProtectionOnboarding::OnOnboardingAckedChanged() const {
   // Maybe set the Hats start and end time now that the profile is onboarded.
-  MaybeSetStartAndEndSurveyTime(pref_service_);
+  MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_);
   for (auto& observer : observers_) {
     observer.OnShouldShowNoticeUpdated();
   }
@@ -569,7 +588,7 @@
   pref_service_->SetInteger(prefs::kTrackingProtectionSentimentSurveyGroup,
                             static_cast<int>(internal_group));
 
-  MaybeSetStartAndEndSurveyTime(pref_service_);
+  MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_);
 }
 
 TrackingProtectionOnboarding::SentimentSurveyGroup
@@ -683,6 +702,8 @@
       static_cast<int>(
           TrackingProtectionOnboarding::OnboardingStatus::kOnboarded));
   RecordSilentOnboardingDidNoticeShownOnboard(true);
+
+  MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_);
 }
 
 void TrackingProtectionOnboarding::NoticeShown(NoticeType notice_type) {
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.h b/components/privacy_sandbox/tracking_protection_onboarding.h
index db1d3501..3b5f77d 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding.h
+++ b/components/privacy_sandbox/tracking_protection_onboarding.h
@@ -145,7 +145,8 @@
   };
 
   TrackingProtectionOnboarding(PrefService* pref_service,
-                               version_info::Channel channel);
+                               version_info::Channel channel,
+                               bool is_silent_onboarding_enabled = false);
   ~TrackingProtectionOnboarding() override;
 
   virtual void AddObserver(Observer* observer);
@@ -242,6 +243,7 @@
   raw_ptr<PrefService> pref_service_;
   PrefChangeRegistrar pref_change_registrar_;
   version_info::Channel channel_;
+  bool is_silent_onboarding_enabled_;
 };
 
 }  // namespace privacy_sandbox
diff --git a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
index 22c3474c..a6fe1680 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
+++ b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
@@ -713,6 +713,109 @@
       1);
 }
 
+class TrackingProtectionSentimentTrackinWithSilentOnboarding
+    : public TrackingProtectionSentimentTracking {
+ public:
+  void SetUp() override {
+    tracking_protection_onboarding_service_ =
+        std::make_unique<TrackingProtectionOnboarding>(
+            prefs(), version_info::Channel::UNKNOWN,
+            /* is_silent_onboarding_enabled=*/true);
+  }
+};
+
+TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding,
+       RegistersControlBeforeOnboarding) {
+  // Setup
+  tracking_protection_onboarding()->MaybeMarkSilentEligible();
+
+  // Action: Register the group.
+  tracking_protection_onboarding()->RegisterSentimentSurveyGroup(
+      SentimentSurveyGroup::kControlImmediate);
+
+  // Verification: Registration no longer required.
+  EXPECT_FALSE(
+      tracking_protection_onboarding()->RequiresSentimentSurveyGroup());
+
+  // Registered group not yet returned
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kNotSet);
+
+  // Registered group Still not returned even after the survey start time, and
+  // before the survey end time.
+  task_env_.FastForwardBy(base::Minutes(3));
+
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kNotSet);
+}
+
+TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding,
+       RegistersControlAfterSilentOnboarding) {
+  // Setup
+  tracking_protection_onboarding()->MaybeMarkSilentEligible();
+  tracking_protection_onboarding()->SilentOnboardingNoticeShown();
+
+  // Needs registration
+  EXPECT_TRUE(tracking_protection_onboarding()->RequiresSentimentSurveyGroup());
+
+  // Action: Register the group.
+  tracking_protection_onboarding()->RegisterSentimentSurveyGroup(
+      SentimentSurveyGroup::kControlDelayed);
+
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.SentimentSurvey.Registered",
+      TrackingProtectionOnboarding::SentimentSurveyGroupMetrics::
+          kControlDelayed,
+      1);
+
+  // Verification: Registration no longer required.
+  EXPECT_FALSE(
+      tracking_protection_onboarding()->RequiresSentimentSurveyGroup());
+
+  // Registered group not yet returned
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kNotSet);
+
+  // Registered returned after the survey start time, and before the survey end
+  // time.
+  task_env_.FastForwardBy(base::Days(14));
+
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kControlDelayed);
+}
+
+TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding,
+       RegistersControlAndOnboardsLater) {
+  // Setup
+  tracking_protection_onboarding()->MaybeMarkSilentEligible();
+
+  // Action: Register the group.
+  tracking_protection_onboarding()->RegisterSentimentSurveyGroup(
+      SentimentSurveyGroup::kControlImmediate);
+
+  // Verification: Registration no longer required.
+  EXPECT_FALSE(
+      tracking_protection_onboarding()->RequiresSentimentSurveyGroup());
+
+  // Action: Silently onboard.
+  tracking_protection_onboarding()->SilentOnboardingNoticeShown();
+
+  // Registered group still not returned after Acking the notice
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kNotSet);
+
+  // Registered group returned after the survey start time, and before the
+  // survey end time.
+  task_env_.FastForwardBy(base::Minutes(3));
+  EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(),
+            SentimentSurveyGroup::kControlImmediate);
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.SentimentSurvey.Registered",
+      TrackingProtectionOnboarding::SentimentSurveyGroupMetrics::
+          kControlImmediate,
+      1);
+}
+
 class TrackingProtectionOffboardingTest
     : public TrackingProtectionOnboardingTest {
  public:
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn
index e29550a..b1fc89b 100644
--- a/components/safe_browsing/content/browser/BUILD.gn
+++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -26,24 +26,6 @@
   ]
 }
 
-source_set("client_report_util") {
-  sources = [
-    "client_report_util.cc",
-    "client_report_util.h",
-  ]
-
-  configs += [ "//build/config/compiler:wexit_time_destructors" ]
-
-  deps = [
-    "//base:base",
-    "//components/safe_browsing/core/common/proto:csd_proto",
-    "//components/security_interstitials/content:security_interstitial_page",
-    "//components/security_interstitials/core",
-    "//components/security_interstitials/core:unsafe_resource",
-    "//content/public/browser",
-  ]
-}
-
 # NOTE: This target is separated from :browser as
 # //components/safe_browsing/content/browser/triggers, which this depends on, depends
 # on :browser.
@@ -66,7 +48,6 @@
 
     deps = [
       ":browser",
-      ":client_report_util",
       "//base",
       "//components/no_state_prefetch/browser",
       "//components/prefs",
@@ -95,6 +76,8 @@
     "base_ui_manager.h",
     "browser_url_loader_throttle.cc",
     "browser_url_loader_throttle.h",
+    "client_report_util.cc",
+    "client_report_util.h",
     "mojo_safe_browsing_impl.cc",
     "mojo_safe_browsing_impl.h",
     "safe_browsing_controller_client.cc",
@@ -107,6 +90,8 @@
     "threat_details_cache.h",
     "threat_details_history.cc",
     "threat_details_history.h",
+    "unsafe_resource_util.cc",
+    "unsafe_resource_util.h",
     "url_checker_on_sb.cc",
     "url_checker_on_sb.h",
     "web_api_handshake_checker.cc",
@@ -118,7 +103,6 @@
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 
   deps = [
-    ":client_report_util",
     "//base",
     "//base:i18n",
     "//components/back_forward_cache",
@@ -190,7 +174,6 @@
     "//components/optimization_guide/proto:optimization_guide_proto",
     "//components/safe_browsing:buildflags",
     "//components/safe_browsing/content/browser:browser",
-    "//components/safe_browsing/content/browser:client_report_util",
     "//components/safe_browsing/core/browser:browser",
     "//components/safe_browsing/core/browser/db:test_database_manager",
     "//components/safe_browsing/core/common",
diff --git a/components/safe_browsing/content/browser/async_check_tracker.cc b/components/safe_browsing/content/browser/async_check_tracker.cc
index c62bcb5..2b331f3 100644
--- a/components/safe_browsing/content/browser/async_check_tracker.cc
+++ b/components/safe_browsing/content/browser/async_check_tracker.cc
@@ -5,6 +5,7 @@
 #include "components/safe_browsing/content/browser/async_check_tracker.h"
 
 #include "components/safe_browsing/content/browser/base_ui_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -22,6 +23,14 @@
   return AsyncCheckTracker::FromWebContents(web_contents);
 }
 
+// static
+bool AsyncCheckTracker::IsMainPageLoadPending(
+    const security_interstitials::UnsafeResource& resource) {
+  // TODO(crbug.com/1501194): Implement this function when
+  // async Safe Browsing check is enabled.
+  return resource.IsMainPageLoadPendingWithSyncCheck();
+}
+
 AsyncCheckTracker::AsyncCheckTracker(content::WebContents* web_contents,
                                      scoped_refptr<BaseUIManager> ui_manager)
     : content::WebContentsUserData<AsyncCheckTracker>(*web_contents),
diff --git a/components/safe_browsing/content/browser/async_check_tracker.h b/components/safe_browsing/content/browser/async_check_tracker.h
index 4900e3a..0d08e6c 100644
--- a/components/safe_browsing/content/browser/async_check_tracker.h
+++ b/components/safe_browsing/content/browser/async_check_tracker.h
@@ -9,6 +9,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "components/safe_browsing/content/browser/url_checker_on_sb.h"
+#include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -35,6 +36,13 @@
       content::WebContents* web_contents,
       scoped_refptr<BaseUIManager> ui_manager);
 
+  // Returns true if the main frame load is pending (i.e. the navigation has not
+  // yet committed). Note that a main frame hit may not be pending, eg. 1)
+  // client side detection happens after the load is committed, or 2) async Safe
+  // Browsing check is enabled.
+  static bool IsMainPageLoadPending(
+      const security_interstitials::UnsafeResource& resource);
+
   AsyncCheckTracker(const AsyncCheckTracker&) = delete;
   AsyncCheckTracker& operator=(const AsyncCheckTracker&) = delete;
 
diff --git a/components/safe_browsing/content/browser/base_blocking_page.cc b/components/safe_browsing/content/browser/base_blocking_page.cc
index eea47dd..d26e13b 100644
--- a/components/safe_browsing/content/browser/base_blocking_page.cc
+++ b/components/safe_browsing/content/browser/base_blocking_page.cc
@@ -11,12 +11,13 @@
 #include "base/lazy_instance.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
+#include "components/safe_browsing/content/browser/async_check_tracker.h"
 #include "components/safe_browsing/content/browser/safe_browsing_controller_client.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/content/settings_page_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/metrics_helper.h"
 #include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
@@ -68,7 +69,7 @@
           base::Time::NowFromSystemTime(),
           controller(),
           /* created_prior_to_navigation */
-          IsMainPageLoadBlocked(unsafe_resources))) {}
+          IsMainPageLoadPending(unsafe_resources))) {}
 
 BaseBlockingPage::~BaseBlockingPage() {}
 
@@ -77,7 +78,7 @@
 BaseBlockingPage::CreateDefaultDisplayOptions(
     const UnsafeResourceList& unsafe_resources) {
   return BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
-      IsMainPageLoadBlocked(unsafe_resources),
+      IsMainPageLoadPending(unsafe_resources),
       false,                 // kSafeBrowsingExtendedReportingOptInAllowed
       false,                 // is_off_the_record
       false,                 // is_extended_reporting
@@ -92,12 +93,12 @@
 }
 
 // static
-bool BaseBlockingPage::IsMainPageLoadBlocked(
+bool BaseBlockingPage::IsMainPageLoadPending(
     const UnsafeResourceList& unsafe_resources) {
   // If there is more than one unsafe resource, the main page load must not be
-  // blocked. Otherwise, check if the one resource is.
+  // pending. Otherwise, check if the one resource is.
   return unsafe_resources.size() == 1 &&
-         unsafe_resources[0].IsMainPageLoadBlocked();
+         AsyncCheckTracker::IsMainPageLoadPending(unsafe_resources[0]);
 }
 
 void BaseBlockingPage::SetThreatDetailsProceedDelayForTesting(int64_t delay) {
diff --git a/components/safe_browsing/content/browser/base_blocking_page.h b/components/safe_browsing/content/browser/base_blocking_page.h
index 83328188..cdc88d4 100644
--- a/components/safe_browsing/content/browser/base_blocking_page.h
+++ b/components/safe_browsing/content/browser/base_blocking_page.h
@@ -48,7 +48,7 @@
 
   // Returns true if the passed |unsafe_resources| is blocking the load of
   // the main page.
-  static bool IsMainPageLoadBlocked(const UnsafeResourceList& unsafe_resources);
+  static bool IsMainPageLoadPending(const UnsafeResourceList& unsafe_resources);
 
   // SecurityInterstitialPage method:
   void CommandReceived(const std::string& command) override;
diff --git a/components/safe_browsing/content/browser/base_ui_manager.cc b/components/safe_browsing/content/browser/base_ui_manager.cc
index 75751e04..5e0e9ee 100644
--- a/components/safe_browsing/content/browser/base_ui_manager.cc
+++ b/components/safe_browsing/content/browser/base_ui_manager.cc
@@ -11,10 +11,11 @@
 #include "base/functional/callback.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/ptr_util.h"
+#include "components/safe_browsing/content/browser/async_check_tracker.h"
 #include "components/safe_browsing/content/browser/base_blocking_page.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -157,11 +158,11 @@
 bool BaseUIManager::IsAllowlisted(const UnsafeResource& resource) {
   NavigationEntry* entry = nullptr;
   if (resource.is_subresource) {
-    entry = GetNavigationEntryForResource(resource);
+    entry = unsafe_resource_util::GetNavigationEntryForResource(resource);
   }
 
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   // |web_contents| can be null after RenderFrameHost is destroyed.
   if (!web_contents)
     return false;
@@ -252,7 +253,7 @@
   // The tab might have been closed. If it was closed, just act as if "Don't
   // Proceed" had been chosen.
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   if (!web_contents) {
     OnBlockingPageDone(std::vector<UnsafeResource>{resource},
                        false /* proceed */, web_contents,
@@ -288,16 +289,17 @@
 
   // |entry| can be null if we are on a brand new tab, and a resource is added
   // via javascript without a navigation.
-  content::NavigationEntry* entry = GetNavigationEntryForResource(resource);
+  content::NavigationEntry* entry =
+      unsafe_resource_util::GetNavigationEntryForResource(resource);
 
   GURL unsafe_url = resource.url;
-  if (entry && !resource.IsMainPageLoadBlocked()) {
+  if (entry && !AsyncCheckTracker::IsMainPageLoadPending(resource)) {
     unsafe_url = entry->GetURL();
   }
 
-  // In top-document navigation cases, we just mark the resource unsafe and
-  // cancel the load from here, the actual interstitial will be shown from the
-  // SafeBrowsingNavigationThrottle when the navigation fails.
+  // If the top-level navigation is still pending, we just mark the resource
+  // unsafe and cancel the load from here, the actual interstitial will be shown
+  // from the SafeBrowsingNavigationThrottle when the navigation fails.
   //
   // In other cases, the error interstitial is manually loaded here, after the
   // load is canceled:
@@ -309,8 +311,11 @@
   // - Delayed Warning Experiment: When enabled, this method is only called
   //   after the navigation completes and a user action occurs so the throttle
   //   cannot be used.
+  // - Async check: If the check is not able to complete before
+  //   DidFinishNavigation, it won't hit the throttle.
   const bool load_post_commit_error_page =
-      !resource.IsMainPageLoadBlocked() || resource.is_delayed_warning;
+      !AsyncCheckTracker::IsMainPageLoadPending(resource) ||
+      resource.is_delayed_warning;
   if (!load_post_commit_error_page) {
     AddUnsafeResource(unsafe_url, resource);
   }
@@ -546,10 +551,11 @@
 // static
 GURL BaseUIManager::GetMainFrameAllowlistUrlForResource(
     const security_interstitials::UnsafeResource& resource) {
-  return GetAllowlistUrl(resource.url, resource.is_subresource,
-                         resource.is_subresource
-                             ? GetNavigationEntryForResource(resource)
-                             : nullptr);
+  return GetAllowlistUrl(
+      resource.url, resource.is_subresource,
+      resource.is_subresource
+          ? unsafe_resource_util::GetNavigationEntryForResource(resource)
+          : nullptr);
 }
 
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/content/browser/client_report_util.cc b/components/safe_browsing/content/browser/client_report_util.cc
index 07626bf..c395376 100644
--- a/components/safe_browsing/content/browser/client_report_util.cc
+++ b/components/safe_browsing/content/browser/client_report_util.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/safe_browsing/content/browser/client_report_util.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_entry.h"
 
@@ -236,7 +236,7 @@
     // |GetNavigationEntryForResource| can only be called from the UI thread.
     if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
       content::NavigationEntry* nav_entry =
-          GetNavigationEntryForResource(resource);
+          unsafe_resource_util::GetNavigationEntryForResource(resource);
       if (nav_entry) {
         page_url = nav_entry->GetURL();
       }
@@ -253,7 +253,7 @@
     // |GetNavigationEntryForResource| can only be called from the UI thread.
     if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
       content::NavigationEntry* nav_entry =
-          GetNavigationEntryForResource(resource);
+          unsafe_resource_util::GetNavigationEntryForResource(resource);
       if (nav_entry) {
         referrer_url = nav_entry->GetReferrer().url;
       }
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc
index 546e1497..5e23723 100644
--- a/components/safe_browsing/content/browser/client_side_detection_host.cc
+++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -24,6 +24,7 @@
 #include "components/safe_browsing/content/browser/client_side_detection_feature_cache.h"
 #include "components/safe_browsing/content/browser/client_side_detection_service.h"
 #include "components/safe_browsing/content/browser/client_side_phishing_model.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom.h"
 #include "components/safe_browsing/content/common/visual_utils.h"
@@ -31,7 +32,7 @@
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/sync/sync_utils.h"
 #include "components/safe_browsing/core/common/features.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/zoom/zoom_controller.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
diff --git a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc
index c686a02..d6bf88e2 100644
--- a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc
@@ -17,6 +17,7 @@
 #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/core/browser/safe_browsing_hats_delegate.h"
 #include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h"
@@ -25,7 +26,6 @@
 #include "components/safe_browsing/core/common/utils.h"
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/content/settings_page_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/controller_client.h"
 #include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc
index b78bc27..40ae3ae 100644
--- a/components/safe_browsing/content/browser/threat_details.cc
+++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -27,17 +27,18 @@
 #include "base/strings/stringprintf.h"
 #include "components/back_forward_cache/back_forward_cache_disable.h"
 #include "components/history/core/browser/history_service.h"
+#include "components/safe_browsing/content/browser/async_check_tracker.h"
 #include "components/safe_browsing/content/browser/base_ui_manager.h"
 #include "components/safe_browsing/content/browser/client_report_util.h"
 #include "components/safe_browsing/content/browser/threat_details_cache.h"
 #include "components/safe_browsing/content/browser/threat_details_history.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/browser/db/hit_report.h"
 #include "components/safe_browsing/core/browser/referrer_chain_provider.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -551,7 +552,7 @@
     AddUrl(referrer_url, GURL(), std::string(), nullptr);
   }
 
-  if (!resource_.IsMainPageLoadBlocked()) {
+  if (!AsyncCheckTracker::IsMainPageLoadPending(resource_)) {
     // Get URLs of frames, scripts etc from the DOM.
     // OnReceivedThreatDOMDetails will be called when the renderer replies.
     // TODO(mattm): In theory, if the user proceeds through the warning DOM
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
index 6deb657..c095429 100644
--- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
+++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
@@ -17,10 +17,10 @@
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_util.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/core/browser/referrer_chain_provider.h"
 #include "components/safe_browsing/core/common/features.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
index 548d8fd..8f5e6cb 100644
--- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
+++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
@@ -13,9 +13,9 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/content/browser/web_contents_key.h"
 #include "components/safe_browsing/core/browser/referrer_chain_provider.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
diff --git a/components/safe_browsing/content/browser/ui_manager.cc b/components/safe_browsing/content/browser/ui_manager.cc
index 13fe444..5245a696 100644
--- a/components/safe_browsing/content/browser/ui_manager.cc
+++ b/components/safe_browsing/content/browser/ui_manager.cc
@@ -12,15 +12,16 @@
 #include "base/threading/thread_restrictions.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/async_check_tracker.h"
 #include "components/safe_browsing/content/browser/client_report_util.h"
 #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/browser/ping_manager.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -62,7 +63,7 @@
 void SafeBrowsingUIManager::CreateAndSendHitReport(
     const UnsafeResource& resource) {
   WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   DCHECK(web_contents);
   std::unique_ptr<HitReport> hit_report = std::make_unique<HitReport>();
   hit_report->malicious_url = resource.url;
@@ -71,7 +72,8 @@
   hit_report->threat_source = resource.threat_source;
   hit_report->population_id = resource.threat_metadata.population_id;
 
-  NavigationEntry* entry = GetNavigationEntryForResource(resource);
+  NavigationEntry* entry =
+      unsafe_resource_util::GetNavigationEntryForResource(resource);
   if (entry) {
     hit_report->page_url = entry->GetURL();
     hit_report->referrer_url = entry->GetReferrer().url;
@@ -105,7 +107,7 @@
 void SafeBrowsingUIManager::CreateAndSendClientSafeBrowsingWarningShownReport(
     const UnsafeResource& resource) {
   WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   DCHECK(web_contents);
   std::unique_ptr<ClientSafeBrowsingReportRequest> report =
       std::make_unique<ClientSafeBrowsingReportRequest>();
@@ -139,7 +141,7 @@
 void SafeBrowsingUIManager::StartDisplayingBlockingPage(
     const security_interstitials::UnsafeResource& resource) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
 
   if (!web_contents) {
     // Tab is gone.
@@ -215,13 +217,13 @@
     return;
   }
 
-  // With committed interstitials, if this is a main frame load, we need to
-  // get the navigation URL and referrer URL from the navigation entry now,
-  // since they are required for threat reporting, and the entry will be
-  // destroyed once the request is failed.
-  if (resource.IsMainPageLoadBlocked()) {
+  // If the main frame load is still pending, we need to get the navigation URL
+  // and referrer URL from the navigation entry now, since they are required for
+  // threat reporting, and the entry will be destroyed once the request is
+  // failed.
+  if (AsyncCheckTracker::IsMainPageLoadPending(resource)) {
     content::NavigationEntry* entry =
-        security_interstitials::GetNavigationEntryForResource(resource);
+        unsafe_resource_util::GetNavigationEntryForResource(resource);
     if (entry) {
       security_interstitials::UnsafeResource resource_copy(resource);
       resource_copy.navigation_url = entry->GetURL();
@@ -238,7 +240,7 @@
     base::OnceCallback<void(bool)> callback,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
   content::WebContents* web_contents =
-      security_interstitials::GetWebContentsForResource(resource);
+      unsafe_resource_util::GetWebContentsForResource(resource);
   auto determine_if_is_prerender = [resource, web_contents]() {
     content::RenderFrameHost* rfh = nullptr;
     if (resource.render_frame_token) {
diff --git a/components/safe_browsing/content/browser/ui_manager_unittest.cc b/components/safe_browsing/content/browser/ui_manager_unittest.cc
index b42d9941..7f478c0 100644
--- a/components/safe_browsing/content/browser/ui_manager_unittest.cc
+++ b/components/safe_browsing/content/browser/ui_manager_unittest.cc
@@ -14,11 +14,11 @@
 #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h"
 #include "components/safe_browsing/content/browser/safe_browsing_blocking_page_factory.h"
 #include "components/safe_browsing/content/browser/safe_browsing_controller_client.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 #include "components/safe_browsing/core/browser/db/util.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/content/settings_page_helper.h"
-#include "components/security_interstitials/content/unsafe_resource_util.h"
 #include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
 #include "components/security_interstitials/core/metrics_helper.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
@@ -108,7 +108,7 @@
                 manager->default_safe_page(),
                 /*settings_helper=*/nullptr),
             BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
-                BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
+                BaseBlockingPage::IsMainPageLoadPending(unsafe_resources),
                 false,                 // is_extended_reporting_opt_in_allowed
                 false,                 // is_off_the_record
                 false,                 // is_extended_reporting_enabled
@@ -349,7 +349,7 @@
   ASSERT_TRUE(entry);
   EXPECT_TRUE(ui_manager()->IsUrlAllowlistedOrPendingForWebContents(
       resource.url, resource.is_subresource, entry,
-      security_interstitials::GetWebContentsForResource(resource), true,
+      unsafe_resource_util::GetWebContentsForResource(resource), true,
       &threat_type));
   EXPECT_EQ(resource.threat_type, threat_type);
 }
@@ -695,7 +695,7 @@
   content::GlobalRenderFrameHostId invalid_rfh_id;
   resource.render_process_id = invalid_rfh_id.child_id;
   resource.render_frame_token = base::UnguessableToken::Create();
-  ASSERT_FALSE(security_interstitials::GetWebContentsForResource(resource));
+  ASSERT_FALSE(unsafe_resource_util::GetWebContentsForResource(resource));
 
   EXPECT_FALSE(IsAllowlisted(resource));
 }
diff --git a/components/security_interstitials/content/unsafe_resource_util.cc b/components/safe_browsing/content/browser/unsafe_resource_util.cc
similarity index 72%
rename from components/security_interstitials/content/unsafe_resource_util.cc
rename to components/safe_browsing/content/browser/unsafe_resource_util.cc
index c7d613f..1d80ff5 100644
--- a/components/security_interstitials/content/unsafe_resource_util.cc
+++ b/components/safe_browsing/content/browser/unsafe_resource_util.cc
@@ -2,23 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/security_interstitials/content/unsafe_resource_util.h"
+#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
 
+#include "components/safe_browsing/content/browser/async_check_tracker.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 
-namespace security_interstitials {
+namespace safe_browsing::unsafe_resource_util {
 
 content::NavigationEntry* GetNavigationEntryForResource(
-    const UnsafeResource& resource) {
-  content::WebContents* web_contents = GetWebContentsForResource(resource);
-  if (!web_contents)
+    const security_interstitials::UnsafeResource& resource) {
+  content::WebContents* web_contents = unsafe_resource_util::GetWebContentsForResource(resource);
+  if (!web_contents) {
     return nullptr;
+  }
   // If a safebrowsing hit occurs during main frame navigation, the navigation
   // will not be committed, and the pending navigation entry refers to the hit.
-  if (resource.IsMainPageLoadBlocked())
+  if (AsyncCheckTracker::IsMainPageLoadPending(resource)) {
     return web_contents->GetController().GetPendingEntry();
+  }
   // If a safebrowsing hit occurs on a subresource load, or on a main frame
   // after the navigation is committed, the last committed navigation entry
   // refers to the page with the hit. Note that there may concurrently be an
@@ -28,7 +31,7 @@
 }
 
 content::WebContents* GetWebContentsForResource(
-    const UnsafeResource& resource) {
+    const security_interstitials::UnsafeResource& resource) {
   if (resource.render_frame_token) {
     content::RenderFrameHost* rfh = content::RenderFrameHost::FromFrameToken(
         content::GlobalRenderFrameHostToken(
@@ -41,4 +44,4 @@
   return content::WebContents::FromFrameTreeNodeId(resource.frame_tree_node_id);
 }
 
-}  // namespace security_interstitials
+}  // namespace safe_browsing::unsafe_resource_util
diff --git a/components/security_interstitials/content/unsafe_resource_util.h b/components/safe_browsing/content/browser/unsafe_resource_util.h
similarity index 63%
rename from components/security_interstitials/content/unsafe_resource_util.h
rename to components/safe_browsing/content/browser/unsafe_resource_util.h
index a37fed6..c5d9ec3 100644
--- a/components/security_interstitials/content/unsafe_resource_util.h
+++ b/components/safe_browsing/content/browser/unsafe_resource_util.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_
-#define COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_
+#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_
+#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_
 
 #include "components/security_interstitials/core/unsafe_resource.h"
 
@@ -12,27 +12,28 @@
 class WebContents;
 }  // namespace content
 
-namespace security_interstitials {
+namespace safe_browsing::unsafe_resource_util {
 
 // Returns the NavigationEntry for |resource| (for a main frame hit) or
 // for the page which contains this resource (for a subresource hit).
 // This method must only be called while the UnsafeResource is still
 // "valid".
 // I.e,
-//   For MainPageLoadBlocked resources, it must not be called if the load
+//   For MainPageLoadPending resources, it must not be called if the load
 //   was aborted (going back or replaced with a different navigation),
 //   or resumed (proceeded through warning or matched whitelist).
-//   For non-MainPageLoadBlocked resources, it must not be called if any
+//   For non-MainPageLoadPending resources, it must not be called if any
 //   other navigation has committed (whether by going back or unrelated
 //   navigations), though a pending navigation is okay.
 content::NavigationEntry* GetNavigationEntryForResource(
-    const UnsafeResource& resource);
+    const security_interstitials::UnsafeResource& resource);
 
 // Returns the WebContents associated with the given |resource| based on the
 // frame or document for which it was created. If that frame/document no longer
 // exists, this returns nullptr.
-content::WebContents* GetWebContentsForResource(const UnsafeResource& resource);
+content::WebContents* GetWebContentsForResource(
+    const security_interstitials::UnsafeResource& resource);
 
-}  // namespace security_interstitials
+}  // namespace safe_browsing::unsafe_resource_util
 
-#endif  // COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_
+#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_
diff --git a/components/security_interstitials/content/BUILD.gn b/components/security_interstitials/content/BUILD.gn
index bd15725..b85b0e12 100644
--- a/components/security_interstitials/content/BUILD.gn
+++ b/components/security_interstitials/content/BUILD.gn
@@ -56,8 +56,6 @@
     "ssl_error_navigation_throttle.h",
     "stateful_ssl_host_state_delegate.cc",
     "stateful_ssl_host_state_delegate.h",
-    "unsafe_resource_util.cc",
-    "unsafe_resource_util.h",
     "urls.cc",
     "urls.h",
     "utils.cc",
diff --git a/components/security_interstitials/core/unsafe_resource.cc b/components/security_interstitials/core/unsafe_resource.cc
index 9bd40c8..4e78cbf 100644
--- a/components/security_interstitials/core/unsafe_resource.cc
+++ b/components/security_interstitials/core/unsafe_resource.cc
@@ -22,7 +22,7 @@
 
 UnsafeResource::~UnsafeResource() = default;
 
-bool UnsafeResource::IsMainPageLoadBlocked() const {
+bool UnsafeResource::IsMainPageLoadPendingWithSyncCheck() const {
   // Subresource hits cannot happen until after main page load is committed.
   if (is_subresource)
     return false;
diff --git a/components/security_interstitials/core/unsafe_resource.h b/components/security_interstitials/core/unsafe_resource.h
index 1b0e375..6adbebfa3 100644
--- a/components/security_interstitials/core/unsafe_resource.h
+++ b/components/security_interstitials/core/unsafe_resource.h
@@ -55,11 +55,12 @@
   UnsafeResource(const UnsafeResource& other);
   ~UnsafeResource();
 
-  // Returns true if this UnsafeResource is a main frame load that was blocked
-  // while the navigation is still pending. Note that a main frame hit may not
-  // be blocking, eg. client side detection happens after the load is
-  // committed.
-  bool IsMainPageLoadBlocked() const;
+  // Returns true if this UnsafeResource is a main frame load while the
+  // navigation is still pending. Note that a main frame hit may not be
+  // blocking, eg. client side detection happens after the load is committed.
+  // Note: If kSafeBrowsingAsyncRealTimeCheck is supported, please call
+  // AsyncCheckTracker::IsMainPageLoadPending instead.
+  bool IsMainPageLoadPendingWithSyncCheck() const;
 
   // Checks if |callback| is not null and posts it to |callback_sequence|.
   void DispatchCallback(const base::Location& from_here,
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
index f610e8a..5a04c150 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
@@ -64,12 +64,15 @@
 
     private MakeCredential_Response mMakeCredentialCallback;
     private GetAssertion_Response mGetAssertionCallback;
-    // A queue is used to store pending IsUserVerifyingPlatformAuthenticatorAvailable request
-    // callbacks when there are multiple requests pending on the result from GMSCore. Noted that
-    // the callbacks may not be invoked in the same order as the pending requests, which in this
-    // situation does not matter because all pending requests will return the same value.
-    private Queue<org.chromium.mojo.bindings.Callbacks.Callback1<Boolean>>
+    // A queue for pending isUserVerifyingPlatformAuthenticatorAvailable request callbacks when
+    // there are multiple requests pending on the result from GMSCore. Note that the callbacks may
+    // not be invoked in the same order the pending requests were enqueued, but this is OK because
+    // all pending requests end up returning the same value.
+    private Queue<IsUserVerifyingPlatformAuthenticatorAvailable_Response>
             mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue = new LinkedList<>();
+    // Similar to the above, but for pending isConditionalMediationAvailable request callbacks.
+    private Queue<IsConditionalMediationAvailable_Response>
+            mIsConditionalMediationAvailableCallbackQueue = new LinkedList<>();
     private Fido2CredentialRequest mPendingFido2CredentialRequest;
     private Set<Fido2CredentialRequest> mUnclosedFido2CredentialRequests = new HashSet<>();
 
@@ -279,12 +282,10 @@
         // If the gmscore and chromium versions are out of sync for some reason, this method will
         // return true but chrome will ignore conditional requests. Android surfaces only platform
         // credentials on conditional requests, use IsUVPAA as a proxy for availability.
-        mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.add(callback);
+        mIsConditionalMediationAvailableCallbackQueue.add(callback);
         getFido2CredentialRequest()
                 .handleIsUserVerifyingPlatformAuthenticatorAvailableRequest(
-                        mContext,
-                        isUvpaa ->
-                                onIsUserVerifyingPlatformAuthenticatorAvailableResponse(isUvpaa));
+                        mContext, isUvpaa -> onIsConditionalMediationAvailableResponse(isUvpaa));
     }
 
     @Override
@@ -325,6 +326,11 @@
         mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.poll().call(isUVPAA);
     }
 
+    public void onIsConditionalMediationAvailableResponse(boolean isUVPAA) {
+        assert !mIsConditionalMediationAvailableCallbackQueue.isEmpty();
+        mIsConditionalMediationAvailableCallbackQueue.poll().call(isUVPAA);
+    }
+
     public void onError(Integer status) {
         // In case mojo pipe is closed due to the page begin destroyed while waiting for response.
         if (!mIsOperationPending) return;
diff --git a/content/browser/media/audio_stream_monitor.cc b/content/browser/media/audio_stream_monitor.cc
index 0f6a801..7e616e0 100644
--- a/content/browser/media/audio_stream_monitor.cc
+++ b/content/browser/media/audio_stream_monitor.cc
@@ -17,38 +17,37 @@
 
 namespace {
 
-AudioStreamMonitor* GetMonitorForRenderFrame(int render_process_id,
-                                             int render_frame_id) {
+AudioStreamMonitor* GetMonitorForRenderFrame(
+    GlobalRenderFrameHostId render_frame_host_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   WebContentsImpl* const web_contents =
       static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(
-          RenderFrameHost::FromID(render_process_id, render_frame_id)));
+          RenderFrameHost::FromID(render_frame_host_id)));
   return web_contents ? web_contents->audio_stream_monitor() : nullptr;
 }
 
 }  // namespace
 
 AudioStreamMonitor::AudibleClientRegistration::AudibleClientRegistration(
-    GlobalRenderFrameHostId host_id,
+    GlobalRenderFrameHostId render_frame_host_id,
     AudioStreamMonitor* audio_stream_monitor)
-    : host_id_(host_id), audio_stream_monitor_(audio_stream_monitor) {
-  audio_stream_monitor_->AddAudibleClient(host_id_);
+    : render_frame_host_id_(render_frame_host_id),
+      audio_stream_monitor_(audio_stream_monitor) {
+  audio_stream_monitor_->AddAudibleClient(render_frame_host_id_);
 }
 
 AudioStreamMonitor::AudibleClientRegistration::~AudibleClientRegistration() {
-  audio_stream_monitor_->RemoveAudibleClient(host_id_);
+  audio_stream_monitor_->RemoveAudibleClient(render_frame_host_id_);
 }
 
 bool AudioStreamMonitor::StreamID::operator<(const StreamID& other) const {
-  return std::tie(render_process_id, render_frame_id, stream_id) <
-         std::tie(other.render_process_id, other.render_frame_id,
-                  other.stream_id);
+  return std::tie(render_frame_host_id, stream_id) <
+         std::tie(other.render_frame_host_id, other.stream_id);
 }
 
 bool AudioStreamMonitor::StreamID::operator==(const StreamID& other) const {
-  return std::tie(render_process_id, render_frame_id, stream_id) ==
-         std::tie(other.render_process_id, other.render_frame_id,
-                  other.stream_id);
+  return std::tie(render_frame_host_id, stream_id) ==
+         std::tie(other.render_frame_host_id, other.stream_id);
 }
 
 AudioStreamMonitor::AudioStreamMonitor(WebContents* contents)
@@ -81,31 +80,35 @@
   // Streams must be removed locally before calling UpdateStreams() in order to
   // avoid removing streams from the process twice, since RenderProcessHost
   // removes the streams on its own when the renderer process is gone.
-  base::EraseIf(streams_,
-                [render_process_id](const std::pair<StreamID, bool>& entry) {
-                  return entry.first.render_process_id == render_process_id;
-                });
+  base::EraseIf(
+      streams_, [render_process_id](const std::pair<StreamID, bool>& entry) {
+        return entry.first.render_frame_host_id.child_id == render_process_id;
+      });
   UpdateStreams();
 }
 
 std::unique_ptr<AudioStreamMonitor::AudibleClientRegistration>
-AudioStreamMonitor::RegisterAudibleClient(GlobalRenderFrameHostId host_id) {
+AudioStreamMonitor::RegisterAudibleClient(
+    GlobalRenderFrameHostId render_frame_host_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return std::make_unique<AudibleClientRegistration>(host_id, this);
+  return std::make_unique<AudibleClientRegistration>(render_frame_host_id,
+                                                     this);
 }
 
-void AudioStreamMonitor::AddAudibleClient(GlobalRenderFrameHostId host_id) {
+void AudioStreamMonitor::AddAudibleClient(
+    GlobalRenderFrameHostId render_frame_host_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  audible_clients_[host_id]++;
+  audible_clients_[render_frame_host_id]++;
   UpdateStreams();
 }
 
-void AudioStreamMonitor::RemoveAudibleClient(GlobalRenderFrameHostId host_id) {
+void AudioStreamMonitor::RemoveAudibleClient(
+    GlobalRenderFrameHostId render_frame_host_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!audible_clients_.empty());
 
-  auto it = audible_clients_.find(host_id);
+  auto it = audible_clients_.find(render_frame_host_id);
   CHECK(it != audible_clients_.end());
   CHECK_GT(it->second, 0u);
   it->second--;
@@ -118,52 +121,52 @@
 }
 
 // static
-void AudioStreamMonitor::StartMonitoringStream(int render_process_id,
-                                               int render_frame_id,
-                                               int stream_id) {
+void AudioStreamMonitor::StartMonitoringStream(
+    GlobalRenderFrameHostId render_frame_host_id,
+    int stream_id) {
   GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(
           [](const StreamID& sid) {
-            if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
-                    sid.render_process_id, sid.render_frame_id)) {
+            if (AudioStreamMonitor* monitor =
+                    GetMonitorForRenderFrame(sid.render_frame_host_id)) {
               monitor->StartMonitoringStreamOnUIThread(sid);
             }
           },
-          StreamID{render_process_id, render_frame_id, stream_id}));
+          StreamID{render_frame_host_id, stream_id}));
 }
 
 // static
-void AudioStreamMonitor::StopMonitoringStream(int render_process_id,
-                                              int render_frame_id,
-                                              int stream_id) {
+void AudioStreamMonitor::StopMonitoringStream(
+    GlobalRenderFrameHostId render_frame_host_id,
+    int stream_id) {
   GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(
           [](const StreamID& sid) {
-            if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
-                    sid.render_process_id, sid.render_frame_id)) {
+            if (AudioStreamMonitor* monitor =
+                    GetMonitorForRenderFrame(sid.render_frame_host_id)) {
               monitor->StopMonitoringStreamOnUIThread(sid);
             }
           },
-          StreamID{render_process_id, render_frame_id, stream_id}));
+          StreamID{render_frame_host_id, stream_id}));
 }
 
 // static
-void AudioStreamMonitor::UpdateStreamAudibleState(int render_process_id,
-                                                  int render_frame_id,
-                                                  int stream_id,
-                                                  bool is_audible) {
+void AudioStreamMonitor::UpdateStreamAudibleState(
+    GlobalRenderFrameHostId render_frame_host_id,
+    int stream_id,
+    bool is_audible) {
   GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(
           [](const StreamID& sid, bool is_audible) {
-            if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
-                    sid.render_process_id, sid.render_frame_id)) {
+            if (AudioStreamMonitor* monitor =
+                    GetMonitorForRenderFrame(sid.render_frame_host_id)) {
               monitor->UpdateStreamAudibleStateOnUIThread(sid, is_audible);
             }
           },
-          StreamID{render_process_id, render_frame_id, stream_id}, is_audible));
+          StreamID{render_frame_host_id, stream_id}, is_audible));
 }
 
 void AudioStreamMonitor::StartMonitoringStreamOnUIThread(const StreamID& sid) {
@@ -208,9 +211,7 @@
   for (auto& kv : streams_) {
     const bool is_stream_audible = kv.second;
     is_audible_ |= is_stream_audible;
-    GlobalRenderFrameHostId host_id(kv.first.render_process_id,
-                                    kv.first.render_frame_id);
-    audible_frames[host_id] |= is_stream_audible;
+    audible_frames[kv.first.render_frame_host_id] |= is_stream_audible;
   }
 
   for (auto& kv : audible_clients_) {
@@ -278,15 +279,11 @@
 
 void AudioStreamMonitor::RenderFrameDeleted(
     RenderFrameHost* render_frame_host) {
-  int render_process_id = render_frame_host->GetProcess()->GetID();
-  int render_frame_id = render_frame_host->GetRoutingID();
-
   // It is possible for a frame to be deleted before notifications about its
   // streams are received. Explicitly clear these streams.
-  base::EraseIf(streams_, [render_process_id, render_frame_id](
+  base::EraseIf(streams_, [render_frame_host](
                               const std::pair<StreamID, bool>& entry) {
-    return entry.first.render_process_id == render_process_id &&
-           entry.first.render_frame_id == render_frame_id;
+    return entry.first.render_frame_host_id == render_frame_host->GetGlobalId();
   });
   UpdateStreams();
 }
diff --git a/content/browser/media/audio_stream_monitor.h b/content/browser/media/audio_stream_monitor.h
index 8fe47fb..ad12769 100644
--- a/content/browser/media/audio_stream_monitor.h
+++ b/content/browser/media/audio_stream_monitor.h
@@ -13,6 +13,7 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/web_contents_observer.h"
 
 namespace content {
@@ -57,18 +58,17 @@
 
   // Starts or stops monitoring respectively for the stream owned by the
   // specified renderer.  Safe to call from any thread.
-  static void StartMonitoringStream(int render_process_id,
-                                    int render_frame_id,
-                                    int stream_id);
-  static void StopMonitoringStream(int render_process_id,
-                                   int render_frame_id,
+  static void StartMonitoringStream(
+      GlobalRenderFrameHostId render_frame_host_id,
+      int stream_id);
+  static void StopMonitoringStream(GlobalRenderFrameHostId render_frame_host_id,
                                    int stream_id);
   // Updates the audible state for the given stream. Safe to call from any
   // thread.
-  static void UpdateStreamAudibleState(int render_process_id,
-                                       int render_frame_id,
-                                       int stream_id,
-                                       bool is_audible);
+  static void UpdateStreamAudibleState(
+      GlobalRenderFrameHostId render_frame_host_id,
+      int stream_id,
+      bool is_audible);
 
   // WebContentsObserver implementation
   void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
@@ -85,19 +85,19 @@
   // Class to help automatically remove audible client.
   class CONTENT_EXPORT AudibleClientRegistration {
    public:
-    AudibleClientRegistration(GlobalRenderFrameHostId host_id,
+    AudibleClientRegistration(GlobalRenderFrameHostId render_frame_host_id,
                               AudioStreamMonitor* audio_stream_monitor);
     ~AudibleClientRegistration();
 
    private:
-    GlobalRenderFrameHostId host_id_;
+    GlobalRenderFrameHostId render_frame_host_id_;
     raw_ptr<AudioStreamMonitor> audio_stream_monitor_;
   };
 
   // Registers an audible client, which will be unregistered when the returned
   // AudibleClientRegistration is released.
   std::unique_ptr<AudibleClientRegistration> RegisterAudibleClient(
-      GlobalRenderFrameHostId host_id);
+      GlobalRenderFrameHostId render_frame_host_id);
 
  private:
   friend class AudioStreamMonitorTest;
@@ -110,8 +110,7 @@
   };
 
   struct CONTENT_EXPORT StreamID {
-    int render_process_id;
-    int render_frame_id;
+    GlobalRenderFrameHostId render_frame_host_id;
     int stream_id;
     bool operator<(const StreamID& other) const;
     bool operator==(const StreamID& other) const;
@@ -133,8 +132,8 @@
   void UpdateStreams();
 
   // Adds/Removes Audible clients.
-  void AddAudibleClient(GlobalRenderFrameHostId host_id);
-  void RemoveAudibleClient(GlobalRenderFrameHostId host_id);
+  void AddAudibleClient(GlobalRenderFrameHostId render_frame_host_id);
+  void RemoveAudibleClient(GlobalRenderFrameHostId render_frame_host_id);
 
   // The WebContents instance to receive indicator toggle notifications. This
   // pointer should be valid for the lifetime of AudioStreamMonitor.
diff --git a/content/browser/media/audio_stream_monitor_unittest.cc b/content/browser/media/audio_stream_monitor_unittest.cc
index ceae3d0..71882d1 100644
--- a/content/browser/media/audio_stream_monitor_unittest.cc
+++ b/content/browser/media/audio_stream_monitor_unittest.cc
@@ -32,12 +32,11 @@
 
 namespace {
 
-const int kRenderProcessId = 1;
-const int kAnotherRenderProcessId = 2;
-const int kStreamId = 3;
-const int kAnotherStreamId = 6;
-const int kRenderFrameId = 4;
-const int kAnotherRenderFrameId = 8;
+const GlobalRenderFrameHostId kRenderFrameHostId = {1, 2};
+const GlobalRenderFrameHostId kRenderFrameHostIdSameProcess = {1, 3};
+const GlobalRenderFrameHostId kRenderFrameHostIdOtherProcess = {4, 5};
+const int kStreamId = 6;
+const int kAnotherStreamId = 7;
 
 // Used to confirm audio indicator state changes occur at the correct times.
 class MockWebContentsDelegate : public WebContentsDelegate {
@@ -79,12 +78,10 @@
     task_environment()->FastForwardBy(delta);
   }
 
-  void ExpectIsMonitoring(int render_process_id,
-                          int render_frame_id,
+  void ExpectIsMonitoring(GlobalRenderFrameHostId render_frame_host_id,
                           int stream_id,
                           bool is_polling) {
-    const AudioStreamMonitor::StreamID key = {render_process_id,
-                                              render_frame_id, stream_id};
+    const AudioStreamMonitor::StreamID key = {render_frame_host_id, stream_id};
     EXPECT_EQ(is_polling,
               monitor_->streams_.find(key) != monitor_->streams_.end());
   }
@@ -139,27 +136,23 @@
     return base::Milliseconds(AudioStreamMonitor::kHoldOnMilliseconds);
   }
 
-  void StartMonitoring(int render_process_id,
-                       int render_frame_id,
+  void StartMonitoring(GlobalRenderFrameHostId render_frame_host_id,
                        int stream_id) {
-    monitor_->StartMonitoringStreamOnUIThread(AudioStreamMonitor::StreamID{
-        render_process_id, render_frame_id, stream_id});
+    monitor_->StartMonitoringStreamOnUIThread(
+        AudioStreamMonitor::StreamID{render_frame_host_id, stream_id});
   }
 
-  void StopMonitoring(int render_process_id,
-                      int render_frame_id,
+  void StopMonitoring(GlobalRenderFrameHostId render_frame_host_id,
                       int stream_id) {
-    monitor_->StopMonitoringStreamOnUIThread(AudioStreamMonitor::StreamID{
-        render_process_id, render_frame_id, stream_id});
+    monitor_->StopMonitoringStreamOnUIThread(
+        AudioStreamMonitor::StreamID{render_frame_host_id, stream_id});
   }
 
-  void UpdateAudibleState(int render_process_id,
-                          int render_frame_id,
+  void UpdateAudibleState(GlobalRenderFrameHostId render_frame_host_id,
                           int stream_id,
                           bool is_audible) {
     monitor_->UpdateStreamAudibleStateOnUIThread(
-        AudioStreamMonitor::StreamID{render_process_id, render_frame_id,
-                                     stream_id},
+        AudioStreamMonitor::StreamID{render_frame_host_id, stream_id},
         is_audible);
   }
 
@@ -188,24 +181,24 @@
 TEST_F(AudioStreamMonitorTest, MonitorsWhenProvidedAStream) {
   EXPECT_FALSE(monitor_->WasRecentlyAudible());
   ExpectNotCurrentlyAudible();
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false);
 
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
   EXPECT_FALSE(monitor_->WasRecentlyAudible());
   ExpectNotCurrentlyAudible();
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true);
 
-  StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
+  StopMonitoring(kRenderFrameHostId, kStreamId);
   EXPECT_FALSE(monitor_->WasRecentlyAudible());
   ExpectNotCurrentlyAudible();
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false);
 }
 
 // Tests that AudioStreamMonitor keeps the indicator on for the holding period
 // even if there is silence during the holding period.
 // See comments in audio_stream_monitor.h for expected behavior.
 TEST_F(AudioStreamMonitorTest, IndicatorIsOnUntilHoldingPeriodHasPassed) {
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
 
   // Expect WebContents will get one call form AudioStreamMonitor to toggle the
   // indicator upon the very first notification that the stream has become
@@ -219,7 +212,7 @@
   do {
     ExpectCurrentlyAudibleChangeNotification(true);
 
-    UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true);
+    UpdateAudibleState(kRenderFrameHostId, kStreamId, true);
     ExpectTabWasRecentlyAudible(true, last_became_silent_time);
     FastForwardBy(one_time_step());
 
@@ -227,7 +220,7 @@
 
     // Notify that the stream has become silent and advance time repeatedly,
     // ensuring that the indicator is being held on during the holding period.
-    UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false);
+    UpdateAudibleState(kRenderFrameHostId, kStreamId, false);
     last_became_silent_time = base::TimeTicks::Now();
     ExpectTabWasRecentlyAudible(true, last_became_silent_time);
     for (int i = 0; i < num_silence_steps; ++i) {
@@ -257,8 +250,8 @@
 // Tests that the AudioStreamMonitor correctly processes updates from two
 // different streams in the same tab.
 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamUpdate) {
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
-  StartMonitoring(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
+  StartMonitoring(kRenderFrameHostIdSameProcess, kAnotherStreamId);
 
   base::TimeTicks last_became_silent_time;
   ExpectTabWasRecentlyAudible(false, last_became_silent_time);
@@ -269,26 +262,23 @@
   ExpectRecentlyAudibleChangeNotification(true);
   ExpectCurrentlyAudibleChangeNotification(true);
 
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true);
-  UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId,
-                     false);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, true);
+  UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false);
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
   ExpectIsCurrentlyAudible();
 
   // Halfway through the holding period, the second stream joins in.  The
   // indicator stays on.
   FastForwardBy(holding_period() / 2);
-  UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId,
-                     true);
+  UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, true);
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
   ExpectIsCurrentlyAudible();
 
   // Now, both streams become silent. The tab becoms silent but the indicator
   // stays on.
   ExpectCurrentlyAudibleChangeNotification(false);
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false);
-  UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId,
-                     false);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, false);
+  UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false);
   last_became_silent_time = base::TimeTicks::Now();
   ExpectNotCurrentlyAudible();
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
@@ -301,7 +291,7 @@
   // The first stream becomes audible again during the holding period.
   // The tab becomes audible and the indicator stays on.
   ExpectCurrentlyAudibleChangeNotification(true);
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, true);
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
   ExpectIsCurrentlyAudible();
 
@@ -314,7 +304,7 @@
   // The first stream becomes silent again. The tab becomes silent and the
   // indicator is still on.
   ExpectCurrentlyAudibleChangeNotification(false);
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, false);
   last_became_silent_time = base::TimeTicks::Now();
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
   ExpectNotCurrentlyAudible();
@@ -329,16 +319,14 @@
   // The tab becomes audible again.
   ExpectRecentlyAudibleChangeNotification(true);
   ExpectCurrentlyAudibleChangeNotification(true);
-  UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId,
-                     true);
+  UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, true);
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
   ExpectIsCurrentlyAudible();
 
   // From here onwards, both streams are silent.  Halfway through the holding
   // period, the tab is no longer audible but stays as recently audible.
   ExpectCurrentlyAudibleChangeNotification(false);
-  UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId,
-                     false);
+  UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false);
   last_became_silent_time = base::TimeTicks::Now();
   FastForwardBy(holding_period() / 2);
   ExpectTabWasRecentlyAudible(true, last_became_silent_time);
@@ -362,39 +350,39 @@
 }
 
 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) {
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
-  StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId);
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true);
-  StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId);
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
+  StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true);
+  StopMonitoring(kRenderFrameHostIdOtherProcess, kStreamId);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, false);
 }
 
 TEST_F(AudioStreamMonitorTest, RenderProcessGone) {
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
-  StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId);
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true);
-  monitor_->RenderProcessGone(kRenderProcessId);
-  ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false);
-  monitor_->RenderProcessGone(kAnotherRenderProcessId);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
+  StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true);
+  monitor_->RenderProcessGone(kRenderFrameHostId.child_id);
+  ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false);
+  monitor_->RenderProcessGone(kRenderFrameHostIdOtherProcess.child_id);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, false);
 }
 
 TEST_F(AudioStreamMonitorTest, RenderFrameGone) {
   RenderFrameHost* render_frame_host = web_contents()->GetPrimaryMainFrame();
-  int render_process_id = render_frame_host->GetProcess()->GetID();
-  int render_frame_id = render_frame_host->GetRoutingID();
+  GlobalRenderFrameHostId render_frame_host_id =
+      render_frame_host->GetGlobalId();
 
-  StartMonitoring(render_process_id, render_frame_id, kStreamId);
-  StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId);
-  ExpectIsMonitoring(render_process_id, render_frame_id, kStreamId, true);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true);
+  StartMonitoring(render_frame_host_id, kStreamId);
+  StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId);
+  ExpectIsMonitoring(render_frame_host_id, kStreamId, true);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true);
 
   monitor_->RenderFrameDeleted(render_frame_host);
-  ExpectIsMonitoring(render_process_id, render_frame_id, kStreamId, false);
-  ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true);
+  ExpectIsMonitoring(render_frame_host_id, kStreamId, false);
+  ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true);
 }
 
 TEST_F(AudioStreamMonitorTest, OneAudibleClient) {
@@ -480,7 +468,7 @@
 }
 
 TEST_F(AudioStreamMonitorTest, AudibleClientAndStream) {
-  StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId);
+  StartMonitoring(kRenderFrameHostId, kStreamId);
   ExpectNotCurrentlyAudible();
 
   auto* render_frame_host_impl =
@@ -494,7 +482,7 @@
   ExpectIsCurrentlyAudible();
 
   // The stream becomes audible and the tab remains audible.
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, true);
   ExpectIsCurrentlyAudible();
 
   // Remove the client and the tab remains audible.
@@ -503,7 +491,7 @@
 
   // The stream becomes not audible and the tab is not audible.
   ExpectCurrentlyAudibleChangeNotification(false);
-  UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false);
+  UpdateAudibleState(kRenderFrameHostId, kStreamId, false);
   ExpectNotCurrentlyAudible();
 }
 
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.h b/content/browser/renderer_host/media/audio_input_device_manager.h
index 810862505..06bc725 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager.h
+++ b/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -76,7 +76,7 @@
   base::ObserverList<MediaStreamProviderListener>::Unchecked listeners_;
   blink::MediaStreamDevices devices_;
 
-  const raw_ptr<media::AudioSystem, DanglingUntriaged> audio_system_;
+  const raw_ptr<media::AudioSystem> audio_system_;
 };
 
 }  // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc b/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc
index 84fca22..3fe40c6 100644
--- a/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc
+++ b/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc
@@ -13,8 +13,7 @@
     int render_process_id,
     int render_frame_id,
     int stream_id)
-    : render_process_id_(render_process_id),
-      render_frame_id_(render_frame_id),
+    : render_frame_host_id_(render_process_id, render_frame_id),
       stream_id_(stream_id) {}
 
 AudioOutputStreamObserverImpl::~AudioOutputStreamObserverImpl() {
@@ -26,20 +25,18 @@
 void AudioOutputStreamObserverImpl::DidStartPlaying() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   did_start_playing_ = true;
-  AudioStreamMonitor::StartMonitoringStream(render_process_id_,
-                                            render_frame_id_, stream_id_);
+  AudioStreamMonitor::StartMonitoringStream(render_frame_host_id_, stream_id_);
 }
 void AudioOutputStreamObserverImpl::DidStopPlaying() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AudioStreamMonitor::StopMonitoringStream(render_process_id_, render_frame_id_,
-                                           stream_id_);
+  AudioStreamMonitor::StopMonitoringStream(render_frame_host_id_, stream_id_);
   did_start_playing_ = false;
 }
 
 void AudioOutputStreamObserverImpl::DidChangeAudibleState(bool is_audible) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AudioStreamMonitor::UpdateStreamAudibleState(
-      render_process_id_, render_frame_id_, stream_id_, is_audible);
+  AudioStreamMonitor::UpdateStreamAudibleState(render_frame_host_id_,
+                                               stream_id_, is_audible);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_stream_observer_impl.h b/content/browser/renderer_host/media/audio_output_stream_observer_impl.h
index 23f2be6c..7d5ba5e 100644
--- a/content/browser/renderer_host/media/audio_output_stream_observer_impl.h
+++ b/content/browser/renderer_host/media/audio_output_stream_observer_impl.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_STREAM_OBSERVER_IMPL_H_
 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_STREAM_OBSERVER_IMPL_H_
 
+#include "content/public/browser/global_routing_id.h"
 #include "media/mojo/mojom/audio_output_stream.mojom.h"
 
 namespace content {
@@ -28,8 +29,7 @@
   void DidChangeAudibleState(bool is_audible) override;
 
  private:
-  const int render_process_id_;
-  const int render_frame_id_;
+  const GlobalRenderFrameHostId render_frame_host_id_;
   const int stream_id_;
   bool did_start_playing_ = false;
 
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
index 670c3ae..47ce896 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
@@ -520,6 +520,9 @@
     render_frame_host_ = web_contents_->GetPrimaryMainFrame();
   }
 
+  std::unique_ptr<media::AudioManager> audio_manager_;
+  std::unique_ptr<media::AudioSystem> audio_system_;
+
   // The order of these members is important on teardown:
   // MediaDevicesDispatcherHost expects to be destroyed on the IO thread while
   // MediaStreamManager expects to be destroyed after the IO thread has been
@@ -528,8 +531,6 @@
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<MediaDevicesDispatcherHost> host_;
 
-  std::unique_ptr<media::AudioManager> audio_manager_;
-  std::unique_ptr<media::AudioSystem> audio_system_;
   raw_ptr<media::FakeVideoCaptureDeviceFactory> video_capture_device_factory_;
   MediaDeviceEnumeration physical_devices_;
   url::Origin origin_;
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index ea9df560..3cf2a25 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -566,9 +566,9 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<MockMediaStreamDispatcherHost> host_;
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
-  BrowserTaskEnvironment task_environment_;
   std::unique_ptr<media::AudioManager> audio_manager_;
   std::unique_ptr<media::AudioSystem> audio_system_;
+  BrowserTaskEnvironment task_environment_;
   MediaDeviceSaltAndOrigin salt_and_origin_;
   media::AudioDeviceDescriptions audio_device_descriptions_;
   std::vector<std::string> stub_video_device_ids_;
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 6c43006..db1b35d 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -704,6 +704,9 @@
     return audio_device;
   }
 
+  std::unique_ptr<MockAudioManager> audio_manager_;
+  std::unique_ptr<media::AudioSystem> audio_system_;
+
   // media_stream_manager_ needs to outlive task_environment_ because it is a
   // CurrentThread::DestructionObserver. audio_manager_ needs to outlive
   // task_environment_ because it uses the underlying message loop.
@@ -715,8 +718,6 @@
   chromeos::ScopedLacrosServiceTestHelper lacros_service_test_helper_;
   mojo::Receiver<crosapi::mojom::MultiCaptureService> receiver_;
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-  std::unique_ptr<MockAudioManager> audio_manager_;
-  std::unique_ptr<media::AudioSystem> audio_system_;
   raw_ptr<MockVideoCaptureProvider> video_capture_provider_;
   std::unique_ptr<MediaStreamProviderListenerMock> stream_provider_listener_;
   size_t screen_count_ = 0;
diff --git a/content/browser/renderer_host/media/video_capture_unittest.cc b/content/browser/renderer_host/media/video_capture_unittest.cc
index 1182caf..52595eef 100644
--- a/content/browser/renderer_host/media/video_capture_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_unittest.cc
@@ -95,10 +95,6 @@
  public:
   VideoCaptureTest()
       : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
-        audio_manager_(std::make_unique<media::MockAudioManager>(
-            std::make_unique<media::TestAudioThread>())),
-        audio_system_(
-            std::make_unique<media::AudioSystemImpl>(audio_manager_.get())),
         task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {}
 
   VideoCaptureTest(const VideoCaptureTest&) = delete;
@@ -108,6 +104,10 @@
 
   void SetUp() override {
     SetBrowserClientForTesting(&browser_client_);
+    audio_manager_ = std::make_unique<media::MockAudioManager>(
+        std::make_unique<media::TestAudioThread>());
+    audio_system_ =
+        std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
 
     media_stream_manager_ = std::make_unique<MediaStreamManager>(
         audio_system_.get(), std::make_unique<FakeVideoCaptureProvider>());
@@ -351,12 +351,13 @@
     std::move(quit_closure).Run();
   }
 
+  std::unique_ptr<media::AudioManager> audio_manager_;
+  std::unique_ptr<media::AudioSystem> audio_system_;
+
   // |media_stream_manager_| needs to outlive |task_environment_| because it is
   // a CurrentThread::DestructionObserver.
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
   const content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
-  std::unique_ptr<media::AudioSystem> audio_system_;
   content::TestBrowserContext browser_context_;
   content::TestContentBrowserClient browser_client_;
   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 385789fb..86c6ef03 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2773,15 +2773,12 @@
       break;
     frame = frame->GetParent();
   }
-  if (!frame)
+  if (!frame) {
     return PageVisibilityState::kHidden;
+  }
 
-  PageVisibilityState visibility_state = GetRenderWidgetHost()->is_hidden()
-                                             ? PageVisibilityState::kHidden
-                                             : PageVisibilityState::kVisible;
-  GetContentClient()->browser()->OverridePageVisibilityState(this,
-                                                             &visibility_state);
-  return visibility_state;
+  return GetRenderWidgetHost()->is_hidden() ? PageVisibilityState::kHidden
+                                            : PageVisibilityState::kVisible;
 }
 
 bool RenderFrameHostImpl::Send(IPC::Message* message) {
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 89b2604..ec15b9a6 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -145,39 +145,6 @@
 namespace content {
 namespace {
 
-// Implementation of ContentBrowserClient that overrides
-// OverridePageVisibilityState() and allows consumers to set a value.
-class PrerenderTestContentBrowserClient
-    : public ContentBrowserTestContentBrowserClient {
- public:
-  PrerenderTestContentBrowserClient()
-      : override_enabled_(false),
-        visibility_override_(PageVisibilityState::kVisible) {}
-
-  PrerenderTestContentBrowserClient(const PrerenderTestContentBrowserClient&) =
-      delete;
-  PrerenderTestContentBrowserClient& operator=(
-      const PrerenderTestContentBrowserClient&) = delete;
-
-  ~PrerenderTestContentBrowserClient() override {}
-
-  void EnableVisibilityOverride(PageVisibilityState visibility_override) {
-    override_enabled_ = true;
-    visibility_override_ = visibility_override;
-  }
-
-  void OverridePageVisibilityState(
-      RenderFrameHost* render_frame_host,
-      PageVisibilityState* visibility_state) override {
-    if (override_enabled_)
-      *visibility_state = visibility_override_;
-  }
-
- private:
-  bool override_enabled_;
-  PageVisibilityState visibility_override_;
-};
-
 const char kTrustMeUrl[] = "trustme://host/path/";
 const char kTrustMeIfEmbeddingSecureUrl[] =
     "trustmeifembeddingsecure://host/path/";
@@ -484,22 +451,6 @@
             web_contents()->GetPrimaryMainFrame()->GetVisibilityState());
 }
 
-// Test that a frame visibility can be overridden by the ContentBrowserClient.
-IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
-                       GetVisibilityState_Override) {
-  EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo")));
-
-  PrerenderTestContentBrowserClient new_client;
-
-  web_contents()->WasShown();
-  EXPECT_EQ(PageVisibilityState::kVisible,
-            web_contents()->GetPrimaryMainFrame()->GetVisibilityState());
-
-  new_client.EnableVisibilityOverride(PageVisibilityState::kHiddenButPainting);
-  EXPECT_EQ(PageVisibilityState::kHiddenButPainting,
-            web_contents()->GetPrimaryMainFrame()->GetVisibilityState());
-}
-
 // Check that the URLLoaderFactories created by RenderFrameHosts for renderers
 // are not trusted.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 966f79ab..2549daa 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1445,12 +1445,6 @@
       RenderProcessHost* render_process_host,
       mojo::GenericPendingReceiver receiver) {}
 
-  // Allows to override the visibility state of a RenderFrameHost.
-  // |visibility_state| should not be null. It will only be set if needed.
-  virtual void OverridePageVisibilityState(
-      RenderFrameHost* render_frame_host,
-      PageVisibilityState* visibility_state) {}
-
   // Allows an embedder to provide its own ControllerPresentationServiceDelegate
   // implementation. Returns nullptr if unavailable.
   virtual ControllerPresentationServiceDelegate*
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn
index 931b2b2d..b2a85244 100644
--- a/google_apis/BUILD.gn
+++ b/google_apis/BUILD.gn
@@ -316,6 +316,7 @@
 bundle_data("google_apis_unittest_bundle_data") {
   testonly = true
   sources = [
+    "test/data/calendar/calendar_list.json",
     "test/data/calendar/event_self_response_statuses.json",
     "test/data/calendar/event_statuses.json",
     "test/data/calendar/event_with_invalid_conference_data_uri.json",
diff --git a/google_apis/calendar/calendar_api_requests.cc b/google_apis/calendar/calendar_api_requests.cc
index 2bef026..74fb64e 100644
--- a/google_apis/calendar/calendar_api_requests.cc
+++ b/google_apis/calendar/calendar_api_requests.cc
@@ -6,7 +6,14 @@
 
 #include <stddef.h>
 
+#include <memory>
+#include <utility>
+
+#include "base/memory/weak_ptr.h"
 #include "base/values.h"
+#include "google_apis/common/api_error_codes.h"
+#include "google_apis/common/base_requests.h"
+#include "google_apis/common/request_sender.h"
 #include "net/base/url_util.h"
 
 namespace google_apis {
@@ -20,6 +27,11 @@
 // should return the participant/requester only as an attendee.
 constexpr int kMaxAttendees = 1;
 
+// Requested maximum number of calendars returned. The default value is 100.
+// Although the events shown to the user will be limited to a fixed number
+// of selected calendars, it is best to be thorough here and filter later.
+constexpr int kMaxCalendars = 250;
+
 // Requested number of events returned on one result page.
 // The default value on the Calendar API side is 250 events per page and some
 // users have >250 events per month.
@@ -30,6 +42,7 @@
 // response.
 constexpr int kMaxResults = 2500;
 
+// Requested fields to be returned in the Event list result.
 constexpr char kCalendarEventListFields[] =
     "timeZone,etag,kind,items(id,kind,summary,colorId,"
     "status,start(date),end(date),start(dateTime),end(dateTime),htmlLink,"
@@ -37,6 +50,10 @@
     "conferenceData(conferenceId,entryPoints(entryPointType,uri)),"
     "creator(self))";
 
+// Requested fields to be returned in the CalendarList result.
+constexpr char kCalendarListFields[] =
+    "etag,kind,items(id,colorId,selected,primary)";
+
 CalendarApiGetRequest::CalendarApiGetRequest(RequestSender* sender,
                                              const std::string& fields)
     : UrlFetchRequestBase(sender, ProgressCallback(), ProgressCallback()),
@@ -71,6 +88,66 @@
   return IsSuccessfulCalendarApiErrorCode(error);
 }
 
+CalendarApiCalendarListRequest::CalendarApiCalendarListRequest(
+    RequestSender* sender,
+    const CalendarApiUrlGenerator& url_generator,
+    CalendarListCallback callback)
+    : CalendarApiGetRequest(sender, kCalendarListFields),
+      callback_(std::move(callback)),
+      url_generator_(url_generator) {
+  CHECK(!callback_.is_null());
+}
+
+CalendarApiCalendarListRequest::~CalendarApiCalendarListRequest() = default;
+
+GURL CalendarApiCalendarListRequest::GetURLInternal() const {
+  return url_generator_.GetCalendarListUrl(/*max_results=*/kMaxCalendars);
+}
+
+void CalendarApiCalendarListRequest::ProcessURLFetchResults(
+    const network::mojom::URLResponseHead* response_head,
+    base::FilePath response_file,
+    std::string response_body) {
+  ApiErrorCode error = GetErrorCode();
+  switch (error) {
+    case HTTP_SUCCESS:
+      blocking_task_runner()->PostTaskAndReplyWithResult(
+          FROM_HERE,
+          base::BindOnce(&CalendarApiCalendarListRequest::Parse,
+                         std::move(response_body)),
+          base::BindOnce(&CalendarApiCalendarListRequest::OnDataParsed,
+                         weak_ptr_factory_.GetWeakPtr(), error));
+      break;
+    default:
+      RunCallbackOnPrematureFailure(error);
+      OnProcessURLFetchResultsComplete();
+      break;
+  }
+}
+
+void CalendarApiCalendarListRequest::RunCallbackOnPrematureFailure(
+    ApiErrorCode error) {
+  std::move(callback_).Run(error, std::unique_ptr<CalendarList>());
+}
+
+// static
+std::unique_ptr<CalendarList> CalendarApiCalendarListRequest::Parse(
+    std::string json) {
+  std::unique_ptr<base::Value> value = ParseJson(json);
+
+  return value ? CalendarList::CreateFrom(*value) : nullptr;
+}
+
+void CalendarApiCalendarListRequest::OnDataParsed(
+    ApiErrorCode error,
+    std::unique_ptr<CalendarList> calendars) {
+  if (!calendars) {
+    error = PARSE_ERROR;
+  }
+  std::move(callback_).Run(error, std::move(calendars));
+  OnProcessURLFetchResultsComplete();
+}
+
 CalendarApiEventsRequest::CalendarApiEventsRequest(
     RequestSender* sender,
     const CalendarApiUrlGenerator& url_generator,
@@ -82,7 +159,7 @@
       url_generator_(url_generator),
       start_time_(start_time),
       end_time_(end_time) {
-  DCHECK(!callback_.is_null());
+  CHECK(!callback_.is_null());
 }
 
 CalendarApiEventsRequest::~CalendarApiEventsRequest() = default;
@@ -115,14 +192,6 @@
   }
 }
 
-void CalendarApiEventsRequest::OnDataParsed(ApiErrorCode error,
-                                            std::unique_ptr<EventList> events) {
-  if (!events)
-    error = PARSE_ERROR;
-  std::move(callback_).Run(error, std::move(events));
-  OnProcessURLFetchResultsComplete();
-}
-
 void CalendarApiEventsRequest::RunCallbackOnPrematureFailure(
     ApiErrorCode error) {
   std::move(callback_).Run(error, std::unique_ptr<EventList>());
@@ -135,5 +204,14 @@
   return value ? EventList::CreateFrom(*value) : nullptr;
 }
 
+void CalendarApiEventsRequest::OnDataParsed(ApiErrorCode error,
+                                            std::unique_ptr<EventList> events) {
+  if (!events) {
+    error = PARSE_ERROR;
+  }
+  std::move(callback_).Run(error, std::move(events));
+  OnProcessURLFetchResultsComplete();
+}
+
 }  // namespace calendar
 }  // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_requests.h b/google_apis/calendar/calendar_api_requests.h
index 99e7c31..fff3793 100644
--- a/google_apis/calendar/calendar_api_requests.h
+++ b/google_apis/calendar/calendar_api_requests.h
@@ -5,6 +5,9 @@
 #ifndef GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_
 #define GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_
 
+#include <memory>
+
+#include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "google_apis/calendar/calendar_api_response_types.h"
 #include "google_apis/calendar/calendar_api_url_generator.h"
@@ -15,6 +18,12 @@
 
 namespace calendar {
 
+// Callback used for requests that the server returns Calendar List
+// data formatted into JSON value.
+using CalendarListCallback =
+    base::OnceCallback<void(ApiErrorCode error,
+                            std::unique_ptr<CalendarList> calendars)>;
+
 // Callback used for requests that the server returns Events data
 // formatted into JSON value.
 using CalendarEventListCallback =
@@ -49,6 +58,46 @@
   std::string fields_;
 };
 
+// Request to fetch the list of the user's calendars.
+class CalendarApiCalendarListRequest : public CalendarApiGetRequest {
+ public:
+  CalendarApiCalendarListRequest(RequestSender* sender,
+                                 const CalendarApiUrlGenerator& url_generator,
+                                 CalendarListCallback callback);
+  CalendarApiCalendarListRequest(const CalendarApiCalendarListRequest&) =
+      delete;
+  CalendarApiCalendarListRequest& operator=(
+      const CalendarApiCalendarListRequest&) = delete;
+  ~CalendarApiCalendarListRequest() override;
+
+ protected:
+  // CalendarApiGetRequest:
+  GURL GetURLInternal() const override;
+
+  // UrlFetchRequestBase:
+  void ProcessURLFetchResults(
+      const network::mojom::URLResponseHead* response_head,
+      base::FilePath response_file,
+      std::string response_body) override;
+
+  void RunCallbackOnPrematureFailure(ApiErrorCode code) override;
+
+ private:
+  // Parses the Calendar List result to a CalendarList.
+  static std::unique_ptr<CalendarList> Parse(std::string json);
+
+  // Receives the parsed calendar list and invokes the callback.
+  void OnDataParsed(ApiErrorCode error,
+                    std::unique_ptr<CalendarList> calendars);
+
+  CalendarListCallback callback_;
+  const CalendarApiUrlGenerator url_generator_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<CalendarApiCalendarListRequest> weak_ptr_factory_{this};
+};
+
 // Request to fetch calendar events.
 class CalendarApiEventsRequest : public CalendarApiGetRequest {
  public:
@@ -68,7 +117,7 @@
   // UrlFetchRequestBase:
   void ProcessURLFetchResults(
       const network::mojom::URLResponseHead* response_head,
-      const base::FilePath response_file,
+      base::FilePath response_file,
       std::string response_body) override;
 
   void RunCallbackOnPrematureFailure(ApiErrorCode code) override;
diff --git a/google_apis/calendar/calendar_api_requests_unittest.cc b/google_apis/calendar/calendar_api_requests_unittest.cc
index f803cea..c18918d8 100644
--- a/google_apis/calendar/calendar_api_requests_unittest.cc
+++ b/google_apis/calendar/calendar_api_requests_unittest.cc
@@ -14,6 +14,7 @@
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/test/test_shared_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -64,19 +65,59 @@
       test_shared_loader_factory_;
   net::test_server::HttpRequest http_request_;
 
-  // Returns the mock calendar event list.
+  // Returns a mock response based on the request URL.
   std::unique_ptr<net::test_server::HttpResponse> HandleDataFileRequest(
       const net::test_server::HttpRequest& request) {
     http_request_ = request;
 
-    // Return the response from the event json file.
-    return test_util::CreateHttpResponseFromFile(
-        test_util::GetTestFilePath("calendar/events.json"));
+    if (net::test_server::ShouldHandle(
+            http_request_, "/calendar/v3/calendars/primary/events")) {
+      return test_util::CreateHttpResponseFromFile(
+          test_util::GetTestFilePath("calendar/events.json"));
+    }
+    if (net::test_server::ShouldHandle(http_request_,
+                                       "/calendar/v3/users/me/calendarList")) {
+      return test_util::CreateHttpResponseFromFile(
+          test_util::GetTestFilePath("calendar/calendar_list.json"));
+    }
+    NOTREACHED_NORETURN();
   }
 };
 
-// Tests the CalendarApiRequestsTest can generate the correct url and get the
-// correct response.
+// Checks that CalendarApiCalendarListRequest can generate the correct url
+// and get a calendar list response.
+TEST_F(CalendarApiRequestsTest, GetCalendarListRequest) {
+  ApiErrorCode error = OTHER_ERROR;
+  std::unique_ptr<CalendarList> calendars;
+
+  {
+    base::RunLoop run_loop;
+    auto request = std::make_unique<CalendarApiCalendarListRequest>(
+        request_sender_.get(), *url_generator_,
+        test_util::CreateQuitCallback(
+            &run_loop,
+            test_util::CreateCopyResultCallback(&error, &calendars)));
+
+    request_sender_->StartRequestWithAuthRetry(std::move(request));
+    run_loop.Run();
+  }
+
+  EXPECT_EQ(HTTP_SUCCESS, error);
+  EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
+  EXPECT_EQ(
+      "/calendar/v3/users/me/calendarList"
+      "?maxResults=250"
+      "&fields=etag%2Ckind%2Citems(id%2CcolorId%2Cselected%2Cprimary)",
+      http_request_.relative_url);
+
+  ASSERT_TRUE(calendars.get());
+  EXPECT_EQ("calendar#calendarList", calendars->kind());
+  EXPECT_EQ(true, calendars->items()[0]->selected());
+  EXPECT_EQ(true, calendars->items()[0]->primary());
+}
+
+// Tests that CalendarApiEventsRequest can generate the correct url and get the
+// correct event list response.
 TEST_F(CalendarApiRequestsTest, GetEventListRequest) {
   ApiErrorCode error = OTHER_ERROR;
   std::unique_ptr<EventList> events;
diff --git a/google_apis/calendar/calendar_api_response_types.cc b/google_apis/calendar/calendar_api_response_types.cc
index 786f58b..bff261a 100644
--- a/google_apis/calendar/calendar_api_response_types.cc
+++ b/google_apis/calendar/calendar_api_response_types.cc
@@ -27,6 +27,14 @@
 namespace calendar {
 
 namespace {
+// CalendarList
+constexpr char kCalendarListKind[] = "calendar#calendarList";
+
+// SingleCalendar
+constexpr char kCalendarColorId[] = "colorId";
+constexpr char kPrimary[] = "primary";
+constexpr char kSelected[] = "selected";
+constexpr char kSingleCalendarKind[] = "calendar#calendarListEntry";
 
 // EventList
 constexpr char kCalendarEventListKind[] = "calendar#events";
@@ -221,6 +229,18 @@
   return result;
 }
 
+bool ConvertCalendarListResponseItems(const base::Value* value,
+                                      SingleCalendar* calendar) {
+  base::JSONValueConverter<SingleCalendar> converter;
+
+  if (!IsResourceKindExpected(*value, kSingleCalendarKind) ||
+      !converter.Convert(*value, calendar)) {
+    DVLOG(1) << "Unable to create: Invalid calendarListEntry JSON!";
+    return false;
+  }
+  return true;
+}
+
 }  // namespace
 
 DateTime::DateTime() = default;
@@ -320,5 +340,65 @@
   items_.push_back(std::move(item));
 }
 
+SingleCalendar::SingleCalendar() = default;
+
+SingleCalendar::~SingleCalendar() = default;
+
+SingleCalendar::SingleCalendar(const SingleCalendar&) = default;
+
+SingleCalendar& SingleCalendar::operator=(const SingleCalendar&) = default;
+
+// static
+void SingleCalendar::RegisterJSONConverter(
+    base::JSONValueConverter<SingleCalendar>* converter) {
+  converter->RegisterStringField(kApiResponseIdKey, &SingleCalendar::id_);
+  converter->RegisterStringField(kCalendarColorId, &SingleCalendar::color_id_);
+  converter->RegisterBoolField(kPrimary, &SingleCalendar::primary_);
+  converter->RegisterBoolField(kSelected, &SingleCalendar::selected_);
+}
+
+int SingleCalendar::GetApproximateSizeInBytes() const {
+  int total_bytes = 0;
+
+  total_bytes += sizeof(SingleCalendar);
+  total_bytes += id_.length();
+  total_bytes += color_id_.length();
+  total_bytes += sizeof(primary_);
+  total_bytes += sizeof(selected_);
+
+  return total_bytes;
+}
+
+CalendarList::CalendarList() = default;
+
+CalendarList::~CalendarList() = default;
+
+// static
+void CalendarList::RegisterJSONConverter(
+    base::JSONValueConverter<CalendarList>* converter) {
+  converter->RegisterStringField(kApiResponseETagKey, &CalendarList::etag_);
+  converter->RegisterStringField(kApiResponseKindKey, &CalendarList::kind_);
+  converter->RegisterRepeatedCustomValue<SingleCalendar>(
+      kApiResponseItemsKey, &CalendarList::items_,
+      &ConvertCalendarListResponseItems);
+}
+
+// static
+std::unique_ptr<CalendarList> CalendarList::CreateFrom(
+    const base::Value& value) {
+  auto calendars = std::make_unique<CalendarList>();
+  base::JSONValueConverter<CalendarList> converter;
+  if (!IsResourceKindExpected(value, kCalendarListKind) ||
+      !converter.Convert(value, calendars.get())) {
+    DVLOG(1) << "Unable to create: Invalid CalendarList JSON!";
+    return nullptr;
+  }
+  return calendars;
+}
+
+void CalendarList::InjectItemForTesting(std::unique_ptr<SingleCalendar> item) {
+  items_.push_back(std::move(item));
+}
+
 }  // namespace calendar
 }  // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_response_types.h b/google_apis/calendar/calendar_api_response_types.h
index dbe1f4b..bcde83a 100644
--- a/google_apis/calendar/calendar_api_response_types.h
+++ b/google_apis/calendar/calendar_api_response_types.h
@@ -28,6 +28,87 @@
 
 namespace calendar {
 
+// Parses a calendar list item from the response.
+class SingleCalendar {
+ public:
+  SingleCalendar();
+  SingleCalendar(const SingleCalendar&);
+  SingleCalendar& operator=(const SingleCalendar&);
+  ~SingleCalendar();
+
+  // Registers the mapping between JSON field names and the members in this
+  // class.
+  static void RegisterJSONConverter(
+      base::JSONValueConverter<SingleCalendar>* converter);
+
+  // The Calendar ID
+  const std::string& id() const { return id_; }
+  void set_id(const std::string& id) { id_ = id; }
+
+  // The color ID of the calendar
+  const std::string& color_id() const { return color_id_; }
+  void set_color_id(const std::string& color_id) { color_id_ = color_id; }
+
+  // Indicates whether or not the calendar is selected.
+  bool selected() const { return selected_; }
+  void set_selected(bool selected) { selected_ = selected; }
+
+  // Indicates whether or not the calendar is the primary calendar.
+  bool primary() const { return primary_; }
+  void set_primary(bool primary) { primary_ = primary; }
+
+  // Return the approximate size of this calendar list item in bytes.
+  int GetApproximateSizeInBytes() const;
+
+ private:
+  std::string id_;
+  std::string color_id_;
+  bool selected_ = false;
+  bool primary_ = false;
+};
+
+// Parses a list of calendars.
+class CalendarList {
+ public:
+  CalendarList();
+  CalendarList(const CalendarList&) = delete;
+  CalendarList& operator=(const CalendarList&) = delete;
+  ~CalendarList();
+
+  // Registers the mapping between JSON field names and the members in this
+  // class.
+  static void RegisterJSONConverter(
+      base::JSONValueConverter<CalendarList>* converter);
+
+  // Creates CalendarList from parsed JSON.
+  static std::unique_ptr<CalendarList> CreateFrom(const base::Value& value);
+
+  // Returns ETag for this calendar list.
+  const std::string& etag() const { return etag_; }
+
+  // Returns the kind.
+  const std::string& kind() const { return kind_; }
+
+  void set_etag(const std::string& etag) { etag_ = etag; }
+  void set_kind(const std::string& kind) { kind_ = kind; }
+
+  // Returns a set of calendars.
+  const std::vector<std::unique_ptr<SingleCalendar>>& items() const {
+    return items_;
+  }
+  std::vector<std::unique_ptr<SingleCalendar>>* mutable_items() {
+    return &items_;
+  }
+
+  void InjectItemForTesting(std::unique_ptr<SingleCalendar> item);
+
+ private:
+  std::string etag_;
+  std::string kind_;
+
+  std::vector<std::unique_ptr<SingleCalendar>> items_;
+};
+
 // Parses the time field in the calendar Events.list response.
 class DateTime {
  public:
diff --git a/google_apis/calendar/calendar_api_response_types_unittest.cc b/google_apis/calendar/calendar_api_response_types_unittest.cc
index 7e6d934..0d04d82 100644
--- a/google_apis/calendar/calendar_api_response_types_unittest.cc
+++ b/google_apis/calendar/calendar_api_response_types_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "google_apis/calendar/calendar_api_response_types.h"
 
+#include <memory>
+
 #include "base/time/time.h"
 #include "base/values.h"
 #include "google_apis/common/test_util.h"
@@ -13,13 +15,73 @@
 
 namespace calendar {
 
+TEST(CalendarAPIResponseTypesTest, ParseCalendarList) {
+  std::unique_ptr<base::Value> calendars =
+      test_util::LoadJSONFile("calendar/calendar_list.json");
+  ASSERT_TRUE(calendars.get());
+
+  ASSERT_EQ(base::Value::Type::DICT, calendars->type());
+  std::unique_ptr<CalendarList> calendar_list =
+      CalendarList::CreateFrom(*calendars);
+
+  EXPECT_EQ("\"p32gqbiyrr257ya1\"", calendar_list->etag());
+  EXPECT_EQ("calendar#calendarList", calendar_list->kind());
+  EXPECT_EQ(3U, calendar_list->items().size());
+
+  const SingleCalendar& calendar = *calendar_list->items()[0];
+  EXPECT_EQ(calendar.id(), "test1@google.com");
+  EXPECT_EQ(calendar.color_id(), "14");
+  EXPECT_TRUE(calendar.selected());
+  EXPECT_TRUE(calendar.primary());
+}
+
+// Checks that calendar list entries with a missing 'selected' parameter
+// are parsed to have a selected member equal to false.
+TEST(CalendarAPIResponseTypesTest, ParseCalendarListWithUnselectedEntry) {
+  std::unique_ptr<base::Value> calendars =
+      test_util::LoadJSONFile("calendar/calendar_list.json");
+  ASSERT_TRUE(calendars.get());
+
+  ASSERT_EQ(base::Value::Type::DICT, calendars->type());
+  std::unique_ptr<CalendarList> calendar_list =
+      CalendarList::CreateFrom(*calendars);
+
+  EXPECT_EQ(3U, calendar_list->items().size());
+
+  const SingleCalendar& calendar = *calendar_list->items()[1];
+  EXPECT_EQ(calendar.id(),
+            "google.com_zu35dc5syt5k0fddetqqfggb75test@"
+            "group.calendar.google.com");
+  EXPECT_FALSE(calendar.selected());
+}
+
+// Checks that calendar list entries with a missing 'primary' parameter
+// are parsed to have a primary member equal to false.
+TEST(CalendarAPIResponseTypesTest, ParseCalendarListWithNonPrimaryEntry) {
+  std::unique_ptr<base::Value> calendars =
+      test_util::LoadJSONFile("calendar/calendar_list.json");
+  ASSERT_TRUE(calendars.get());
+
+  ASSERT_EQ(base::Value::Type::DICT, calendars->type());
+  std::unique_ptr<CalendarList> calendar_list =
+      CalendarList::CreateFrom(*calendars);
+
+  EXPECT_EQ(3U, calendar_list->items().size());
+
+  const SingleCalendar& calendar = *calendar_list->items()[2];
+  EXPECT_EQ(calendar.id(),
+            "google.com_3edk4wi2oio66fu9l9zh19zsw9test@"
+            "group.calendar.google.com");
+  EXPECT_FALSE(calendar.primary());
+}
+
 TEST(CalendarAPIResponseTypesTest, ParseEventList) {
   std::unique_ptr<base::Value> events =
       test_util::LoadJSONFile("calendar/events.json");
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ("America/Los_Angeles", event_list->time_zone());
   EXPECT_EQ("calendar#events", event_list->kind());
@@ -53,7 +115,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(3U, event_list->items().size());
 
@@ -67,7 +129,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(4U, event_list->items().size());
 
@@ -82,7 +144,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(1U, event_list->items().size());
 
@@ -95,7 +157,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(1U, event_list->items().size());
 
@@ -108,7 +170,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(4U, event_list->items().size());
 
@@ -129,7 +191,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
 
   EXPECT_EQ(8U, event_list->items().size());
 
@@ -157,7 +219,7 @@
   ASSERT_TRUE(events.get());
 
   ASSERT_EQ(base::Value::Type::DICT, events->type());
-  auto event_list = EventList::CreateFrom(*events);
+  std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events);
   ASSERT_EQ(event_list, nullptr);
 }
 }  // namespace calendar
diff --git a/google_apis/calendar/calendar_api_url_generator.cc b/google_apis/calendar/calendar_api_url_generator.cc
index 20a78cb..3b09e772 100644
--- a/google_apis/calendar/calendar_api_url_generator.cc
+++ b/google_apis/calendar/calendar_api_url_generator.cc
@@ -18,6 +18,8 @@
 // Hard coded URLs for communication with a google calendar server.
 constexpr char kCalendarV3ColorUrl[] = "calendar/v3/colors";
 constexpr char kCalendarV3EventsUrl[] = "calendar/v3/calendars/primary/events";
+constexpr char kCalendarV3CalendarListUrl[] =
+    "calendar/v3/users/me/calendarList";
 constexpr char kMaxAttendeesParameterName[] = "maxAttendees";
 constexpr char kMaxResultsParameterName[] = "maxResults";
 constexpr char kSingleEventsParameterName[] = "singleEvents";
@@ -69,5 +71,16 @@
   return url;
 }
 
+GURL CalendarApiUrlGenerator::GetCalendarListUrl(
+    std::optional<int> max_results) const {
+  GURL url = base_url_.Resolve(kCalendarV3CalendarListUrl);
+  if (max_results.has_value()) {
+    url = net::AppendOrReplaceQueryParameter(
+        url, kMaxResultsParameterName,
+        base::NumberToString(max_results.value()));
+  }
+  return url;
+}
+
 }  // namespace calendar
 }  // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_url_generator.h b/google_apis/calendar/calendar_api_url_generator.h
index 70666f5..e30448e6 100644
--- a/google_apis/calendar/calendar_api_url_generator.h
+++ b/google_apis/calendar/calendar_api_url_generator.h
@@ -46,6 +46,11 @@
   // Returns a URL to fetch a map of calendar color id to color code.
   GURL GetCalendarColorListUrl() const;
 
+  // Returns a URL to fetch a list of calendars.
+  // max_results   Maximum number of calendars returned on one result page.
+  //               Optional.
+  GURL GetCalendarListUrl(std::optional<int> max_results) const;
+
   // The base url can be set here. It defaults to the production base url.
   void SetBaseUrlForTesting(const std::string& url) { base_url_ = GURL(url); }
 
diff --git a/google_apis/calendar/calendar_api_url_generator_unittest.cc b/google_apis/calendar/calendar_api_url_generator_unittest.cc
index 0e1f3d7..ae93efd 100644
--- a/google_apis/calendar/calendar_api_url_generator_unittest.cc
+++ b/google_apis/calendar/calendar_api_url_generator_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "google_apis/calendar/calendar_api_url_generator.h"
 
+#include <optional>
+
 #include "base/time/time.h"
 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
 
@@ -57,5 +59,20 @@
           .spec());
 }
 
+TEST(CalendarApiUrlGeneratorTest, GetCalendarListUrl) {
+  CalendarApiUrlGenerator url_generator_;
+  EXPECT_EQ(
+      "https://www.googleapis.com/calendar/v3/users/me/calendarList"
+      "?maxResults=50",
+      url_generator_.GetCalendarListUrl(/*max_results=*/50).spec());
+}
+
+TEST(CalendarApiUrlGeneratorTest,
+     GetCalendarListUrlWithDefaultOptionalParameters) {
+  CalendarApiUrlGenerator url_generator_;
+  EXPECT_EQ(
+      "https://www.googleapis.com/calendar/v3/users/me/calendarList",
+      url_generator_.GetCalendarListUrl(/*max_results=*/std::nullopt).spec());
+}
 }  // namespace calendar
 }  // namespace google_apis
diff --git a/google_apis/test/data/calendar/calendar_list.json b/google_apis/test/data/calendar/calendar_list.json
new file mode 100644
index 0000000..82b9e4b8
--- /dev/null
+++ b/google_apis/test/data/calendar/calendar_list.json
@@ -0,0 +1,63 @@
+{
+  "kind": "calendar#calendarList",
+  "etag": "\"p32gqbiyrr257ya1\"",
+  "nextSyncToken": "vFjLRyv2e1bgx1fBEAzswbbyRrCMgpo2T6Baf47ISpP5",
+  "items": [
+    {
+      "kind": "calendar#calendarListEntry",
+      "etag": "\"3428208519567381\"",
+      "id": "test1@google.com",
+      "summary": "test1@google.com",
+      "description": "Primary Calendar",
+      "timeZone": "America/New_York",
+      "colorId": "14",
+      "backgroundColor": "#9fe1e7",
+      "foregroundColor": "#000000",
+      "selected": true,
+      "accessRole": "reader",
+      "primary": true,
+      "defaultReminders": [],
+      "conferenceProperties": {
+        "allowedConferenceSolutionTypes": [
+          "hangoutsMeet"
+        ]
+      }
+    },
+    {
+      "kind": "calendar#calendarListEntry",
+      "etag": "\"9090908504717641\"",
+      "id": "google.com_zu35dc5syt5k0fddetqqfggb75test@group.calendar.google.com",
+      "summary": "Happy Hour Events",
+      "timeZone": "America/New_York",
+      "colorId": "17",
+      "backgroundColor": "#9a9cff",
+      "foregroundColor": "#000000",
+      "accessRole": "reader",
+      "defaultReminders": [],
+      "conferenceProperties": {
+        "allowedConferenceSolutionTypes": [
+          "hangoutsMeet"
+        ]
+      }
+    },
+    {
+      "kind": "calendar#calendarListEntry",
+      "etag": "\"7777398739068290\"",
+      "id": "google.com_3edk4wi2oio66fu9l9zh19zsw9test@group.calendar.google.com",
+      "summary": "Birthdays",
+      "description": "Displays birthdays, anniversaries, and other event dates.",
+      "timeZone": "America/New_York",
+      "colorId": "13",
+      "backgroundColor": "#92e1c0",
+      "foregroundColor": "#000000",
+      "selected": true,
+      "accessRole": "reader",
+      "defaultReminders": [],
+      "conferenceProperties": {
+        "allowedConferenceSolutionTypes": [
+          "hangoutsMeet"
+        ]
+      }
+    }
+  ]
+}
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
index ac7d364..1638100f 100644
--- a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
+++ b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
@@ -127,6 +127,8 @@
       return shared_image_representation_factory_->ProduceGLTexture(mailbox);
   }
 
+  // Creates a SharedImage that can be used for reading and writing via the
+  // GLES2 interface (these tests do both).
   Mailbox CreateSharedImage(const viz::SharedImageFormat& format) {
     auto mailbox = Mailbox::GenerateForSharedImage();
     backing_factory_->CreateSharedImage(
diff --git a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
index 171d496..b0014ed4 100644
--- a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
+++ b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
@@ -97,12 +97,11 @@
   // Create the shared image
   SharedImageInterface* sii = gl_context_->GetSharedImageInterface();
   Mailbox gl_mailbox =
-      sii->CreateSharedImage(
-             viz::SinglePlaneFormat::kRGBA_8888, {1, 1},
-             gfx::ColorSpace::CreateSRGB(), kTopLeft_GrSurfaceOrigin,
-             kPremul_SkAlphaType,
-             SHARED_IMAGE_USAGE_GLES2_READ | SHARED_IMAGE_USAGE_GLES2_WRITE,
-             "TestLabel", kNullSurfaceHandle)
+      sii->CreateSharedImage(viz::SinglePlaneFormat::kRGBA_8888, {1, 1},
+                             gfx::ColorSpace::CreateSRGB(),
+                             kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
+                             SHARED_IMAGE_USAGE_GLES2_WRITE, "TestLabel",
+                             kNullSurfaceHandle)
           ->mailbox();
   SyncToken mailbox_produced_token = sii->GenVerifiedSyncToken();
   gl()->WaitSyncTokenCHROMIUM(mailbox_produced_token.GetConstData());
diff --git a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm
index 49342f5..02093c1 100644
--- a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm
+++ b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm
@@ -56,7 +56,7 @@
             SECURITY_SENSITIVE_SAFE_BROWSING_INTERSTITIAL);
   }
   return BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
-      resource.IsMainPageLoadBlocked(),
+      resource.IsMainPageLoadPendingWithSyncCheck(),
       /*is_extended_reporting_opt_in_allowed=*/false,
       /*is_off_the_record=*/false,
       /*is_extended_reporting=*/false,
@@ -89,7 +89,7 @@
     : IOSSecurityInterstitialPage(resource.weak_web_state.get(),
                                   GetMainFrameUrl(resource),
                                   client),
-      is_main_page_load_blocked_(resource.IsMainPageLoadBlocked()),
+      is_main_page_load_blocked_(resource.IsMainPageLoadPendingWithSyncCheck()),
       error_ui_(std::make_unique<SafeBrowsingLoudErrorUI>(
           resource.url,
           GetMainFrameUrl(resource),
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.h b/ios/chrome/browser/sessions/legacy_session_restoration_service.h
index 3184ebf..093d4e9 100644
--- a/ios/chrome/browser/sessions/legacy_session_restoration_service.h
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.h
@@ -58,6 +58,7 @@
   void InvokeClosureWhenBackgroundProcessingDone(
       base::OnceClosure closure) final;
   void PurgeUnassociatedData(base::OnceClosure closure) final;
+  bool PlaceholderTabsEnabled() const final;
 
   // SessionRestorationObserver implementation.
   void WillStartSessionRestoration(Browser* browser) final;
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
index c0f388e..4f71e03 100644
--- a/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
@@ -161,6 +161,11 @@
       purgeUnassociatedDataWithCompletion:std::move(closure)];
 }
 
+bool LegacySessionRestorationService::PlaceholderTabsEnabled() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return false;
+}
+
 void LegacySessionRestorationService::WillStartSessionRestoration(
     Browser* browser) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
index 931336d..1633235 100644
--- a/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
@@ -1050,3 +1050,8 @@
       ->RemoveBrowser(&browser);
   service()->Disconnect(&browser);
 }
+
+// Tests that PlaceholderTabsEnabled() can be called at any time.
+TEST_F(LegacySessionRestorationServiceTest, PlaceholderTabsEnabled) {
+  EXPECT_FALSE(service()->PlaceholderTabsEnabled());
+}
diff --git a/ios/chrome/browser/sessions/session_restoration_service.h b/ios/chrome/browser/sessions/session_restoration_service.h
index 508b96b..fc1f2bd 100644
--- a/ios/chrome/browser/sessions/session_restoration_service.h
+++ b/ios/chrome/browser/sessions/session_restoration_service.h
@@ -91,6 +91,9 @@
   // Removes any persisted data that is no longer needed and invokes
   // `closure` on the calling sequence when done.
   virtual void PurgeUnassociatedData(base::OnceClosure closure) = 0;
+
+  // Returns whether placeholder tabs support is enabled.
+  virtual bool PlaceholderTabsEnabled() const = 0;
 };
 
 #endif  // IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_SERVICE_H_
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.h b/ios/chrome/browser/sessions/session_restoration_service_impl.h
index b1b6b5a0..5d3887492 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl.h
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl.h
@@ -61,6 +61,7 @@
   void InvokeClosureWhenBackgroundProcessingDone(
       base::OnceClosure closure) final;
   void PurgeUnassociatedData(base::OnceClosure closure) final;
+  bool PlaceholderTabsEnabled() const final;
 
  private:
   // Helper type used to record information about a single WebStateList.
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.mm b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
index effc4d1..c733740 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
@@ -497,6 +497,11 @@
                                                            std::move(closure));
 }
 
+bool SessionRestorationServiceImpl::PlaceholderTabsEnabled() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return true;
+}
+
 #pragma mark - Private
 
 void SessionRestorationServiceImpl::MarkWebStateListDirty(
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
index c5a6765..d80096ab 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
@@ -1044,3 +1044,8 @@
 
   service()->Disconnect(&browser);
 }
+
+// Tests that PlaceholderTabsEnabled() can be called at any time.
+TEST_F(SessionRestorationServiceImplTest, PlaceholderTabsEnabled) {
+  EXPECT_TRUE(service()->PlaceholderTabsEnabled());
+}
diff --git a/ios/chrome/browser/sessions/test_session_restoration_service.h b/ios/chrome/browser/sessions/test_session_restoration_service.h
index e0d76fd0..2ebf241 100644
--- a/ios/chrome/browser/sessions/test_session_restoration_service.h
+++ b/ios/chrome/browser/sessions/test_session_restoration_service.h
@@ -39,6 +39,7 @@
   void InvokeClosureWhenBackgroundProcessingDone(
       base::OnceClosure closure) override;
   void PurgeUnassociatedData(base::OnceClosure closure) final;
+  bool PlaceholderTabsEnabled() const final;
 
  private:
   base::ObserverList<SessionRestorationObserver, true> observers_;
diff --git a/ios/chrome/browser/sessions/test_session_restoration_service.mm b/ios/chrome/browser/sessions/test_session_restoration_service.mm
index 99bfb6c9c..674d7a29 100644
--- a/ios/chrome/browser/sessions/test_session_restoration_service.mm
+++ b/ios/chrome/browser/sessions/test_session_restoration_service.mm
@@ -97,3 +97,7 @@
   base::SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE,
                                                            std::move(closure));
 }
+
+bool TestSessionRestorationService::PlaceholderTabsEnabled() const {
+  return false;
+}
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn
index 61a450ff..8045aff 100644
--- a/ios/chrome/browser/tabs/model/BUILD.gn
+++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -164,10 +164,15 @@
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/sync/model/glue",
-    "//ios/web/common:features",
     "//ios/web/public",
     "//ios/web/public:web_state_observer",
     "//ios/web/public/navigation",
+
+    # TODO(crbug.com/1504753): Remove those deps when support for legacy
+    # session storage is removed.
+    "//ios/chrome/browser/sessions:session_restoration_service",
+    "//ios/chrome/browser/sessions:session_restoration_service_factory",
+    "//ios/chrome/browser/shared/model/browser_state",
     "//ios/web/public/session",
   ]
 }
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h
index dc20395..02ec813 100644
--- a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h
+++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h
@@ -63,6 +63,9 @@
   // The associated WebState.
   web::WebState* const web_state_;
 
+  // Whether placeholder tabs support is enabled.
+  const bool placeholder_tabs_support_enabled_;
+
   // The session storage for the WebState. Used only when the support for
   // placeholder tabs is not enabled. Invalid to use otherwise.
   mutable CRWSessionStorage* session_storage_;
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm
index 365730f..27f6075 100644
--- a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm
+++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm
@@ -10,12 +10,17 @@
 #import "components/sync_sessions/synced_window_delegates_getter.h"
 #import "ios/chrome/browser/complex_tasks/model/ios_task_tab_helper.h"
 #import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
-#import "ios/web/common/features.h"
 #import "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/navigation/navigation_manager.h"
+#import "ios/web/public/web_state.h"
+
+// TODO(crbug.com/1504753): Remove those imports and the corresponding deps
+// when support for legacy session storage is removed.
+#import "ios/chrome/browser/sessions/session_restoration_service.h"
+#import "ios/chrome/browser/sessions/session_restoration_service_factory.h"
+#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/web/public/session/crw_navigation_item_storage.h"
 #import "ios/web/public/session/crw_session_storage.h"
-#import "ios/web/public/web_state.h"
 
 namespace {
 
@@ -30,27 +35,26 @@
              : web_state->GetNavigationManager()->GetItemAtIndex(index);
 }
 
-// Returns whether placeholder tabs are supported.
-bool ArePlaceholderTabsSupported() {
-  // The support for placeholder tabs requires the WebState session id to be
-  // stable across application restart. It is the case since M-114 which added
-  // the code to save and restore the identifier. However, it also requires
-  // that the stable identifier is communicated to sync with the detail about
-  // the corresponding session which will happen as the application is used.
-  //
-  // Yet, placeholder tabs support is required to enable session restoration
-  // optimisations. As this will be launched later, it is expected that by
-  // that point, all existing sessions will have been converted to use the
-  // stable session id and the session state uploaded to sync. Thus it is
-  // safe to enable the support of placeholder tabs behind the same feature
-  // controlling the other session restoration optimisations.
-  return web::features::UseSessionSerializationOptimizations();
+// Returns whether the session restoration service requires the support of
+// placeholder tabs to be used.
+bool PlaceholderTabsSupportEnabled(web::WebState* web_state) {
+  // Some unit tests create WebStates without a BrowserState. Don't crash.
+  web::BrowserState* browser_state = web_state->GetBrowserState();
+  if (!browser_state) {
+    return false;
+  }
+
+  return SessionRestorationServiceFactory::GetForBrowserState(
+             ChromeBrowserState::FromBrowserState(browser_state))
+      ->PlaceholderTabsEnabled();
 }
 
 }  // namespace
 
 IOSChromeSyncedTabDelegate::IOSChromeSyncedTabDelegate(web::WebState* web_state)
-    : web_state_(web_state) {
+    : web_state_(web_state),
+      placeholder_tabs_support_enabled_(
+          PlaceholderTabsSupportEnabled(web_state_)) {
   DCHECK(web_state);
 }
 
@@ -163,7 +167,7 @@
 bool IOSChromeSyncedTabDelegate::IsPlaceholderTab() const {
   // Can't be a placeholder tab if the support for placeholder tabs is not
   // enabled.
-  if (!ArePlaceholderTabsSupported()) {
+  if (!placeholder_tabs_support_enabled_) {
     return false;
   }
 
@@ -247,7 +251,7 @@
   // Never use the session storage when placeholder tabs support is enabled.
   // In fact, using the session storage is a workaround to missing placeholder
   // tab support.
-  if (ArePlaceholderTabsSupported()) {
+  if (placeholder_tabs_support_enabled_) {
     return false;
   }
 
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm
index a0e2c3c..79bcae28 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm
@@ -148,14 +148,12 @@
 
 // Observes the frame property of the view of the `webState` using KVO.
 - (void)observeWebStateViewFrame:(web::WebState*)webState {
-  if (_installedObserver || !webState->GetView()) {
+  if (base::FeatureList::IsEnabled(kFullscreenImprovement) ||
+      _installedObserver || !webState->GetView()) {
     return;
   }
 
   NSKeyValueObservingOptions options = 0;
-  if (!base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) {
-    options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
-  }
   [webState->GetView() addObserver:self
                         forKeyPath:@"frame"
                            options:options
@@ -168,19 +166,9 @@
                       ofObject:(id)object
                         change:(NSDictionary*)change
                        context:(void*)context {
-  if (![keyPath isEqualToString:@"frame"] || object != _webState->GetView())
+  if (base::FeatureList::IsEnabled(kFullscreenImprovement) ||
+      ![keyPath isEqualToString:@"frame"] || object != _webState->GetView()) {
     return;
-
-  if (!base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) {
-    NSValue* oldValue =
-        base::apple::ObjCCast<NSValue>(change[NSKeyValueChangeOldKey]);
-    NSValue* newValue =
-        base::apple::ObjCCast<NSValue>(change[NSKeyValueChangeNewKey]);
-    // If the value is unchanged -- if the old and new values are equal --
-    // then return without notifying observers.
-    if (oldValue && newValue && [newValue isEqualToValue:oldValue]) {
-      return;
-    }
   }
 
   [self updateForCurrentState];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
index c47a6871..34c626c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
@@ -36,6 +36,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_item_identifier.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_mutator.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_delegate.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.h"
@@ -73,6 +74,7 @@
 NSString* const kSuggestedActionsSectionIdentifier =
     @"SuggestedActionsSectionIdentifier";
 NSString* const kCellIdentifier = @"GridCellIdentifier";
+NSString* const kGroupCellIdentifier = @"GroupGridCellIdentifier";
 
 // Creates an NSIndexPath with `index` in section 0.
 NSIndexPath* CreateIndexPath(NSInteger index) {
@@ -85,9 +87,17 @@
   return [NSString stringWithFormat:@"%@%ld", kGridCellIdentifierPrefix, index];
 }
 
+// Returns the accessibility identifier to set on a GroupGridCell when
+// positioned at the given index.
+NSString* GroupGridCellAccessibilityIdentifier(NSUInteger index) {
+  return [NSString
+      stringWithFormat:@"%@%ld", kGroupGridCellIdentifierPrefix, index];
+}
+
 }  // namespace
 
 @interface BaseGridViewController () <GridCellDelegate,
+                                      GroupGridCellDelegate,
                                       SuggestedActionsViewControllerDelegate,
                                       UICollectionViewDragDelegate,
                                       UICollectionViewDropDelegate,
@@ -99,6 +109,9 @@
 // The cell registration for grid cells.
 @property(nonatomic, strong)
     UICollectionViewCellRegistration* gridCellRegistration;
+// The cell registration for grid group cells.
+@property(nonatomic, strong)
+    UICollectionViewCellRegistration* groupGridCellRegistration;
 // The cell registration for the Suggested Actions cell.
 @property(nonatomic, strong)
     UICollectionViewCellRegistration* suggestedActionsCellRegistration;
@@ -218,6 +231,8 @@
   // registered.
   [collectionView registerClass:[GridCell class]
       forCellWithReuseIdentifier:kCellIdentifier];
+  [collectionView registerClass:[GroupGridCell class]
+      forCellWithReuseIdentifier:kGroupCellIdentifier];
 
   collectionView.delegate = self;
   collectionView.backgroundView = [[UIView alloc] init];
@@ -433,8 +448,14 @@
     if (path.section != tabSectionIndex) {
       continue;
     }
-    GridCell* cell = ObjCCastStrict<GridCell>(
-        [self.collectionView cellForItemAtIndexPath:path]);
+    UICollectionViewCell* collectionViewCell =
+        [self.collectionView cellForItemAtIndexPath:path];
+    if (![collectionViewCell isKindOfClass:[GridCell class]]) {
+      // TODO(crbug.com/1513165): Remove once the transition annimation for the
+      // group cells is available.
+      continue;
+    }
+    GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell);
     UICollectionViewLayoutAttributes* attributes =
         [self.collectionView layoutAttributesForItemAtIndexPath:path];
     // Normalize frame to window coordinates. The attributes class applies this
@@ -477,9 +498,14 @@
           containsObject:selectedItemIndexPath]) {
     return nil;
   }
-
-  GridCell* cell = ObjCCastStrict<GridCell>(
-      [self.collectionView cellForItemAtIndexPath:selectedItemIndexPath]);
+  UICollectionViewCell* collectionViewCell =
+      [self.collectionView cellForItemAtIndexPath:selectedItemIndexPath];
+  if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) {
+    // TODO(crbug.com/1501837): Handle once the annimations are available for
+    // group cells.
+    return nil;
+  }
+  GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell);
 
   UICollectionViewLayoutAttributes* attributes = [self.collectionView
       layoutAttributesForItemAtIndexPath:selectedItemIndexPath];
@@ -603,6 +629,11 @@
       // another – correct – layout shortly after the incorrect one.
       // Keep `items`' bounds valid.
       if (self.items.count == 0 || itemIndex >= self.items.count) {
+        if (base::FeatureList::IsEnabled(kTabGroupsInGrid)) {
+          return [self.collectionView
+              dequeueReusableCellWithReuseIdentifier:kGroupCellIdentifier
+                                        forIndexPath:indexPath];
+        }
         // Dequeue using the reuse identifier, not the registration, as there is
         // no valid `item` that could be passed in for the configuration.
         return [self.collectionView
@@ -610,6 +641,14 @@
                                       forIndexPath:indexPath];
       }
       TabSwitcherItem* item = self.items[itemIndex];
+      if (base::FeatureList::IsEnabled(kTabGroupsInGrid)) {
+        UICollectionViewCellRegistration* groupCellRegistration =
+            self.groupGridCellRegistration;
+        return [self.collectionView
+            dequeueConfiguredReusableCellWithRegistration:groupCellRegistration
+                                             forIndexPath:indexPath
+                                                     item:item];
+      }
       UICollectionViewCellRegistration* registration =
           self.gridCellRegistration;
       return [self.collectionView
@@ -679,8 +718,14 @@
     return nil;
   }
 
-  GridCell* cell = ObjCCastStrict<GridCell>(
-      [self.collectionView cellForItemAtIndexPath:indexPath]);
+  UICollectionViewCell* collectionViewCell =
+      [self.collectionView cellForItemAtIndexPath:indexPath];
+  if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) {
+    // TODO(crbug.com/1501837): Handle the context menu for group cells, and
+    // remove this check.
+    return nil;
+  }
+  GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell);
 
   MenuScenarioHistogram scenario;
   if (_mode == TabGridModeSearch) {
@@ -874,8 +919,14 @@
     return nil;
   }
 
-  GridCell* gridCell = ObjCCastStrict<GridCell>(
-      [self.collectionView cellForItemAtIndexPath:indexPath]);
+  UICollectionViewCell* collectionViewCell =
+      [self.collectionView cellForItemAtIndexPath:indexPath];
+  if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) {
+    // TODO(crbug.com/1513165): Remove once the annimations for group cells are
+    // available.
+    return nil;
+  }
+  GridCell* gridCell = ObjCCastStrict<GridCell>(collectionViewCell);
   return gridCell.dragPreviewParameters;
 }
 
@@ -1025,6 +1076,13 @@
   }
 }
 
+#pragma mark - GroupGridCellDelegate
+
+- (void)closeButtonTappedForGroupCell:(GroupGridCell*)cell {
+  [self.delegate gridViewController:self
+                 didCloseItemWithID:cell.itemIdentifier];
+}
+
 #pragma mark - SuggestedActionsViewControllerDelegate
 
 - (void)suggestedActionsViewController:
@@ -1451,6 +1509,14 @@
 - (void)createRegistrations {
   __weak __typeof(self) weakSelf = self;
 
+  auto configureGroupGridCell =
+      ^(GroupGridCell* cell, NSIndexPath* indexPath, TabSwitcherItem* item) {
+        [weakSelf configureGroupCell:cell withItem:item atIndex:indexPath.item];
+      };
+  self.groupGridCellRegistration = [UICollectionViewCellRegistration
+      registrationWithCellClass:[GroupGridCell class]
+           configurationHandler:configureGroupGridCell];
+
   // Register GridCell.
   auto configureGridCell =
       ^(GridCell* cell, NSIndexPath* indexPath, TabSwitcherItem* item) {
@@ -1600,6 +1666,64 @@
   return [self.items indexOfObjectPassingTest:selectedTest];
 }
 
+// Configures `groupCell`'s identifier and title synchronously, and pass the
+// list of `GroupTabInfo`asynchronously with information from `item`. Updates
+// the `cell`'s theme to this view controller's theme. This view controller
+// becomes the delegate for the cell.
+- (void)configureGroupCell:(GroupGridCell*)cell
+                  withItem:(TabSwitcherItem*)item
+                   atIndex:(NSUInteger)index {
+  CHECK(cell);
+  CHECK(item);
+  cell.delegate = self;
+  cell.theme = self.theme;
+  cell.itemIdentifier = item.identifier;
+  cell.title = item.title;
+  cell.titleHidden = item.hidesTitle;
+  cell.accessibilityIdentifier = GroupGridCellAccessibilityIdentifier(index);
+  if (self.mode == TabGridModeSelection) {
+    if ([self.gridProvider isItemSelected:item.identifier]) {
+      cell.state = GridCellStateEditingSelected;
+    } else {
+      cell.state = GridCellStateEditingUnselected;
+    }
+  } else {
+    cell.state = GridCellStateNotEditing;
+  }
+  [item fetchFavicon:^(TabSwitcherItem* innerItem, UIImage* icon) {
+    // Only update the icon if the cell is not already reused for another item.
+    if (cell.itemIdentifier == innerItem.identifier) {
+      // TODO(crbug.com/1501837): Remove once the group color is available
+      // throught the group model. Keep for now for testing purposes.
+      cell.icon = icon;
+    }
+  }];
+
+  [item fetchSnapshot:^(TabSwitcherItem* innerItem, UIImage* snapshot) {
+    // Only update the icon if the cell is not already reused for another item.
+    if (cell.itemIdentifier == innerItem.identifier) {
+      GroupTabInfo* snapshotFavicon = [[GroupTabInfo alloc] init];
+      snapshotFavicon.snapshot = snapshot;
+      snapshotFavicon.favicon = snapshot;
+      // The `snapshotFavicon` is for demo purposes only, it will be replaced
+      // when the group tab model is available, the objects in `groupTabInfos`
+      // can be updated manually to view the different group tab configurations.
+      NSArray<GroupTabInfo*>* groupTabInfos = @[
+        snapshotFavicon, snapshotFavicon, snapshotFavicon, snapshotFavicon,
+        snapshotFavicon, snapshotFavicon
+      ];
+      [cell configureWithGroupTabInfos:groupTabInfos];
+    }
+  }];
+
+  cell.opacity = 1.0f;
+  if (item.showsActivity) {
+    [cell showActivityIndicator];
+  } else {
+    [cell hideActivityIndicator];
+  }
+}
+
 // Configures `cell`'s identifier and title synchronously, and favicon and
 // snapshot asynchronously with information from `item`. Updates the `cell`'s
 // theme to this view controller's theme. This view controller becomes the
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h
index 06d2993..c0afdd3 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h
@@ -8,6 +8,7 @@
 #import <UIKit/UIKit.h>
 
 #import "ios/chrome/browser/ui/commerce/price_card/price_card_view.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_theme.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_cell.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_grid_to_tab_transition_view.h"
@@ -19,13 +20,6 @@
 - (void)closeButtonTappedForCell:(GridCell*)cell;
 @end
 
-// Values describing the editing state of the cell.
-typedef NS_ENUM(NSUInteger, GridCellState) {
-  GridCellStateNotEditing = 1,
-  GridCellStateEditingUnselected,
-  GridCellStateEditingSelected,
-};
-
 // A square-ish cell in a grid. Contains an icon, title, snapshot, and close
 // button.
 @interface GridCell : TabCell
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
index c2c828a..08f7e09 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
@@ -14,7 +14,6 @@
 #import "ios/chrome/browser/shared/ui/elements/top_aligned_image_view.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
-#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
 #import "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h
index 9bdedcb..d76ef71 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h
@@ -14,6 +14,12 @@
 // index].
 extern NSString* const kGridCellIdentifierPrefix;
 
+// Accessibility identifier prefix of a group grid cell. To reference a specific
+// cell, concatenate `kGroupGridCellIdentifierPrefix` with the index of the
+// cell. For example, [NSString stringWithFormat:@"%@%d",
+// kGroupGridCellIdentifierPrefix, index].
+extern NSString* const kGroupGridCellIdentifierPrefix;
+
 // Accessibility identifier for the close button in a grid cell.
 extern NSString* const kGridCellCloseButtonIdentifier;
 
@@ -99,4 +105,10 @@
 extern const CGFloat kGridCellPriceDropLeadingSpacing;
 extern const CGFloat kGridCellPriceDropTrailingSpacing;
 
+typedef NS_ENUM(NSUInteger, GridCellState) {
+  GridCellStateNotEditing = 1,
+  GridCellStateEditingUnselected,
+  GridCellStateEditingSelected,
+};
+
 #endif  // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm
index bef4b06..b360ea2 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm
@@ -7,6 +7,10 @@
 // Accessibility identifier prefix of a grid cell.
 NSString* const kGridCellIdentifierPrefix = @"GridCellIdentifierPrefix";
 
+// Accessibility identifier prefix of a grid cell.
+NSString* const kGroupGridCellIdentifierPrefix =
+    @"GroupGridCellIdentifierPrefix";
+
 // Accessibility identifier for the close button in a grid cell.
 NSString* const kGridCellCloseButtonIdentifier =
     @"GridCellCloseButtonIdentifier";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h
index f63c407..b3771024 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h
@@ -7,6 +7,7 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_theme.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_info.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_cell.h"
@@ -18,13 +19,6 @@
 - (void)closeButtonTappedForGroupCell:(GroupGridCell*)cell;
 @end
 
-// Values describing the editing state of the cell.
-typedef NS_ENUM(NSUInteger, GroupGridCellState) {
-  GroupGridCellStateNotEditing = 1,
-  GroupGridCellStateEditingUnselected,
-  GroupGridCellStateEditingSelected,
-};
-
 // A square-ish cell in a grid. Contains the group's favicon, its title and
 // close button.
 @interface GroupGridCell : TabCell
@@ -39,7 +33,7 @@
 // Sets to update and keep cell alpha in sync.
 @property(nonatomic, assign) CGFloat opacity;
 // The current state which the cell should display.
-@property(nonatomic, assign) GroupGridCellState state;
+@property(nonatomic, assign) GridCellState state;
 
 // Configures every tab of the group with a given snapshot/favicon pairs.
 - (void)configureWithGroupTabInfos:(NSArray<GroupTabInfo*>*)groupTabInfos;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
index c0fcac1..6471153 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
@@ -84,7 +84,7 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _state = GroupGridCellStateNotEditing;
+    _state = GridCellStateNotEditing;
 
     // The background color must be set to avoid the corners behind the rounded
     // layer from showing when dragging and dropping. Unfortunately, using
@@ -567,7 +567,7 @@
 }
 
 - (UIImage*)selectIconImageForCurrentState {
-  if (_state == GroupGridCellStateEditingUnselected) {
+  if (_state == GridCellStateEditingUnselected) {
     return DefaultSymbolTemplateWithPointSize(kCircleSymbol,
                                               kIconSymbolPointSize);
   }
@@ -609,10 +609,10 @@
 }
 
 - (BOOL)isInSelectionMode {
-  return self.state != GroupGridCellStateNotEditing;
+  return self.state != GridCellStateNotEditing;
 }
 
-- (void)setState:(GroupGridCellState)state {
+- (void)setState:(GridCellState)state {
   if (state == _state) {
     return;
   }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
index 14d3084f..214ce98 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
@@ -21,6 +21,9 @@
 // Size of the decoration corner when the cell is selected.
 const CGFloat kCornerSize = 16;
 
+// Threshold width for collapsing the cell and hiding the close button.
+const CGFloat kCollapsedWidthThreshold = 150;
+
 // Content view constants.
 const CGFloat kFaviconLeadingMargin = 16;
 const CGFloat kCloseButtonMargin = 10;
@@ -52,6 +55,10 @@
 
   // Circular spinner that shows the loading state of the tab.
   MDCActivityIndicator* _activityIndicator;
+
+  // Title label's trailing constraints.
+  NSLayoutConstraint* _titleLabelCollapsedTrailingConstraint;
+  NSLayoutConstraint* _titleLabelTrailingConstraint;
 }
 
 - (instancetype)initWithFrame:(CGRect)frame {
@@ -147,6 +154,15 @@
   _rightTailView.hidden = !selected;
   _topLeftCornerView.hidden = !selected;
   _topRightCornerView.hidden = !selected;
+
+  [self updateCollapsedState];
+}
+
+- (void)applyLayoutAttributes:
+    (UICollectionViewLayoutAttributes*)layoutAttributes {
+  [super applyLayoutAttributes:layoutAttributes];
+
+  [self updateCollapsedState];
 }
 
 #pragma mark - UICollectionViewCell
@@ -199,6 +215,30 @@
   _decorationLayersUpdated = YES;
 }
 
+/// Hides the close button view if the cell is collapsed.
+- (void)updateCollapsedState {
+  BOOL collapsed = NO;
+  if (self.frame.size.width < kCollapsedWidthThreshold) {
+    // Don't hide the close button if the cell is selected.
+    collapsed = !self.selected;
+  }
+
+  if (collapsed == _closeButton.hidden) {
+    return;
+  }
+
+  _closeButton.hidden = collapsed;
+
+  // To avoid breaking the layout, always disable the active constraint first.
+  if (collapsed) {
+    _titleLabelTrailingConstraint.active = NO;
+    _titleLabelCollapsedTrailingConstraint.active = YES;
+  } else {
+    _titleLabelCollapsedTrailingConstraint.active = NO;
+    _titleLabelTrailingConstraint.active = YES;
+  }
+}
+
 // Sets the cell constraints.
 - (void)setupConstraints {
   UILayoutGuide* leadingImageGuide = [[UILayoutGuide alloc] init];
@@ -220,11 +260,8 @@
   AddSameConstraints(leadingImageGuide, _faviconView);
   AddSameConstraints(leadingImageGuide, _activityIndicator);
 
-  /// `_closeButton` image constraints.
+  /// `_closeButton` constraints.
   [NSLayoutConstraint activateConstraints:@[
-    [_closeButton.leadingAnchor
-        constraintEqualToAnchor:_titleLabel.trailingAnchor
-                       constant:kCloseButtonMargin],
     [_closeButton.trailingAnchor
         constraintEqualToAnchor:contentView.trailingAnchor
                        constant:-kCloseButtonMargin],
@@ -235,13 +272,16 @@
   ]];
 
   /// `_titleLabel` constraints.
+  _titleLabelTrailingConstraint = [_titleLabel.trailingAnchor
+      constraintEqualToAnchor:_closeButton.leadingAnchor
+                     constant:-kTitleInset];
+  _titleLabelCollapsedTrailingConstraint = [_titleLabel.trailingAnchor
+      constraintEqualToAnchor:contentView.trailingAnchor
+                     constant:-kTitleInset];
   [NSLayoutConstraint activateConstraints:@[
     [_titleLabel.leadingAnchor
         constraintEqualToAnchor:leadingImageGuide.trailingAnchor
                        constant:kTitleInset],
-    [_titleLabel.trailingAnchor
-        constraintLessThanOrEqualToAnchor:contentView.trailingAnchor
-                                 constant:-kTitleInset],
     [_titleLabel.centerYAnchor
         constraintEqualToAnchor:contentView.centerYAnchor],
   ]];
diff --git a/ios/chrome/browser/ui/unit_conversion/BUILD.gn b/ios/chrome/browser/ui/unit_conversion/BUILD.gn
index 56137ea..ab3b951 100644
--- a/ios/chrome/browser/ui/unit_conversion/BUILD.gn
+++ b/ios/chrome/browser/ui/unit_conversion/BUILD.gn
@@ -44,6 +44,7 @@
   ]
   deps = [
     ":constants",
+    "//components/crash/core/common",
     "//components/prefs",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/shared/ui/symbols",
diff --git a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
index 52d18d0..62be56d 100644
--- a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
+++ b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
@@ -7,7 +7,10 @@
 #import <vector>
 
 #import "base/check.h"
+#import "base/debug/dump_without_crashing.h"
 #import "base/notreached.h"
+#import "base/strings/sys_string_conversions.h"
+#import "components/crash/core/common/crash_key.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/ui/unit_conversion/unit_conversion_constants.h"
 #import "ios/chrome/browser/ui/unit_conversion/unit_conversion_mutator.h"
@@ -467,6 +470,43 @@
   }
 }
 
+- (void)generateDumpReport {
+  // There has been evidence that unitMenuButtonTitle may be nil (see
+  // crbug/1512445) but this could not be reproduced. To prevent further
+  // crash, set the title to a valid string and log more info so this can
+  // be debugged.
+  // TODO(crbug.com/1513168): remove when the issue is fixed.
+  NSString* debugSourceUnit = _formattedSourceUnit;
+  if (!debugSourceUnit) {
+    debugSourceUnit = [_sourceUnit description];
+  }
+  if (!debugSourceUnit) {
+    debugSourceUnit = @"";
+  }
+  if ([debugSourceUnit length] > 31) {
+    debugSourceUnit = [debugSourceUnit substringToIndex:31];
+  }
+  NSString* debugTargetUnit = _formattedTargetUnit;
+  if (!debugTargetUnit) {
+    debugTargetUnit = [_targetUnit description];
+  }
+  if (!debugTargetUnit) {
+    debugTargetUnit = @"";
+  }
+  if ([debugTargetUnit length] > 31) {
+    debugTargetUnit = [debugTargetUnit substringToIndex:31];
+  }
+  static crash_reporter::CrashKeyString<32> sourceKey("source_unit");
+  crash_reporter::ScopedCrashKeyString crashSourceKey(
+      &sourceKey, base::SysNSStringToUTF8(debugSourceUnit));
+
+  static crash_reporter::CrashKeyString<32> targetKey("target_unit");
+  crash_reporter::ScopedCrashKeyString crashTargetKey(
+      &targetKey, base::SysNSStringToUTF8(debugTargetUnit));
+
+  base::debug::DumpWithoutCrashing();
+}
+
 #pragma mark - UITableViewDataSource
 
 - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
@@ -501,6 +541,11 @@
     } else {
       NOTREACHED_NORETURN();
     }
+
+    if (!unitMenuButtonTitle) {
+      unitMenuButtonTitle = @"";
+      [self generateDumpReport];
+    }
     UIButtonConfiguration* unitMenuButtonConfiguration =
         cell.unitMenuButton.configuration;
     unitMenuButtonConfiguration.attributedTitle = [self
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index 5370effe..f896ed6 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-55a056904656de72e797a23b6a39b3c66bee3a0a
\ No newline at end of file
+d993b76ada9c5f5522d770d7ef3e676e38d34be3
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index 3f08bea6..5bed726 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-2e130d8faaa86d745e6a8d37d33688bd8082d48c
\ No newline at end of file
+6b3a919faf4176124aa8d3e031c1bcacf2258eef
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index c405e9e..391485d2 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-fafa9a291ec1e036ead78e4758c2450491830be8
\ No newline at end of file
+73e9840224064639a3e94e0e4574d455f0e65cfc
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index d8f4caa..d2e0cec 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a3ce27dd82e16caf6eecb16ff43274d99e36e987
\ No newline at end of file
+64f39ba3b9c8b8d957e1ce1e3cb3405c14a2b979
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 32f84e9..36edc26f 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-c69d827812c640c5939cad173867737c6ba5e833
\ No newline at end of file
+e867aa6bbdf80ea7eab1814ca0f6e9546f822d51
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 89a711e..99d70158 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-d8217234f3502146d8623f95ad760b0e00d91c0f
\ No newline at end of file
+5123007a328f2100bb08e81108972835b3922b54
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index e364c136..0993858c 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-d5b76e4e5dee70358814fbe60efa70cee7e2ecee
\ No newline at end of file
+78652ed2f1573874826b3a0b03cd51d76a513bd7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 01e3cb8..0282d39 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a5fa1f969c43c034a1eef3d3903e40dc2d7e6ca4
\ No newline at end of file
+622fa3d70bc9d5b666f3d322d889a43d93242476
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 00bbdba59..33be0e3 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-c60230963f286e6e8c712f15d43132e7a4d89d09
\ No newline at end of file
+8d340b1c37e30ea4ad26e2854bb138f99b2e828e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 88009b31..bb6ff17 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-b74e5edc85b3b83bd5b48b35d0db8b54a65d67f0
\ No newline at end of file
+1a7df88d2ce8e86546975daa8c84196d4ecc23de
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index b84924c7..d125338 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-1c0690d9572073a7872140e70375d0f8bef66672
\ No newline at end of file
+bef2afa2ae40d627c9793fec7de2e42eb20e5c62
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 84d3220..c57a893 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a291bb6a88e0212fa4c8300e364bf4b5f30a0048
\ No newline at end of file
+50b48dd625d63050824df681e6501e225024ce97
\ No newline at end of file
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn
index 0b8d5f6e..edf01d97 100644
--- a/ios/third_party/material_components_ios/BUILD.gn
+++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -136,8 +136,6 @@
   "src/components/Chips/src/MDCChipView.h",
   "src/components/Chips/src/MDCChipViewAccessoryView.h",
   "src/components/Chips/src/MDCChipViewDeleteButton.h",
-  "src/components/Chips/src/MDCLegacyChipField.h",
-  "src/components/Chips/src/MDCLegacyChipFieldDelegate.h",
   "src/components/Chips/src/MaterialChips.h",
   "src/components/Chips/src/PerformantShadowMigration/MDCChipView+ShadowsPrivate.h",
   "src/components/Chips/src/Theming/MDCChipView+MaterialTheming.h",
@@ -924,9 +922,6 @@
   "src/components/Chips/src/MDCChipViewAccessoryView.m",
   "src/components/Chips/src/MDCChipViewDeleteButton.h",
   "src/components/Chips/src/MDCChipViewDeleteButton.m",
-  "src/components/Chips/src/MDCLegacyChipField.h",
-  "src/components/Chips/src/MDCLegacyChipField.m",
-  "src/components/Chips/src/MDCLegacyChipFieldDelegate.h",
   "src/components/Chips/src/MaterialChips.h",
   "src/components/Chips/src/PerformantShadowMigration/MDCChipView+ShadowsPrivate.h",
   "src/components/Chips/src/Theming/MDCChipView+MaterialTheming.h",
diff --git a/ios/third_party/material_components_ios/src b/ios/third_party/material_components_ios/src
index c4c73b5..00fac7e 160000
--- a/ios/third_party/material_components_ios/src
+++ b/ios/third_party/material_components_ios/src
@@ -1 +1 @@
-Subproject commit c4c73b5452c7efca23db99cde8746d36e0ed107a
+Subproject commit 00fac7e67918c03a47eb79b5e65d7a5aa6cbf70f
diff --git a/ios_internal b/ios_internal
index 6ab4b39..ac06513 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 6ab4b39499215991e1d58a879aec026c6f54a925
+Subproject commit ac06513c41078df3c7e5c292bbfdd2423dc61741
diff --git a/media/cdm/cdm_module.cc b/media/cdm/cdm_module.cc
index 83bd26b..65fef0d 100644
--- a/media/cdm/cdm_module.cc
+++ b/media/cdm/cdm_module.cc
@@ -172,6 +172,7 @@
 void CdmModule::InitializeCdmModule() {
   DCHECK(initialized_);
   DCHECK(initialize_cdm_module_func_);
+  TRACE_EVENT0("media", "CdmModule::InitializeCdmModule");
   initialize_cdm_module_func_();
 }
 
diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn
index 2c445208..9e2cf61 100644
--- a/mojo/public/java/BUILD.gn
+++ b/mojo/public/java/BUILD.gn
@@ -29,7 +29,6 @@
     "bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java",
     "bindings/src/org/chromium/mojo/bindings/AutoCloseableRouter.java",
     "bindings/src/org/chromium/mojo/bindings/BindingsHelper.java",
-    "bindings/src/org/chromium/mojo/bindings/Callbacks.java",
     "bindings/src/org/chromium/mojo/bindings/ConnectionErrorHandler.java",
     "bindings/src/org/chromium/mojo/bindings/Connector.java",
     "bindings/src/org/chromium/mojo/bindings/DataHeader.java",
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java
deleted file mode 100644
index 0ee59d9..0000000
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file was generated using
-//     mojo/tools/generate_java_callback_interfaces.py
-
-package org.chromium.mojo.bindings;
-
-/** Contains a generic interface for callbacks. */
-public interface Callbacks {
-
-    /** A generic callback. */
-    interface Callback0 {
-        /** Call the callback. */
-        public void call();
-    }
-
-    /**
-     * A generic 1-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     */
-    interface Callback1<T1> {
-        /** Call the callback. */
-        public void call(T1 arg1);
-    }
-
-    /**
-     * A generic 2-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     */
-    interface Callback2<T1, T2> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2);
-    }
-
-    /**
-     * A generic 3-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     */
-    interface Callback3<T1, T2, T3> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2, T3 arg3);
-    }
-
-    /**
-     * A generic 4-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     */
-    interface Callback4<T1, T2, T3, T4> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-    }
-
-    /**
-     * A generic 5-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     */
-    interface Callback5<T1, T2, T3, T4, T5> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
-    }
-
-    /**
-     * A generic 6-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     * @param <T6> the type of argument 6.
-     */
-    interface Callback6<T1, T2, T3, T4, T5, T6> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
-    }
-
-    /**
-     * A generic 7-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     * @param <T6> the type of argument 6.
-     * @param <T7> the type of argument 7.
-     */
-    interface Callback7<T1, T2, T3, T4, T5, T6, T7> {
-        /** Call the callback. */
-        public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
-    }
-
-    /**
-     * A generic 11-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     * @param <T6> the type of argument 6.
-     * @param <T7> the type of argument 7.
-     * @param <T8> the type of argument 8.
-     * @param <T9> the type of argument 9.
-     * @param <T10> the type of argument 10.
-     * @param <T11> the type of argument 11.
-     */
-    interface Callback11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> {
-        /** Call the callback. */
-        public void call(
-                T1 arg1,
-                T2 arg2,
-                T3 arg3,
-                T4 arg4,
-                T5 arg5,
-                T6 arg6,
-                T7 arg7,
-                T8 arg8,
-                T9 arg9,
-                T10 arg10,
-                T11 arg11);
-    }
-
-    /**
-     * A generic 13-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     * @param <T6> the type of argument 6.
-     * @param <T7> the type of argument 7.
-     * @param <T8> the type of argument 8.
-     * @param <T9> the type of argument 9.
-     * @param <T10> the type of argument 10.
-     * @param <T11> the type of argument 11.
-     * @param <T12> the type of argument 12.
-     * @param <T13> the type of argument 13.
-     */
-    interface Callback13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> {
-        /** Call the callback. */
-        public void call(
-                T1 arg1,
-                T2 arg2,
-                T3 arg3,
-                T4 arg4,
-                T5 arg5,
-                T6 arg6,
-                T7 arg7,
-                T8 arg8,
-                T9 arg9,
-                T10 arg10,
-                T11 arg11,
-                T12 arg12,
-                T13 arg13);
-    }
-
-    /**
-     * A generic 22-argument callback.
-     *
-     * @param <T1> the type of argument 1.
-     * @param <T2> the type of argument 2.
-     * @param <T3> the type of argument 3.
-     * @param <T4> the type of argument 4.
-     * @param <T5> the type of argument 5.
-     * @param <T6> the type of argument 6.
-     * @param <T7> the type of argument 7.
-     * @param <T8> the type of argument 8.
-     * @param <T9> the type of argument 9.
-     * @param <T10> the type of argument 10.
-     * @param <T11> the type of argument 11.
-     * @param <T12> the type of argument 12.
-     * @param <T13> the type of argument 13.
-     * @param <T14> the type of argument 14.
-     * @param <T15> the type of argument 15.
-     * @param <T16> the type of argument 16.
-     * @param <T17> the type of argument 17.
-     * @param <T18> the type of argument 18.
-     * @param <T19> the type of argument 19.
-     * @param <T20> the type of argument 20.
-     * @param <T21> the type of argument 21.
-     * @param <T22> the type of argument 22.
-     */
-    interface Callback22<
-            T1,
-            T2,
-            T3,
-            T4,
-            T5,
-            T6,
-            T7,
-            T8,
-            T9,
-            T10,
-            T11,
-            T12,
-            T13,
-            T14,
-            T15,
-            T16,
-            T17,
-            T18,
-            T19,
-            T20,
-            T21,
-            T22> {
-        /** Call the callback. */
-        public void call(
-                T1 arg1,
-                T2 arg2,
-                T3 arg3,
-                T4 arg4,
-                T5 arg5,
-                T6 arg6,
-                T7 arg7,
-                T8 arg8,
-                T9 arg9,
-                T10 arg10,
-                T11 arg11,
-                T12 arg12,
-                T13 arg13,
-                T14 arg14,
-                T15 arg15,
-                T16 arg16,
-                T17 arg17,
-                T18 arg18,
-                T19 arg19,
-                T20 arg20,
-                T21 arg21,
-                T22 arg22);
-    }
-}
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
index db07462..51ab799 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
@@ -4,7 +4,6 @@
 
 package org.chromium.mojo.bindings;
 
-import org.chromium.mojo.bindings.Callbacks.Callback1;
 import org.chromium.mojo.bindings.Interface.AbstractProxy.HandlerImpl;
 import org.chromium.mojo.bindings.interfacecontrol.QueryVersion;
 import org.chromium.mojo.bindings.interfacecontrol.RequireVersion;
@@ -53,12 +52,17 @@
             /** Returns the version number of the interface that the remote side supports. */
             public int getVersion();
 
+            /** Callback interface for the async response to {@link Proxy#queryVersion}. */
+            interface QueryVersionCallback {
+                public void call(int version);
+            }
+
             /**
              * Queries the max version that the remote side supports. On completion, the result will
              * be returned as the input of |callback|. The version number of this interface pointer
              * will also be updated.
              */
-            public void queryVersion(Callback1<Integer> callback);
+            public void queryVersion(QueryVersionCallback callback);
 
             /**
              * If the remote side doesn't support the specified version, it will close its end of
@@ -167,7 +171,7 @@
              * @see Handler#queryVersion(org.chromium.mojo.bindings.Callbacks.Callback1)
              */
             @Override
-            public void queryVersion(final Callback1<Integer> callback) {
+            public void queryVersion(QueryVersionCallback callback) {
                 RunMessageParams message = new RunMessageParams();
                 message.input = new RunInput();
                 message.input.setQueryVersion(new QueryVersion());
@@ -176,7 +180,7 @@
                         getCore(),
                         mMessageReceiver,
                         message,
-                        new Callback1<RunResponseMessageParams>() {
+                        new InterfaceControlMessagesHelper.SendRunMessageCallback() {
                             @Override
                             public void call(RunResponseMessageParams response) {
                                 if (response.output != null
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java
index 253e639..33882dd 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java
@@ -4,7 +4,6 @@
 
 package org.chromium.mojo.bindings;
 
-import org.chromium.mojo.bindings.Callbacks.Callback1;
 import org.chromium.mojo.bindings.Interface.Manager;
 import org.chromium.mojo.bindings.Interface.Proxy;
 import org.chromium.mojo.bindings.interfacecontrol.InterfaceControlMessagesConstants;
@@ -23,14 +22,22 @@
  */
 public class InterfaceControlMessagesHelper {
     /**
+     * Callback interface for the async response to {@link
+     * InterfaceControlMessagesHelper#sendRunMessage}.
+     */
+    interface SendRunMessageCallback {
+        public void call(RunResponseMessageParams params);
+    }
+
+    /**
      * MessageReceiver that forwards a message containing a {@link RunResponseMessageParams} to a
      * callback.
      */
     private static class RunResponseForwardToCallback extends SideEffectFreeCloseable
             implements MessageReceiver {
-        private final Callback1<RunResponseMessageParams> mCallback;
+        private final SendRunMessageCallback mCallback;
 
-        RunResponseForwardToCallback(Callback1<RunResponseMessageParams> callback) {
+        RunResponseForwardToCallback(SendRunMessageCallback callback) {
             mCallback = callback;
         }
 
@@ -51,7 +58,7 @@
             Core core,
             MessageReceiverWithResponder receiver,
             RunMessageParams params,
-            Callback1<RunResponseMessageParams> callback) {
+            SendRunMessageCallback callback) {
         Message message =
                 params.serializeWithHeader(
                         core,
diff --git a/mojo/public/java/system/BUILD.gn b/mojo/public/java/system/BUILD.gn
index 4d6caf24..862f772 100644
--- a/mojo/public/java/system/BUILD.gn
+++ b/mojo/public/java/system/BUILD.gn
@@ -106,7 +106,6 @@
     "javatests/src/org/chromium/mojo/bindings/BindingsTest.java",
     "javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java",
     "javatests/src/org/chromium/mojo/bindings/BindingsVersioningTest.java",
-    "javatests/src/org/chromium/mojo/bindings/CallbacksTest.java",
     "javatests/src/org/chromium/mojo/bindings/ConnectorTest.java",
     "javatests/src/org/chromium/mojo/bindings/ExecutorFactoryTest.java",
     "javatests/src/org/chromium/mojo/bindings/InterfacesTest.java",
diff --git a/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java b/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java
deleted file mode 100644
index c9f8e6b..0000000
--- a/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.mojo.bindings;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.mojo.bindings.Callbacks.Callback1;
-import org.chromium.mojo.bindings.Callbacks.Callback7;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/** Testing generated callbacks */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class CallbacksTest {
-    /** Testing {@link Callback1}. */
-    @Test
-    @SmallTest
-    public void testCallback1() {
-        final List<Integer> parameters = new ArrayList<Integer>();
-        new Callback1<Integer>() {
-            @Override
-            public void call(Integer i1) {
-                parameters.add(i1);
-            }
-        }.call(1);
-        Assert.assertEquals(Arrays.asList(1), parameters);
-    }
-
-    /** Testing {@link Callback7}. */
-    @Test
-    @SmallTest
-    public void testCallback7() {
-        final List<Integer> parameters = new ArrayList<Integer>();
-        new Callback7<Integer, Integer, Integer, Integer, Integer, Integer, Integer>() {
-            @Override
-            public void call(
-                    Integer i1,
-                    Integer i2,
-                    Integer i3,
-                    Integer i4,
-                    Integer i5,
-                    Integer i6,
-                    Integer i7) {
-                parameters.add(i1);
-                parameters.add(i2);
-                parameters.add(i3);
-                parameters.add(i4);
-                parameters.add(i5);
-                parameters.add(i6);
-                parameters.add(i7);
-            }
-        }.call(1, 2, 3, 4, 5, 6, 7);
-        Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), parameters);
-    }
-}
diff --git a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
index c8d1209..72a57f5 100644
--- a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
@@ -18,13 +18,14 @@
 {% endmacro %}
 
 {%- macro declare_callback(method) -%}
-
-interface {{method|interface_response_name}} extends org.chromium.mojo.bindings.Callbacks.Callback{{method.response_parameters|length}}{% if method.response_parameters %}<
-{%-   for param in method.response_parameters -%}
-{{param.kind|java_type(True)}}
+interface {{method|interface_response_name}} {
+  public void call(
+{%- for param in method.response_parameters %}
+      {{param.kind|java_type(True)}} {{param|name}}
 {%- if not loop.last %}, {% endif %}
-{%-   endfor -%}
->{% endif %} { }
+{%- endfor -%}
+      );
+}
 {%- endmacro -%}
 
 {%- macro run_callback(variable, parameters) -%}
diff --git a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java
index bddd5426d..85edafe 100644
--- a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java
+++ b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java
@@ -29,7 +29,6 @@
 import org.chromium.device.mojom.NdefWriteOptions;
 import org.chromium.device.mojom.Nfc;
 import org.chromium.device.mojom.NfcClient;
-import org.chromium.mojo.bindings.Callbacks;
 import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.bindings.Router;
 import org.chromium.mojo.system.MojoException;
@@ -202,7 +201,11 @@
      */
     @Override
     public void push(NdefMessage message, NdefWriteOptions options, Push_Response callback) {
-        if (!checkIfReady(callback)) return;
+        NdefError error = checkIfReady();
+        if (error != null) {
+            callback.call(error);
+            return;
+        }
 
         if (mOperationsSuspended) {
             callback.call(
@@ -247,7 +250,11 @@
      */
     @Override
     public void makeReadOnly(MakeReadOnly_Response callback) {
-        if (!checkIfReady(callback)) return;
+        NdefError error = checkIfReady();
+        if (error != null) {
+            callback.call(error);
+            return;
+        }
 
         if (mOperationsSuspended) {
             callback.call(
@@ -289,7 +296,12 @@
      */
     @Override
     public void watch(int id, Watch_Response callback) {
-        if (!checkIfReady(callback)) return;
+        NdefError error = checkIfReady();
+        if (error != null) {
+            callback.call(error);
+            return;
+        }
+
         // We received a duplicate |id| here that should never happen, in such a case we should
         // report a bad message to Mojo but unfortunately Mojo bindings for Java does not support
         // this feature yet. So, we just passes back a generic error instead.
@@ -415,20 +427,6 @@
     }
 
     /**
-     * Uses checkIfReady() method and if NFC cannot be used, calls mojo callback with NdefError.
-     *
-     * @param callback Generic callback that is provided to watch() and push() methods.
-     * @return boolean true if NFC functionality can be used, false otherwise.
-     */
-    private boolean checkIfReady(Callbacks.Callback1<NdefError> callback) {
-        NdefError error = checkIfReady();
-        if (error == null) return true;
-
-        callback.call(error);
-        return false;
-    }
-
-    /**
      * Implementation of android.nfc.NfcAdapter.ReaderCallback. Callback is called when NFC tag is
      * discovered, Tag object is delegated to mojo service implementation method
      * NfcImpl.onTagDiscovered().
@@ -611,7 +609,8 @@
                 pendingMakeReadOnlyOperationCompleted(
                         createError(
                                 NdefErrorType.NOT_SUPPORTED,
-                                "Failed to make read-only because the tag cannot be made read-only"));
+                                "Failed to make read-only because the tag cannot be made"
+                                        + " read-only"));
             }
         } catch (TagLostException e) {
             Log.w(TAG, "Cannot make NFC tag read-only. Tag is lost: " + e.getMessage());
diff --git a/services/on_device_model/ml/chrome_ml.cc b/services/on_device_model/ml/chrome_ml.cc
index 4a22e6ba..db3cd48 100644
--- a/services/on_device_model/ml/chrome_ml.cc
+++ b/services/on_device_model/ml/chrome_ml.cc
@@ -134,6 +134,10 @@
 
 DISABLE_CFI_DLSYM
 bool ChromeML::IsGpuBlocked() const {
+  if (allow_gpu_for_testing_) {
+    return false;
+  }
+
   GpuConfig gpu_config;
   if (!api().GetGpuConfig(gpu_config)) {
     LogGpuBlocked(GpuBlockedReason::kGpuConfigError);
diff --git a/services/on_device_model/ml/chrome_ml.h b/services/on_device_model/ml/chrome_ml.h
index b2432b2c..e8e77c5 100644
--- a/services/on_device_model/ml/chrome_ml.h
+++ b/services/on_device_model/ml/chrome_ml.h
@@ -37,12 +37,17 @@
   // Whether or not the GPU is blocklisted.
   bool IsGpuBlocked() const;
 
+  void SetAllowGpuForTesting(bool allow_gpu) {
+    allow_gpu_for_testing_ = allow_gpu;
+  }
+
  private:
   static std::unique_ptr<ChromeML> Create(
       const std::optional<std::string>& library_name);
 
   const base::ScopedNativeLibrary library_;
   const raw_ptr<const ChromeMLAPI> api_;
+  bool allow_gpu_for_testing_ = false;
 };
 
 }  // namespace ml
diff --git a/services/webnn/dml/graph_impl_test.cc b/services/webnn/dml/graph_impl_test.cc
index 96f5ea0..dcbd61b 100644
--- a/services/webnn/dml/graph_impl_test.cc
+++ b/services/webnn/dml/graph_impl_test.cc
@@ -11,7 +11,9 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "components/ml/webnn/features.mojom-features.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/webnn/dml/adapter.h"
 #include "services/webnn/dml/command_queue.h"
@@ -227,12 +229,17 @@
   void SetUp() override;
 
  protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
   base::test::TaskEnvironment task_environment_;
   scoped_refptr<Adapter> adapter_;
 };
 
 void WebNNGraphDMLImplTest::SetUp() {
   SKIP_TEST_IF(!UseGPUInTests());
+
+  scoped_feature_list_.InitAndEnableFeature(
+      webnn::mojom::features::kWebMachineLearningNeuralNetwork);
+
   ASSERT_TRUE(InitializeGLDisplay());
   Adapter::EnableDebugLayerForTesting();
   auto adapter_creation_result = Adapter::GetInstanceForTesting();
diff --git a/services/webnn/webnn_graph_impl_unittest.cc b/services/webnn/webnn_graph_impl_unittest.cc
index 7d930f4..c07a3f3 100644
--- a/services/webnn/webnn_graph_impl_unittest.cc
+++ b/services/webnn/webnn_graph_impl_unittest.cc
@@ -5001,8 +5001,9 @@
 }
 
 TEST_F(WebNNGraphImplTest, ValidateInputsTest) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitFromCommandLine("WebMachineLearningNeuralNetwork", "");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      webnn::mojom::features::kWebMachineLearningNeuralNetwork);
 
   const std::vector<uint32_t> dimensions = {3, 5};
   // Build the graph with mojo type.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b30a1ec..f80b4e3 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -15098,66 +15098,6 @@
             ]
         }
     ],
-    "RequestDesktopSiteDefaultsControlCohort": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RequestDesktopSiteDefaultsControlSynthetic"
-                    ]
-                }
-            ]
-        }
-    ],
-    "RequestDesktopSiteDefaultsEnabledCohort": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RequestDesktopSiteDefaultsSynthetic"
-                    ]
-                }
-            ]
-        }
-    ],
-    "RequestDesktopSiteOptInControlCohort": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RequestDesktopSiteOptInControlSynthetic"
-                    ]
-                }
-            ]
-        }
-    ],
-    "RequestDesktopSiteOptInEnabledCohort": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RequestDesktopSiteOptInSynthetic"
-                    ]
-                }
-            ]
-        }
-    ],
     "ResponsiveToolbar": [
         {
             "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 3674dd1..b3a5540 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -64,12 +64,6 @@
 /google-truth/src/
 /googlefonts_testdata/data
 /guava/lib/
-/gvr-android-sdk/common_library.aar
-/gvr-android-sdk/libgvr_shim_static_*.a
-/gvr-android-sdk/test-apks/daydream_home/*.apk
-/gvr-android-sdk/test-apks/vr_keyboard/*.apk
-/gvr-android-sdk/test-apks/vr_services/*.apk
-/gvr-android-sdk/test-libraries/controller_test_api.aar
 /hamcrest/lib/
 /icu4j/lib/
 /instrumented_libraries/scripts/*.tgz
diff --git a/third_party/angle b/third_party/angle
index e3600ab..82c95b3 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit e3600abb810666033b35b8e98043869fb1c10603
+Subproject commit 82c95b3012573f46a99f7f32d2a93c3671c0e8b9
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
index 5d3ab23..59969ef 100644
--- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
@@ -106,11 +106,6 @@
 
  public:
 
-  // ComputedStyle sub-objects are heavily inlined, and on relatively hot
-  // codepaths. Disable pointer-compression.
-  template <typename T>
-  using DataMember = subtle::UncompressedMember<T>;
-
   inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const {
     return (
         {{fieldwise_compare(computed_style, computed_style.all_fields
@@ -262,7 +257,7 @@
 
   // Storage.
   {% for subgroup in computed_style.subgroups %}
-  DataMember<{{subgroup.type_name}}> {{subgroup.member_name}};
+  Member<{{subgroup.type_name}}> {{subgroup.member_name}};
   {% endfor %}
 
   {# Members #}
@@ -329,7 +324,7 @@
   }
 
   template <typename T>
-  static T* Access(ComputedStyleBase::DataMember<T>& data, bool& access_flag) {
+  static T* Access(Member<T>& data, bool& access_flag) {
     if (!access_flag) {
       access_flag = true;
       data = data->Copy();
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl
index 5557ad8..cd164f8 100644
--- a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl
+++ b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl
@@ -60,7 +60,7 @@
   bool operator!=(const {{group.type_name}}& other) const { return !(*this == other); }
 
   {% for subgroup in group.subgroups %}
-  DataMember<{{subgroup.type_name}}> {{subgroup.member_name}};
+  Member<{{subgroup.type_name}}> {{subgroup.member_name}};
   {% endfor %}
   {% for field in group.fields %}
   {{declare_storage(field)}}
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 4d996fc..4977d03 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -5315,7 +5315,7 @@
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       interpolable: true,
       layout_dependent: true,
-      field_group: "*",
+      field_group: "svg",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/style/transform_origin.h"],
       default_value: "TransformOrigin(Length::Percent(50.0), Length::Percent(50.0), 0)",
diff --git a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
index 9103f5b..27c46438 100644
--- a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
@@ -126,12 +126,12 @@
     if (layout_object->IsText() &&
         To<LayoutText>(layout_object)->ResolvedTextLength()) {
       if (style.ShouldPreserveBreaks()) {
-        auto* text = To<LayoutText>(layout_object);
-        int index = text->TextLength();
+        const String& text = To<LayoutText>(layout_object)->GetText();
+        int index = text.length();
         if (previous_node_iterator == start_node && candidate_offset < index)
           index = max(0, candidate_offset);
         while (--index >= 0) {
-          if ((*text)[index] == '\n') {
+          if (text[index] == '\n') {
             return PositionTemplate<Strategy>(To<Text>(previous_node_iterator),
                                               index + 1);
           }
@@ -239,21 +239,24 @@
     // can't accept the caret.
     if (layout_object->IsText() &&
         To<LayoutText>(layout_object)->ResolvedTextLength()) {
-      auto* const text = To<LayoutText>(layout_object);
+      auto* const layout_text = To<LayoutText>(layout_object);
       if (style.ShouldPreserveBreaks()) {
-        const int length = text->TextLength();
+        const String& text = layout_text->GetText();
+        const int length = text.length();
         for (int i = (next_node_iterator == start_node ? candidate_offset : 0);
              i < length; ++i) {
-          if ((*text)[i] == '\n') {
-            return PositionTemplate<Strategy>(To<Text>(next_node_iterator),
-                                              i + text->TextStartOffset());
+          if (text[i] == '\n') {
+            return PositionTemplate<Strategy>(
+                To<Text>(next_node_iterator),
+                i + layout_text->TextStartOffset());
           }
         }
       }
 
       candidate_node = next_node_iterator;
       candidate_type = PositionAnchorType::kOffsetInAnchor;
-      candidate_offset = text->CaretMaxOffset() + text->TextStartOffset();
+      candidate_offset =
+          layout_text->CaretMaxOffset() + layout_text->TextStartOffset();
       next_node_iterator = nextNode();
     } else if (EditingIgnoresContent(*next_node_iterator) ||
                IsDisplayInsideTable(next_node_iterator)) {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index 49e0954..500074c 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -1310,8 +1310,9 @@
   else if (auto* option = DynamicTo<HTMLOptionElement>(element))
     item_string = option->TextIndentedToRespectGroupLabel();
 
-  if (GetLayoutObject() && GetLayoutObject()->Style())
-    GetLayoutObject()->Style()->ApplyTextTransform(&item_string);
+  if (GetLayoutObject() && GetLayoutObject()->Style()) {
+    return GetLayoutObject()->Style()->ApplyTextTransform(item_string);
+  }
   return item_string;
 }
 
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index d851151..96fdba63 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -479,6 +479,7 @@
 void HTMLDocumentParser::PrepareToStopParsing() {
   TRACE_EVENT1("blink", "HTMLDocumentParser::PrepareToStopParsing", "parser",
                (void*)this);
+  base::ElapsedTimer timer;
   DCHECK(!HasInsertionPoint());
 
   // If we've already been detached, e.g. in
@@ -523,6 +524,8 @@
   GetDocument()->OnPrepareToStopParsing();
 
   AttemptToRunDeferredScriptsAndEnd();
+
+  base::UmaHistogramTimes("Blink.PrepareToStopParsingTime", timer.Elapsed());
 }
 
 bool HTMLDocumentParser::IsParsingFragment() const {
@@ -652,6 +655,7 @@
                        "should_complete", should_run_until_completion,
                        "bytes_queued", starting_bytes);
   }
+  base::ElapsedTimer pump_tokenizer_timer;
 
   // We tell the InspectorInstrumentation about every pump, even if we end up
   // pumping nothing.  It can filter out empty pumps itself.
@@ -760,6 +764,9 @@
     }
   }
 
+  base::UmaHistogramTimes("Blink.PumpTokenizerTime",
+                          pump_tokenizer_timer.Elapsed());
+
   if (is_tracing) {
     TRACE_EVENT_END2("blink", "HTMLDocumentParser::PumpTokenizer",
                      "parsed_tokens", tokens_parsed, "parsed_bytes",
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index d687b459..f27b248 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -874,6 +874,8 @@
   LayoutUnit row_gap = grid->GridGap(kForRows);
   LayoutUnit column_gap = grid->GridGap(kForColumns);
 
+  // TODO(kschmi) - merge area names in `GridLineResolver` so that
+  // subgrid-inherited grid areas are included.
   for (const auto& item : grid->StyleRef().GridTemplateAreas()->named_areas) {
     const GridArea& area = item.value;
     const String& name = item.key;
@@ -959,19 +961,13 @@
   };
 
   const NamedGridLinesMap& explicit_lines_map =
-      (direction == kForColumns)
-          ? grid_container_style.GridTemplateColumns().named_grid_lines
-          : grid_container_style.GridTemplateRows().named_grid_lines;
+      grid->CachedPlacementData().line_resolver.ExplicitNamedLinesMap(
+          direction);
   process_grid_lines_map(explicit_lines_map);
-
-  if (const auto& grid_template_areas =
-          grid_container_style.GridTemplateAreas()) {
-    const NamedGridLinesMap& implicit_lines_map =
-        (direction == kForColumns)
-            ? grid_template_areas->implicit_named_grid_column_lines
-            : grid_template_areas->implicit_named_grid_row_lines;
-    process_grid_lines_map(implicit_lines_map);
-  }
+  const NamedGridLinesMap& implicit_lines_map =
+      grid->CachedPlacementData().line_resolver.ImplicitNamedLinesMap(
+          direction);
+  process_grid_lines_map(implicit_lines_map);
 
   return lines;
 }
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h
index c32f6ff..049c17e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.h
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -283,10 +283,6 @@
   ColorFormat color_format_;
 };
 
-std::unique_ptr<protocol::DictionaryValue> InspectorGridHighlight(
-    Node*,
-    const InspectorGridHighlightConfig& config);
-
 std::unique_ptr<protocol::DictionaryValue> InspectorFlexContainerHighlight(
     Node* node,
     const InspectorFlexContainerHighlightConfig& config);
@@ -305,6 +301,9 @@
 
 // CORE_EXPORT is required to make these functions available for unit tests.
 std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
+InspectorGridHighlight(Node*, const InspectorGridHighlightConfig& config);
+
+std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
 BuildSnapContainerInfo(Node* node);
 
 std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
index 06cb262..822fe1b8 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
@@ -353,4 +353,142 @@
               Eq("lab(20 -10 -10)"));
 }
 
+TEST_F(InspectorHighlightTest, GridLineNames) {
+  GetDocument().body()->setInnerHTML(R"HTML(
+    <style>
+    #grid {
+      display: grid;
+      grid-template-columns: [a] 1fr [b] 1fr [c] 1fr;
+      grid-template-rows: [d] 1fr [e] 1fr [f] 1fr;
+    }
+    #subgrid {
+      display: grid;
+      grid-column: 1 / 4;
+      grid-row: 1 / 4;
+      grid-template-columns: subgrid [a_sub] [b_sub] [c_sub];
+      grid-template-rows: subgrid [d_sub] [e_sub] [f_sub];
+    }
+    </style>
+    <div id="grid">
+      <div id="subgrid">
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+      </div>
+    </div>
+  )HTML");
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+  Node* subgrid = GetDocument().getElementById(AtomicString("subgrid"));
+  EXPECT_TRUE(subgrid);
+  auto info =
+      InspectorGridHighlight(subgrid, InspectorHighlight::DefaultGridConfig());
+  EXPECT_TRUE(info);
+
+  auto CompareLineNames = [](protocol::ListValue* row_or_column_list,
+                             WTF::Vector<WTF::String>& expected_names) -> void {
+    for (wtf_size_t i = 0; i < row_or_column_list->size(); ++i) {
+      protocol::DictionaryValue* current_value =
+          static_cast<protocol::DictionaryValue*>(row_or_column_list->at(i));
+
+      WTF::String string_value;
+      EXPECT_TRUE(current_value->getString("name", &string_value));
+
+      EXPECT_EQ(expected_names[i], string_value);
+    }
+  };
+
+  protocol::ListValue* row_info = info->getArray("rowLineNameOffsets");
+  EXPECT_EQ(row_info->size(), 6u);
+  WTF::Vector<WTF::String> expected_row_names = {"d", "e_sub", "e",
+                                                 "f", "d_sub", "f_sub"};
+  CompareLineNames(row_info, expected_row_names);
+
+  protocol::ListValue* column_info = info->getArray("columnLineNameOffsets");
+  EXPECT_EQ(column_info->size(), 6u);
+  WTF::Vector<WTF::String> expected_column_names = {"b", "a_sub", "b_sub",
+                                                    "c", "a",     "c_sub"};
+  CompareLineNames(column_info, expected_column_names);
+}
+
+TEST_F(InspectorHighlightTest, GridAreaNames) {
+  GetDocument().body()->setInnerHTML(R"HTML(
+    <style>
+    #grid {
+      display: grid;
+      grid-template-columns: 1fr 1fr 1fr;
+      grid-template-rows: 1fr 1fr 1fr;
+      grid-template-areas:
+            "a a a"
+            "b b b"
+            "c c c";
+    }
+    #subgrid {
+      display: grid;
+      grid-column: 1 / 4;
+      grid-row: 1 / 4;
+      grid-template-columns: subgrid;
+      grid-template-rows: subgrid;
+      grid-template-areas:
+            "d d d"
+            "e e e"
+            "f f f";
+    }
+    </style>
+    <div id="grid">
+      <div id="subgrid">
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+        <div class="griditem"></div>
+      </div>
+    </div>
+  )HTML");
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+
+  auto CompareAreaNames = [](protocol::DictionaryValue* area_names,
+                             WTF::Vector<WTF::String>& expected_names) -> void {
+    for (WTF::String& name : expected_names) {
+      EXPECT_TRUE(area_names->get(name));
+    }
+  };
+
+  Node* grid = GetDocument().getElementById(AtomicString("grid"));
+  EXPECT_TRUE(grid);
+  auto grid_info =
+      InspectorGridHighlight(grid, InspectorHighlight::DefaultGridConfig());
+  EXPECT_TRUE(grid_info);
+  protocol::DictionaryValue* grid_area_names =
+      grid_info->getObject("areaNames");
+  EXPECT_EQ(grid_area_names->size(), 3u);
+
+  WTF::Vector<WTF::String> expected_grid_area_names = {"a", "b", "c"};
+  CompareAreaNames(grid_area_names, expected_grid_area_names);
+
+  Node* subgrid = GetDocument().getElementById(AtomicString("subgrid"));
+  EXPECT_TRUE(subgrid);
+  auto subgrid_info =
+      InspectorGridHighlight(subgrid, InspectorHighlight::DefaultGridConfig());
+  EXPECT_TRUE(subgrid_info);
+
+  protocol::DictionaryValue* subgrid_area_names =
+      subgrid_info->getObject("areaNames");
+  EXPECT_EQ(subgrid_area_names->size(), 3u);
+
+  // TODO(kschmi): This should include "a", "b", and "c", but it's not
+  // currently. See TODO in `BuildAreaNamePaths`.
+  WTF::Vector<WTF::String> expected_subgrid_area_names = {"d", "e", "f"};
+  CompareAreaNames(subgrid_area_names, expected_subgrid_area_names);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/fragment_builder.cc b/third_party/blink/renderer/core/layout/fragment_builder.cc
index d05b4e4..03253fe 100644
--- a/third_party/blink/renderer/core/layout/fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/fragment_builder.cc
@@ -250,8 +250,18 @@
   PropagateSnapAreas(child);
   PropagateScrollStartTarget(child);
 
+  // Propagate info about OOF descendants if necessary. This part must be
+  // skipped when adding OOF children to fragmentainers, as propagation is
+  // special and performed manually from the OOF code in such cases, and cannot
+  // be done as part of adding child fragments. First of all, the parameters to
+  // PropagateOOFPositionedInfo() will be different from what we can provide
+  // here, and furthermore, OOFs in fragmentation are added by recreating
+  // fragmentainers, by adding old children and then appending new OOF
+  // children. This may take place in several passes (if there are nested OOFs
+  // that are discovered as part of laying out an outer OOF), and repropagating
+  // for OOFs that were laid out previously over and over again would be wrong.
   if (child.NeedsOOFPositionedInfoPropagation() &&
-      !disable_oof_descendants_propagation_) {
+      (!IsFragmentainerBoxType() || !child.IsOutOfFlowPositioned())) {
     LayoutUnit adjustment_for_oof_propagation =
         BlockOffsetAdjustmentForFragmentainer();
 
diff --git a/third_party/blink/renderer/core/layout/fragment_builder.h b/third_party/blink/renderer/core/layout/fragment_builder.h
index 53addfa..6e3a907 100644
--- a/third_party/blink/renderer/core/layout/fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/fragment_builder.h
@@ -299,10 +299,6 @@
   LayoutUnit BlockOffsetAdjustmentForFragmentainer(
       LayoutUnit fragmentainer_consumed_block_size = LayoutUnit()) const;
 
-  void SetDisableOOFDescendantsPropagation() {
-    disable_oof_descendants_propagation_ = true;
-  }
-
   bool HasOutOfFlowFragmentChild() const {
     return has_out_of_flow_fragment_child_;
   }
@@ -635,7 +631,6 @@
   bool should_add_break_tokens_manually_ = false;
   bool has_out_of_flow_fragment_child_ = false;
   bool has_out_of_flow_in_fragmentainer_subtree_ = false;
-  bool disable_oof_descendants_propagation_ = false;
 
 #if DCHECK_IS_ON()
   bool is_may_have_descendant_above_block_start_explicitly_set_ = false;
diff --git a/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h b/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h
index 381e8aa..59bdd84 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h
+++ b/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h
@@ -70,13 +70,13 @@
       const ComputedStyle& grid_item_style,
       GridTrackSizingDirection track_direction) const;
 
- private:
   const NamedGridLinesMap& ImplicitNamedLinesMap(
       GridTrackSizingDirection track_direction) const;
 
   const NamedGridLinesMap& ExplicitNamedLinesMap(
       GridTrackSizingDirection track_direction) const;
 
+ private:
   const NamedGridLinesMap& AutoRepeatLineNamesMap(
       GridTrackSizingDirection track_direction) const;
 
diff --git a/third_party/blink/renderer/core/layout/inline/inline_node.cc b/third_party/blink/renderer/core/layout/inline/inline_node.cc
index b820488..7b41ed43 100644
--- a/third_party/blink/renderer/core/layout/inline/inline_node.cc
+++ b/third_party/blink/renderer/core/layout/inline/inline_node.cc
@@ -943,8 +943,8 @@
   FontCachePurgePreventer font_cache_purge_preventer;
 
   String new_text(std::move(new_text_in));
-  layout_text->StyleRef().ApplyTextTransform(&new_text,
-                                             layout_text->PreviousCharacter());
+  new_text = layout_text->StyleRef().ApplyTextTransform(
+      new_text, layout_text->PreviousCharacter());
   layout_text->SetTextInternal(new_text);
 
   InlineNode node(editor.GetLayoutBlockFlow());
@@ -978,7 +978,6 @@
   if (!data->offset_mapping) {
     DCHECK(!data->text_content.IsNull());
     ComputeOffsetMapping(GetLayoutBlockFlow(), data);
-    DCHECK(data->offset_mapping);
   }
 
   return data->offset_mapping.Get();
@@ -1020,9 +1019,11 @@
   // TODO(xiaochengh): This doesn't compute offset mapping correctly when
   // text-transform CSS property changes text length.
   OffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder();
-  mapping_builder.SetDestinationString(data->text_content);
-  data->offset_mapping = mapping_builder.Build();
-  DCHECK(data->offset_mapping);
+  data->offset_mapping = nullptr;
+  if (mapping_builder.SetDestinationString(data->text_content)) {
+    data->offset_mapping = mapping_builder.Build();
+    DCHECK(data->offset_mapping);
+  }
 }
 
 const OffsetMapping* InlineNode::GetOffsetMapping(
@@ -1104,7 +1105,7 @@
   data.svg_node_data_ = svg_attr_builder.CreateSvgInlineNodeData();
 
   // Compute DOM offsets of text chunks.
-  mapping_builder.SetDestinationString(ifc_text_content);
+  CHECK(mapping_builder.SetDestinationString(ifc_text_content));
   OffsetMapping* mapping = mapping_builder.Build();
   StringView ifc_text_view(ifc_text_content);
   for (wtf_size_t i = 0; i < data.svg_node_data_->character_data_list.size();
@@ -1530,24 +1531,24 @@
     return;
 
   auto* first_line_items = MakeGarbageCollected<InlineItemsData>();
-  first_line_items->text_content = data->text_content;
+  String text_content = data->text_content;
   bool needs_reshape = false;
   if (first_line_style->TextTransform() != block_style->TextTransform()) {
     // TODO(kojii): This logic assumes that text-transform is applied only to
     // ::first-line, and does not work when the base style has text-transform
     // and ::first-line has different text-transform.
-    first_line_style->ApplyTextTransform(&first_line_items->text_content);
-    if (first_line_items->text_content != data->text_content) {
+    text_content = first_line_style->ApplyTextTransform(text_content);
+    if (text_content != data->text_content) {
       // TODO(kojii): When text-transform changes the length, we need to adjust
       // offset in InlineItem, or re-collect inlines. Other classes such as
       // line breaker need to support the scenario too. For now, we force the
       // string to be the same length to prevent them from crashing. This may
       // result in a missing or a duplicate character if the length changes.
-      TruncateOrPadText(&first_line_items->text_content,
-                        data->text_content.length());
+      TruncateOrPadText(&text_content, data->text_content.length());
       needs_reshape = true;
     }
   }
+  first_line_items->text_content = text_content;
 
   first_line_items->items.AppendVector(data->items);
   for (auto& item : first_line_items->items) {
diff --git a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc
index b578cfb..21ef27e 100644
--- a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc
+++ b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc
@@ -213,9 +213,17 @@
   return;
 }
 
-void OffsetMappingBuilder::SetDestinationString(String string) {
+bool OffsetMappingBuilder::SetDestinationString(const String& string) {
   DCHECK_EQ(destination_length_, string.length());
+  if (RuntimeEnabledFeatures::NoOffsetMappingForInconsistentTextEnabled() &&
+      destination_length_ != string.length()) {
+    // If we continue building an OffsetMapping with the inconsistent IFC text
+    // content, it might cause out-of-bounds accesses. It happens only if we
+    // have a bug, and we should fail safely.
+    return false;
+  }
   destination_string_ = string;
+  return true;
 }
 
 OffsetMapping* OffsetMappingBuilder::Build() {
diff --git a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h
index 81c6637..2015c60 100644
--- a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h
+++ b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h
@@ -119,7 +119,9 @@
                                        unsigned offset);
 
   // Set the destination string of the offset mapping.
-  void SetDestinationString(String);
+  // Returns false if the specified string is inconsistent with
+  // `destination_length_`. We can't build an OffstMapping in such case.
+  bool SetDestinationString(const String&);
 
   // Finalize and return the offset mapping.
   // This method can only be called once, as it can invalidate the stored data.
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 36260f4..2ea90a1 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -328,8 +328,8 @@
   float max_option_width = 0;
   if (!box.ShouldApplySizeContainment()) {
     for (auto* const option : select.GetOptionList()) {
-      String text = option->TextIndentedToRespectGroupLabel();
-      style.ApplyTextTransform(&text);
+      String text =
+          style.ApplyTextTransform(option->TextIndentedToRespectGroupLabel());
       // We apply SELECT's style, not OPTION's style because max_option_width is
       // used to determine intrinsic width of the menulist box.
       max_option_width =
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 2d83804..307fe766 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -715,16 +715,18 @@
 bool LayoutText::IsAllCollapsibleWhitespace() const {
   NOT_DESTROYED();
   unsigned length = TextLength();
-  if (Is8Bit()) {
+  if (text_.Is8Bit()) {
     for (unsigned i = 0; i < length; ++i) {
-      if (!StyleRef().IsCollapsibleWhiteSpace(Characters8()[i]))
+      if (!StyleRef().IsCollapsibleWhiteSpace(text_.Characters8()[i])) {
         return false;
+      }
     }
     return true;
   }
   for (unsigned i = 0; i < length; ++i) {
-    if (!StyleRef().IsCollapsibleWhiteSpace(Characters16()[i]))
+    if (!StyleRef().IsCollapsibleWhiteSpace(text_.Characters16()[i])) {
       return false;
+    }
   }
   return true;
 }
@@ -877,7 +879,7 @@
 void LayoutText::ApplyTextTransform() {
   NOT_DESTROYED();
   if (const ComputedStyle* style = Style()) {
-    style->ApplyTextTransform(&text_, PreviousCharacter());
+    text_ = style->ApplyTextTransform(text_, PreviousCharacter());
 
     // We use the same characters here as for list markers.
     // See CollectUACounterStyleRules() in ua_counter_style_map.cc.
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index f8a82e83..31c4bb0 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -130,29 +130,10 @@
 
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
 
-  bool Is8Bit() const {
-    NOT_DESTROYED();
-    return text_.Is8Bit();
-  }
-  const LChar* Characters8() const {
-    NOT_DESTROYED();
-    return text_.Characters8();
-  }
-  const UChar* Characters16() const {
-    NOT_DESTROYED();
-    return text_.Characters16();
-  }
   bool HasEmptyText() const {
     NOT_DESTROYED();
     return text_.empty();
   }
-  UChar CharacterAt(unsigned) const;
-  UChar UncheckedCharacterAt(unsigned) const;
-  UChar operator[](unsigned i) const {
-    NOT_DESTROYED();
-    return UncheckedCharacterAt(i);
-  }
-  UChar32 CodepointAt(unsigned) const;
   unsigned TextLength() const {
     NOT_DESTROYED();
     return text_.length();
@@ -448,28 +429,6 @@
   return first_fragment_item_index_;
 }
 
-inline UChar LayoutText::UncheckedCharacterAt(unsigned i) const {
-  SECURITY_DCHECK(i < TextLength());
-  return Is8Bit() ? Characters8()[i] : Characters16()[i];
-}
-
-inline UChar LayoutText::CharacterAt(unsigned i) const {
-  if (i >= TextLength())
-    return 0;
-
-  return UncheckedCharacterAt(i);
-}
-
-inline UChar32 LayoutText::CodepointAt(unsigned i) const {
-  if (i >= TextLength())
-    return 0;
-  if (Is8Bit())
-    return Characters8()[i];
-  UChar32 c;
-  U16_GET(Characters16(), 0, i, TextLength(), c);
-  return c;
-}
-
 inline void LayoutText::DetachAbstractInlineTextBoxesIfNeeded() {
   if (UNLIKELY(has_abstract_inline_text_box_))
     DetachAbstractInlineTextBoxes();
diff --git a/third_party/blink/renderer/core/layout/logical_box_fragment.cc b/third_party/blink/renderer/core/layout/logical_box_fragment.cc
index 2c20a74..6786198 100644
--- a/third_party/blink/renderer/core/layout/logical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/logical_box_fragment.cc
@@ -16,8 +16,14 @@
     FontBaseline baseline_type) const {
   // For checkbox and radio controls, we always use the border edge instead of
   // the margin edge.
-  if (physical_fragment_.Style().IsCheckboxOrRadioPart())
-    return FontHeight(margins.line_over + BlockSize(), margins.line_under);
+  if (physical_fragment_.Style().IsCheckboxOrRadioPart()) {
+    if (baseline_type == kAlphabeticBaseline) {
+      return FontHeight(margins.line_over + BlockSize(), margins.line_under);
+    }
+    // For a central baseline, center within the checkbox/radio part.
+    return FontHeight(margins.line_over + BlockSize() / 2,
+                      BlockSize() - BlockSize() / 2 + margins.line_under);
+  }
 
   absl::optional<LayoutUnit> baseline;
   switch (physical_fragment_.Style().BaselineSource()) {
diff --git a/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc
index 5e2a5c7..88e2d492 100644
--- a/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc
@@ -221,6 +221,10 @@
 
 const LayoutResult*
 SimplifiedLayoutAlgorithm::CreateResultAfterManualChildLayout() {
+  if (container_builder_.HasOutOfFlowFragmentainerDescendants()) {
+    container_builder_.AddMulticolWithPendingOOFs(Node());
+  }
+
   const LayoutResult* result = container_builder_.ToBoxFragment();
   if (result->GetPhysicalFragment().IsOutOfFlowPositioned()) {
     result->CopyMutableOutOfFlowData(previous_result_);
diff --git a/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc b/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc
index 134f5eb0d..b8da069a 100644
--- a/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc
@@ -26,7 +26,6 @@
   container_builder_.SetPageNameIfNeeded(previous_fragment.PageName());
   container_builder_.SetFragmentBlockSize(
       params.space.FragmentainerBlockSize());
-  container_builder_.SetDisableOOFDescendantsPropagation();
   container_builder_.SetHasOutOfFlowFragmentChild(true);
 
   const BlockBreakToken* old_fragment_break_token =
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 4082b53..1d4c9467 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1303,6 +1303,7 @@
                                        HistoryItem* previous_history_item,
                                        CommitReason commit_reason) {
   TRACE_EVENT("blink", "FrameLoader::CommitDocumentLoader");
+  base::ElapsedTimer timer;
   document_loader_ = document_loader;
   CHECK(document_loader_);
 
@@ -1341,6 +1342,8 @@
   Client()->TransitionToCommittedForNewPage();
 
   document_loader_->CommitNavigation();
+
+  base::UmaHistogramTimes("Blink.CommitDocumentLoaderTime", timer.Elapsed());
 }
 
 void FrameLoader::RestoreScrollPositionAndViewState() {
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 5c061d8..ab78e1ee 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -110,14 +110,12 @@
 struct SameSizeAsComputedStyleBase
     : public GarbageCollected<SameSizeAsComputedStyleBase> {
   SameSizeAsComputedStyleBase() {
-    base::debug::Alias(&data_refs);
     base::debug::Alias(&pointers);
     base::debug::Alias(&bitfields);
   }
 
  private:
-  void* data_refs[8];
-  Member<void*> pointers[1];
+  Member<void*> pointers[9];
   unsigned bitfields[5];
 };
 
@@ -1823,47 +1821,43 @@
 
 namespace {
 
-static void ApplyMathAutoTransform(String* text) {
-  if (text->length() != 1) {
-    return;
+String ApplyMathAutoTransform(const String& text) {
+  if (text.length() != 1) {
+    return text;
   }
-  UChar character = (*text)[0];
-  UChar32 transformed_char = ItalicMathVariant((*text)[0]);
+  UChar character = text[0];
+  UChar32 transformed_char = ItalicMathVariant(text[0]);
   if (transformed_char == static_cast<UChar32>(character)) {
-    return;
+    return text;
   }
 
   Vector<UChar> transformed_text(U16_LENGTH(transformed_char));
   int i = 0;
   U16_APPEND_UNSAFE(transformed_text, i, transformed_char);
-  *text = String(transformed_text);
+  return String(transformed_text);
 }
 
 }  // namespace
 
-void ComputedStyle::ApplyTextTransform(String* text,
-                                       UChar previous_character) const {
+String ComputedStyle::ApplyTextTransform(const String& text,
+                                         UChar previous_character) const {
   switch (TextTransform()) {
     case ETextTransform::kNone:
-      return;
+      return text;
     case ETextTransform::kCapitalize:
-      *text = Capitalize(*text, previous_character);
-      return;
+      return Capitalize(text, previous_character);
     case ETextTransform::kUppercase: {
       const LayoutLocale* locale = GetFontDescription().Locale();
       CaseMap case_map(locale ? locale->CaseMapLocale() : CaseMap::Locale());
-      *text = DisableNewGeorgianCapitalLetters(case_map.ToUpper(*text));
-      return;
+      return DisableNewGeorgianCapitalLetters(case_map.ToUpper(text));
     }
     case ETextTransform::kLowercase: {
       const LayoutLocale* locale = GetFontDescription().Locale();
       CaseMap case_map(locale ? locale->CaseMapLocale() : CaseMap::Locale());
-      *text = case_map.ToLower(*text);
-      return;
+      return case_map.ToLower(text);
     }
     case ETextTransform::kMathAuto:
-      ApplyMathAutoTransform(text);
-      return;
+      return ApplyMathAutoTransform(text);
   }
   NOTREACHED();
 }
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 925b9bc6..c2426d3 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -1144,7 +1144,8 @@
   bool ShouldUseTextIndent(bool is_first_line) const;
 
   // text-transform utility functions.
-  void ApplyTextTransform(String*, UChar previous_character = ' ') const;
+  [[nodiscard]] String ApplyTextTransform(const String&,
+                                          UChar previous_character = ' ') const;
 
   // Line-height utility functions.
   const Length& SpecifiedLineHeight() const { return LineHeightInternal(); }
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 e3ac18e0..c0901434 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
@@ -51,6 +51,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
 #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
 #include "third_party/blink/renderer/platform/graphics/video_frame_sink_bundle.h"
+#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
 #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 #include "third_party/blink/renderer/platform/p2p/empty_network_manager.h"
@@ -443,8 +444,8 @@
   context.GetBrowserInterfaceBroker().GetInterface(
       perf_recorder.InitWithNewPipeAndPassReceiver());
 
-  webrtc_video_perf_reporter_.Initialize(
-      context.GetTaskRunner(TaskType::kInternalMedia),
+  webrtc_video_perf_reporter_ = MakeGarbageCollected<WebrtcVideoPerfReporter>(
+      context.GetTaskRunner(TaskType::kInternalMedia), &context,
       std::move(perf_recorder));
 }
 
@@ -626,7 +627,7 @@
       base::FeatureList::IsEnabled(features::kWebRtcSendPacketBatch));
 
   gpu_factories_ = gpu_factories;
-  // base::Unretained is safe below, because
+  // WrapCrossThreadWeakPersistent is safe below, because
   // PeerConnectionDependencyFactory (that holds `webrtc_video_perf_reporter_`)
   // outlives the encoders and decoders that are using the callback. The
   // lifetime of PeerConnectionDependencyFactory is tied to the ExecutionContext
@@ -637,13 +638,15 @@
       blink::CreateWebrtcVideoEncoderFactory(
           gpu_factories, std::move(video_encoder_metrics_provider_factory),
           base::BindRepeating(&WebrtcVideoPerfReporter::StoreWebrtcVideoStats,
-                              base::Unretained(&webrtc_video_perf_reporter_)));
+                              WrapCrossThreadWeakPersistent(
+                                  webrtc_video_perf_reporter_.Get())));
   std::unique_ptr<webrtc::VideoDecoderFactory> webrtc_decoder_factory =
       blink::CreateWebrtcVideoDecoderFactory(
           gpu_factories, media_decoder_factory, std::move(media_task_runner),
           render_color_space,
           base::BindRepeating(&WebrtcVideoPerfReporter::StoreWebrtcVideoStats,
-                              base::Unretained(&webrtc_video_perf_reporter_)));
+                              WrapCrossThreadWeakPersistent(
+                                  webrtc_video_perf_reporter_.Get())));
 
   // Enable Multiplex codec in SDP optionally.
   if (base::FeatureList::IsEnabled(blink::features::kWebRtcMultiplexCodec)) {
@@ -903,7 +906,6 @@
 void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DVLOG(1) << "PeerConnectionDependencyFactory::CleanupPeerConnectionFactory()";
-  webrtc_video_perf_reporter_.Shutdown();
   socket_factory_ = nullptr;
   // Not obtaining `signaling_thread` using GetWebRtcSignalingTaskRunner()
   // because that method triggers EnsureInitialized() and we're trying to
@@ -1013,5 +1015,7 @@
   Supplement<ExecutionContext>::Trace(visitor);
   ExecutionContextLifecycleObserver::Trace(visitor);
   visitor->Trace(p2p_socket_dispatcher_);
+  visitor->Trace(webrtc_video_perf_reporter_);
 }
+
 }  // namespace blink
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 a4200ef4..e17bf1b6 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
@@ -20,7 +20,6 @@
 #include "third_party/blink/renderer/platform/heap/prefinalizer.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 #include "third_party/blink/renderer/platform/supplementable.h"
-#include "third_party/blink/renderer/platform/wtf/gc_plugin.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "third_party/webrtc/api/async_dns_resolver.h"
@@ -198,6 +197,8 @@
   std::unique_ptr<IpcNetworkManager> network_manager_;
   std::unique_ptr<IpcPacketSocketFactory> socket_factory_;
 
+  Member<WebrtcVideoPerfReporter> webrtc_video_perf_reporter_;
+
   rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
 
   // Dispatches all P2P sockets.
@@ -208,9 +209,6 @@
   raw_ptr<media::GpuVideoAcceleratorFactories, ExperimentalRenderer>
       gpu_factories_;
 
-  GC_PLUGIN_IGNORE("https://crbug.com/1381979")
-  WebrtcVideoPerfReporter webrtc_video_perf_reporter_;
-
   THREAD_CHECKER(thread_checker_);
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc
index 6f5445b..cee2a22 100644
--- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc
@@ -10,28 +10,15 @@
 
 namespace blink {
 
-WebrtcVideoPerfReporter::WebrtcVideoPerfReporter() {
-  weak_this_ = weak_factory_.GetWeakPtr();
-}
-
-WebrtcVideoPerfReporter::~WebrtcVideoPerfReporter() {
-  // `task_runner_` may not be set in some unit tests of other features.
-  DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
-}
-
-void WebrtcVideoPerfReporter::Shutdown() {
-  // `task_runner_` may not be set in some unit tests of other features.
-  DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-void WebrtcVideoPerfReporter::Initialize(
+WebrtcVideoPerfReporter::WebrtcVideoPerfReporter(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    ContextLifecycleNotifier* notifier,
     mojo::PendingRemote<media::mojom::blink::WebrtcVideoPerfRecorder>
-        perf_recorder) {
+        perf_recorder)
+    : perf_recorder_(notifier) {
   task_runner_ = task_runner;
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
-  perf_recorder_.Bind(std::move(perf_recorder));
+  perf_recorder_.Bind(std::move(perf_recorder), task_runner_);
 }
 
 void WebrtcVideoPerfReporter::StoreWebrtcVideoStats(
@@ -42,7 +29,7 @@
       FROM_HERE,
       base::BindOnce(
           &WebrtcVideoPerfReporter::StoreWebrtcVideoStatsOnTaskRunner,
-          weak_this_, stats_key, video_stats));
+          WrapWeakPersistent(this), stats_key, video_stats));
 }
 
 void WebrtcVideoPerfReporter::StoreWebrtcVideoStatsOnTaskRunner(
@@ -51,6 +38,10 @@
   DCHECK(task_runner_);
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
+  if (!perf_recorder_.is_bound()) {
+    return;
+  }
+
   auto mojo_features = media::mojom::blink::WebrtcPredictionFeatures::New(
       stats_key.is_decode,
       static_cast<media::mojom::blink::VideoCodecProfile>(
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h
index 2bbbb188..784b934 100644
--- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h
@@ -8,41 +8,41 @@
 #include "base/task/single_thread_task_runner.h"
 #include "media/base/video_codecs.h"
 #include "media/mojo/mojom/webrtc_video_perf.mojom-blink.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
 #include "third_party/blink/renderer/platform/peerconnection/stats_collector.h"
 
 namespace blink {
 
+class ContextLifecycleNotifier;
+
 // This class is used for WebRTC video performance stats data collection. Its
 // sole purpose is to pass data collected in the render process to the browser
 // process where the data is stored to a local database. The data is later used
 // for smoothness predictions when the MediaCapabilities API receives a query
 // for a particular video configuration.
-class MODULES_EXPORT WebrtcVideoPerfReporter {
+class MODULES_EXPORT WebrtcVideoPerfReporter
+    : public GarbageCollected<WebrtcVideoPerfReporter> {
  public:
-  WebrtcVideoPerfReporter();
-  ~WebrtcVideoPerfReporter();
-
-  void Initialize(
+  WebrtcVideoPerfReporter(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      ContextLifecycleNotifier* notifier,
       mojo::PendingRemote<media::mojom::blink::WebrtcVideoPerfRecorder>
           perf_recorder);
 
   void StoreWebrtcVideoStats(const StatsCollector::StatsKey& stats_key,
                              const StatsCollector::VideoStats& video_stats);
 
-  void Shutdown();
+  void Trace(Visitor* visitor) const { visitor->Trace(perf_recorder_); }
 
  private:
   void StoreWebrtcVideoStatsOnTaskRunner(
       const StatsCollector::StatsKey& stats_key,
       const StatsCollector::VideoStats& video_stats);
 
-  base::WeakPtr<WebrtcVideoPerfReporter> weak_this_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  mojo::Remote<media::mojom::blink::WebrtcVideoPerfRecorder> perf_recorder_;
-  base::WeakPtrFactory<WebrtcVideoPerfReporter> weak_factory_{this};
+  HeapMojoRemote<media::mojom::blink::WebrtcVideoPerfRecorder> perf_recorder_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc
index b54127f9..48d4a66 100644
--- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc
@@ -46,15 +46,15 @@
  public:
   WebrtcVideoPerfReporterTest() {
     mock_recorder_ = std::make_unique<MockWebrtcVideoPerfRecorder>();
-    reporter_.Initialize(
+    reporter_ = MakeGarbageCollected<WebrtcVideoPerfReporter>(
         blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
-        mock_recorder_->CreatePendingRemote());
+        /* notifier */ nullptr, mock_recorder_->CreatePendingRemote());
   }
 
  protected:
   test::TaskEnvironment task_environment_;
   std::unique_ptr<MockWebrtcVideoPerfRecorder> mock_recorder_;
-  WebrtcVideoPerfReporter reporter_;
+  Persistent<WebrtcVideoPerfReporter> reporter_;
 };
 
 TEST_F(WebrtcVideoPerfReporterTest, StoreWebrtcVideoStats) {
@@ -78,7 +78,7 @@
         EXPECT_EQ(kExpectedFeaturesA, *features);
         EXPECT_EQ(kExpectedVideoStats, *video_stats);
       });
-  reporter_.StoreWebrtcVideoStats(kStatsKeyA, kVideoStats);
+  reporter_->StoreWebrtcVideoStats(kStatsKeyA, kVideoStats);
   base::RunLoop().RunUntilIdle();
 
   // Toggle the booleans.
@@ -97,7 +97,7 @@
         EXPECT_EQ(kExpectedFeaturesB, *features);
         EXPECT_EQ(kExpectedVideoStats, *video_stats);
       });
-  reporter_.StoreWebrtcVideoStats(kStatsKeyB, kVideoStats);
+  reporter_->StoreWebrtcVideoStats(kStatsKeyB, kVideoStats);
   base::RunLoop().RunUntilIdle();
 }
 
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
index 4950372..5dadc933 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
+++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -579,7 +579,7 @@
       return "2d";
     case WGPUTextureDimension_3D:
       return "3d";
-    case WGPUTextureDimension_Force32:
+    default:
       NOTREACHED();
   }
   return "";
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
index a2d10ed5..ad0a62b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -36,6 +36,10 @@
 
   *out = {};
   out->view = in->view()->GetHandle();
+  out->depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
+  if (in->hasDepthSlice()) {
+    out->depthSlice = in->depthSlice();
+  }
   if (in->hasResolveTarget()) {
     out->resolveTarget = in->resolveTarget()->GetHandle();
   }
@@ -52,6 +56,30 @@
 namespace {
 
 // Dawn represents `undefined` as the special uint32_t value
+// WGPU_DEPTH_SLICE_UNDEFINED (0xFFFF'FFFF). Blink must make sure that an
+// actual value of 0xFFFF'FFFF coming in from JS is not treated as
+// WGPU_DEPTH_SLICE_UNDEFINED, so it injects an error in that case.
+std::string ValidateColorAttachmentsDepthSlice(
+    const HeapVector<Member<GPURenderPassColorAttachment>>& in) {
+  for (wtf_size_t i = 0; i < in.size(); ++i) {
+    if (!in[i]) {
+      continue;
+    }
+
+    const GPURenderPassColorAttachment* attachment = in[i].Get();
+    if (attachment->hasDepthSlice() &&
+        attachment->depthSlice() == WGPU_DEPTH_SLICE_UNDEFINED) {
+      std::ostringstream error;
+      error << "depthSlice (" << attachment->depthSlice()
+            << ") in colorAttachments[" << i << "] is too large";
+      return error.str();
+    }
+  }
+
+  return std::string();
+}
+
+// Dawn represents `undefined` as the special uint32_t value
 // WGPU_QUERY_SET_INDEX_UNDEFINED (0xFFFF'FFFF). Blink must make sure that an
 // actual value of 0xFFFF'FFFF coming in from JS is not treated as
 // WGPU_QUERY_SET_INDEX_UNDEFINED, so it injects an error in that case.
@@ -195,6 +223,13 @@
   std::unique_ptr<WGPURenderPassColorAttachment[]> color_attachments;
   dawn_desc.colorAttachmentCount = descriptor->colorAttachments().size();
   if (dawn_desc.colorAttachmentCount > 0) {
+    std::string error =
+        ValidateColorAttachmentsDepthSlice(descriptor->colorAttachments());
+    if (!error.empty()) {
+      GetProcs().commandEncoderInjectValidationError(GetHandle(),
+                                                     error.c_str());
+    }
+
     if (!ConvertToDawn(descriptor->colorAttachments(), &color_attachments,
                        exception_state)) {
       return nullptr;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl
index 638e1f18..08a7c8c 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl
@@ -6,6 +6,7 @@
 
 dictionary GPURenderPassColorAttachment {
     required GPUTextureView view;
+    GPUSize32 depthSlice;
     GPUTextureView resolveTarget;
 
     GPUColor clearValue;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 9ba3fc49..ccf5dd6 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2581,6 +2581,10 @@
       name: "NonStandardAppearanceValuesLowUsage",
     },
     {
+      name: "NoOffsetMappingForInconsistentText",
+      status: "stable",
+    },
+    {
       name: "NotificationConstructor",
       // Android won't be able to reliably support non-persistent notifications, the
       // intended behavior for which is in flux by itself.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index d7a60ab0..c3e4b9f9 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1512,19 +1512,6 @@
 # Bug in <select multiple> tap behavior:
 crbug.com/1045672 fast/forms/select/listbox-tap.html [ Failure ]
 
-# ========== Unload deprecation pending
-
-# unload-deprecate is a large virtual test suite. Rather than adding
-# the tests one-by-one (which requires a VirtualTestSuites-owner
-# review for each CL), they have been added as "Skip". They will be
-# removed from this section as we address each one as part of
-# https://crbug.com/1488371.
-# See https://docs.google.com/document/d/1FH0iG8G8mEebjMpVA_zvSfHBWUhWqC92jRFctaGcxrc/edit#heading=h.pacsgp238vkn
-
-crbug.com/1488371 virtual/deprecate-unload/http/tests/navigation/image-load-in-unload-handler.html [ Failure Skip Timeout ]
-
-# ========== End of Unload deprecation pending
-
 ######## Unload Deprecation
 # This is for tests in the "deprecate-unload" virtual suite that
 # cannot be fixed and require a timeout expecation.
@@ -2663,10 +2650,6 @@
 crbug.com/626703 external/wpt/screen-orientation/lock-unlock-check.html [ Timeout ]
 crbug.com/626703 [ Win10.20h2 ] external/wpt/fledge/tentative/direct-from-seller-signals.https.window.html?6-10 [ Skip Timeout ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-095.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html [ Failure ]
 crbug.com/626703 external/wpt/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html [ Failure ]
 crbug.com/626703 external/wpt/svg/color-inherit-link-visited.svg [ Failure ]
 crbug.com/626703 external/wpt/html/semantics/forms/the-input-element/input-type-checkbox-switch.tentative.window.html [ Failure ]
@@ -5144,6 +5127,7 @@
 crbug.com/1509336 http/tests/devtools/har-importer.js [ Failure Pass ]
 crbug.com/1509336 http/tests/devtools/network/json-preview.js [ Failure Pass ]
 crbug.com/1509336 http/tests/devtools/network/network-choose-preview-view.js [ Failure Pass ]
+crbug.com/1509336 http/tests/devtools/network/network-xhr-binary-content.js [ Failure Pass ]
 
 # Possible Interop PE 2024 investigation
 crbug.com/1495467 external/wpt/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=LEFT&button=0&buttons=1 [ Failure ]
@@ -5209,9 +5193,6 @@
 crbug.com/1299948 [ Mac12 ] external/wpt/css/css-tables/crashtests/textarea-intrinsic-size-crash.html [ Pass Timeout ]
 crbug.com/1299972 [ Linux ] screen_orientation/screenorientation-unsupported-no-crash.html [ Failure Pass Timeout ]
 
-# Disabled temporarily to land https://crrev.com/c/5134807
-crbug.com/1509340 http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js [ Failure Pass ]
-
 # Disable flaky test for further investigation
 crbug.com/1229801 http/tests/devtools/elements/css-rule-hover-highlights-selectors.js [ Failure Pass ]
 
@@ -6270,7 +6251,6 @@
 [ Debug Mac13 ] jquery/traversing.html [ Skip Timeout ]
 [ Debug Mac13 ] external/wpt/html/interaction/focus/chrome-object-tab-focus-bug.html [ Failure ]
 [ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/sandbox-attribute.https.html [ Failure ]
-[ Debug Mac13 ] accessibility/selection-change-notification-on-selection-removed.html [ Failure ]
 [ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.worker.html [ Failure ]
 [ Debug Mac13 ] external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
 [ Debug Mac13 ] http/tests/devtools/sources/debugger-breakpoints/breakpoint-manager-listeners-count.js [ Failure ]
@@ -6880,3 +6860,6 @@
 # TODO(crbug.com/1496375): Re-enable these tests.
 crbug.com/1496375 [ Linux ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ]
 crbug.com/1496375 [ Mac ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ]
+
+# Gardener 2023-12-20
+[ Mac ] accessibility/selection-change-notification-on-selection-removed.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 29e9eac..dade4ad 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2508,7 +2508,6 @@
       "http/tests/inspector-protocol/permissions-policy.js",
       "http/tests/navigation/history-back-across-form-submission-to-fragment.html",
       "http/tests/navigation/image-css-load-in-subframe-unload-handler.html",
-      "http/tests/navigation/image-load-in-unload-handler.html",
       "http/tests/navigation/redirect-on-back-updates-history-item.html",
       "http/tests/navigation/redirect-on-reload-updates-history-item.html",
       "http/tests/navigation/targeted-navigation-in-unload-handler.html",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html
new file mode 100644
index 0000000..6b9427d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1501713">
+<div style="columns:2; column-fill:auto; height:100px; will-change:transform;">
+  <div style="columns:2; column-fill:auto;">
+    <div style="position:relative;">
+      <div style="position:absolute; height:150px;">
+        <div id="trouble" style="position:fixed; height:50px;"></div>
+      </div>
+    </div>
+  </div>
+</div>
+<script>
+  document.body.offsetHeight;
+  trouble.style.width = "2px";
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html
index c3f61075..a43403c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The checkbox should be center-aligned with the label text.</p>
+<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p>
 <div style="writing-mode: vertical-lr">
     <input type="checkbox" id="checkbox" checked>
     <label for="checkbox">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-lr; text-orientation: sideways;">
+  <input type="checkbox" id="checkbox" checked>
+  <label for="checkbox">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html
index b19de13..377a8e8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The checkbox should be center-aligned with the label text.</p>
+<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p>
 <div style="writing-mode: vertical-lr">
     <input type="checkbox" id="checkbox" checked>
     <label for="checkbox">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-lr; text-orientation: sideways;">
+  <input type="checkbox" id="checkbox" checked>
+  <label for="checkbox">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html
index a253a71d..7fe6db340 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The checkbox should be center-aligned with the label text.</p>
+<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p>
 <div style="writing-mode: vertical-rl">
     <input type="checkbox" id="checkbox" checked>
     <label for="checkbox">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-rl; text-orientation: sideways;">
+  <input type="checkbox" id="checkbox" checked>
+  <label for="checkbox">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html
index 3efb211..630a83c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The checkbox should be center-aligned with the label text.</p>
+<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p>
 <div style="writing-mode: vertical-rl">
     <input type="checkbox" id="checkbox" checked>
     <label for="checkbox">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-rl; text-orientation: sideways;">
+  <input type="checkbox" id="checkbox" checked>
+  <label for="checkbox">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html
index 9b09537c9..6fca0762 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The radio button should be center-aligned with the label text.</p>
+<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p>
 <div style="writing-mode: vertical-lr">
     <input type="radio" id="radio" checked>
     <label for="radio">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-lr; text-orientation: sideways;">
+  <input type="radio" id="radio" checked>
+  <label for="radio">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html
index 8d5bf75f..c7810034 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The radio button should be center-aligned with the label text.</p>
+<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p>
 <div style="writing-mode: vertical-lr">
     <input type="radio" id="radio" checked>
     <label for="radio">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-lr; text-orientation: sideways;">
+  <input type="radio" id="radio" checked>
+  <label for="radio">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html
index 95871a51..9e5dda82 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The radio button should be center-aligned with the label text.</p>
+<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p>
 <div style="writing-mode: vertical-rl">
     <input type="radio" id="radio" checked>
     <label for="radio">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-rl; text-orientation: sideways;">
+  <input type="radio" id="radio" checked>
+  <label for="radio">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html
index 4c5a59a0..6f7eed7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html
@@ -14,8 +14,16 @@
 }
 
 </style>
-<p>The radio button should be center-aligned with the label text.</p>
+<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p>
 <div style="writing-mode: vertical-rl">
     <input type="radio" id="radio" checked>
     <label for="radio">こんにちわ</label>
 </div>
+
+<br>
+
+<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p>
+<div style="writing-mode: vertical-rl; text-orientation: sideways;">
+  <input type="radio" id="radio" checked>
+  <label for="radio">Baseline</label>
+</div>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt
index 18cf94d..6695740 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt
@@ -2,29 +2,29 @@
 Expression `document.querySelector('div').x = "foo"`
 has side effect: true, expected: true
 Expression `$('div')`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `$$('div')`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `$x('//div')`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `getEventListeners(document)`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `$.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `$$.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `$x.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `getEventListeners.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `monitorEvents()`
 has side effect: true, expected: true
 Expression `unmonitorEvents()`
 has side effect: true, expected: true
 Expression `monitorEvents.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `unmonitorEvents.toString()`
-has side effect: false, expected: false
+has side effect: true, expected: true
 Expression `document.getElementsByTagName('div')`
 has side effect: false, expected: false
 Expression `document.getElementsByTagNameNS(namespace, 'div')`
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js
index 3333f3a..28a112d8 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js
@@ -37,20 +37,20 @@
   await checkHasSideEffect(`document.querySelector('div').x = "foo"`);
 
   // Command Line API
-  await checkHasNoSideEffect(`$('div')`);
-  await checkHasNoSideEffect(`$$('div')`);
-  await checkHasNoSideEffect(`$x('//div')`);
-  await checkHasNoSideEffect(`getEventListeners(document)`);
-  await checkHasNoSideEffect(`$.toString()`);
-  await checkHasNoSideEffect(`$$.toString()`);
-  await checkHasNoSideEffect(`$x.toString()`);
-  await checkHasNoSideEffect(`getEventListeners.toString()`);
+  await checkHasSideEffect(`$('div')`);
+  await checkHasSideEffect(`$$('div')`);
+  await checkHasSideEffect(`$x('//div')`);
+  await checkHasSideEffect(`getEventListeners(document)`);
+  await checkHasSideEffect(`$.toString()`);
+  await checkHasSideEffect(`$$.toString()`);
+  await checkHasSideEffect(`$x.toString()`);
+  await checkHasSideEffect(`getEventListeners.toString()`);
 
   // Unsafe Command Line API
   await checkHasSideEffect(`monitorEvents()`);
   await checkHasSideEffect(`unmonitorEvents()`);
-  await checkHasNoSideEffect(`monitorEvents.toString()`);
-  await checkHasNoSideEffect(`unmonitorEvents.toString()`);
+  await checkHasSideEffect(`monitorEvents.toString()`);
+  await checkHasSideEffect(`unmonitorEvents.toString()`);
 
   // Document
   await checkHasNoSideEffect(`document.getElementsByTagName('div')`);
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt
new file mode 100644
index 0000000..71c4b3e
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt
@@ -0,0 +1,3 @@
+Ping sent successfully
+HTTP_REFERER: http://127.0.0.1:8000/navigation/image-load-in-pagehide-handler.html
+REQUEST_METHOD: GET
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html
similarity index 67%
rename from third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html
rename to third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html
index d872a82..aa60cbc6 100644
--- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html
+++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html
@@ -2,7 +2,7 @@
 <html>
 
 <head>
-  <title>Image load in unload handler</title>
+  <title>Image load in pagehide handler</title>
   <script>
     // We need to ensure that other instances of this test running in parallel
     // (e.g. in a virtual suite) do not interfere.
@@ -15,32 +15,32 @@
 
     async function test() {
 
-      const response = await fetch(`resources/delete-ping.php?test=unload-image-${key}`);
+      const response = await fetch(`resources/delete-ping.php?test=pagehide-image-${key}`);
       if (response.ok) {
         // We can't go to check-ping.php directly, since that doesn't start sending
-        // a response until the ping data is detected, but unload handlers (where
+        // a response until the ping data is detected, but pagehide handlers (where
         // we send the ping) are only run once we've begun receiving data from the
         // page being navigated to. Instead, we go through a dummy redirect page,
-        // to make sure that the onunload handler has run before we get to
+        // to make sure that the onpagehide handler has run before we get to
         // check-ping.php.
-        location.assign(`resources/ping-redirect.html?test=unload-image-${key}`);
+        location.assign(`resources/ping-redirect.html?test=pagehide-image-${key}`);
       }
     }
 
     function ping() {
       var img = new Image(1, 1);
-      img.src = `resources/save-Ping.php?test=unload-image-${key}`
+      img.src = `resources/save-Ping.php?test=pagehide-image-${key}`
     }
 
   </script>
 </head>
 
-<body onload="test();" onunload="ping();">
+<body onload="test();" onpagehide="ping();">
   Test case for https://bugs.webkit.org/show_bug.cgi?id=30457. Previously, if an image<br>
-  load was trigger from an unload handler, we would kill it almost immediately due to the<br>
+  load was trigger from an pagehide handler, we would kill it almost immediately due to the<br>
   navigation stopping all loaders. These loads now happen entirely in the background and detached<br>
   from the DOM, so they're invisible to the normal resource load callback infrastructure. We generate a<br>
-  timestamp, then in the unload handler, we load an 'image' (actually a php script) that takes the<br>
+  timestamp, then in the pagehide handler, we load an 'image' (actually a php script) that takes the<br>
   timestamp as a parameter and saves it to a file. The destination page is a php script that checks for<br>
   the existence of that file and passes the test if the file contains the expected timestamp.<br>
 </body>
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt
deleted file mode 100644
index 05f1e2a..0000000
--- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Ping sent successfully
-HTTP_REFERER: http://127.0.0.1:8000/navigation/image-load-in-unload-handler.html
-REQUEST_METHOD: GET
diff --git a/third_party/dawn b/third_party/dawn
index 667f56e..4d6794a 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit 667f56eab3feb5ed6aa40dd9b2319b3fb784f1f6
+Subproject commit 4d6794a7625867209adaaf3839b6969578acea2f
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 3900055..007dd45 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 390005586bde14be9b55fde71ca4ae2107021ac9
+Subproject commit 007dd45a94b8fe400fb69113f7999fed185cb5c1
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 7a46eb1..c415910 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 7a46eb1458616c7271b7aa5787a8ae89c800bc34
+Subproject commit c41591023f94b09a395d82d1c8bf571ead6895b2
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 5fad45b..d757184 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 5fad45b99a7ca290b0e36ca81f0074589ee2ef9b
+Subproject commit d7571848c16a0ff89d4964c838dc44e0ce915049
diff --git a/third_party/gvr-android-sdk/BUILD.gn b/third_party/gvr-android-sdk/BUILD.gn
deleted file mode 100644
index 2a6ded8..0000000
--- a/third_party/gvr-android-sdk/BUILD.gn
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2016 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-import("//build/config/c++/c++.gni")
-import("//device/vr/buildflags/buildflags.gni")
-
-assert(enable_vr)
-
-android_aar_prebuilt("controller_test_api_java") {
-  testonly = true
-  aar_path = "test-libraries/controller_test_api.aar"
-  proguard_configs = [ "test-libraries/proguard.txt" ]
-
-  # Jar includes conflicting copies of Desugar-runtime.jar classes.
-  # Includes conflicting copy from j2objc/annotations.
-  # Errorprone annotations conflicts with doubledown!material_design.
-  jar_excluded_patterns = [
-    "*ThrowableExtension*.class",
-    "*j2objc/annotations*",
-    "com/google/errorprone/annotations*",
-  ]
-
-  deps = [
-    ":gvr_common_java",
-    "//third_party/android_deps:guava_android_java",
-  ]
-}
-
-android_aar_prebuilt("gvr_common_java") {
-  aar_path = "src/libraries/sdk-common-1.130.0.aar"
-  proguard_configs = [
-    "src/proguard-gvr.txt",
-    "proguard-gvr-chromium.txt",
-  ]
-  ignore_native_libraries = true
-  deps = [ "//third_party/android_protobuf:protobuf_nano_javalib" ]
-}
-
-android_aar_prebuilt("gvr_controller_java") {
-  aar_path = "src/libraries/sdk-controller-1.130.0.aar"
-  deps = [ ":gvr_common_java" ]
-}
-
-config("libgvr_config") {
-  include_dirs = [ "src/libraries/headers/" ]
-}
-
-component("gvr_shim") {
-  libs = [
-    "android",
-    "log",
-  ]
-  if (enable_chrome_android_internal && !is_official_build) {
-    deps = [ "//clank/third_party/gvr_shim" ]
-  } else {
-    if (use_relative_vtables_abi) {
-      _vtables = "_vtables"
-    } else {
-      _vtables = ""
-    }
-    library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}${_vtables}.a"
-    libs += [ library ]
-
-    if (libcxx_is_shared) {
-      ldflags = [
-        "-Wl,--whole-archive",
-        rebase_path(library, root_build_dir),
-        "-Wl,--no-whole-archive",
-      ]
-    }
-  }
-}
diff --git a/third_party/gvr-android-sdk/DEPS b/third_party/gvr-android-sdk/DEPS
deleted file mode 100644
index 978e204..0000000
--- a/third_party/gvr-android-sdk/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-include_rules = [
-  '+base/android/jni_android.h',
-  '+third_party/jni_zero/jni_int_wrapper.h',
-  '+third_party/jni_zero/jni_zero_helper.h',
-]
diff --git a/third_party/gvr-android-sdk/DIR_METADATA b/third_party/gvr-android-sdk/DIR_METADATA
deleted file mode 100644
index 4aece69..0000000
--- a/third_party/gvr-android-sdk/DIR_METADATA
+++ /dev/null
@@ -1,5 +0,0 @@
-monorail {
-  component: "Internals>XR>VR"
-}
-team_email: "xr-dev@chromium.org"
-os: ANDROID
diff --git a/third_party/gvr-android-sdk/LICENSE b/third_party/gvr-android-sdk/LICENSE
deleted file mode 100644
index a2945f2..0000000
--- a/third_party/gvr-android-sdk/LICENSE
+++ /dev/null
@@ -1,7943 +0,0 @@
-   Copyright (c) 2015, Google Inc.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-====================
-Open Source Licenses
-====================
-
-This software may use portions of the following libraries subject to the accompanying licenses:
-
-****************************
-chromium_audio
-****************************
-// Copyright 2014 The Chromium Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-curl
-****************************
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1996 - 2014, Daniel Stenberg, <daniel@haxx.se>.
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software for any purpose
-with or without fee is hereby granted, provided that the above copyright
-notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
-NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not
-be used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization of the copyright holder.
-
-
-****************************
-dynamic_annotations
-****************************
-Copyright (c) 2008-2009, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-eigen3
-****************************
-Eigen is primarily MPL2 licensed. See COPYING.MPL2 and these links:
-  http://www.mozilla.org/MPL/2.0/
-  http://www.mozilla.org/MPL/2.0/FAQ.html
-
-Some files contain third-party code under BSD or LGPL licenses, whence
-the other COPYING.* files here.
-
-All the LGPL code is either LGPL 2.1-only, or LGPL 2.1-or-later.
-For this reason, the COPYING.LGPL file contains the LGPL 2.1 text.
-
-If you want to guarantee that the Eigen code that you are #including
-is licensed under the MPL2 and possibly more permissive licenses (like
-BSD), #define this preprocessor symbol: EIGEN_MPL2_ONLY
-For example, with most compilers, you could add this to your project
-      CXXFLAGS: -DEIGEN_MPL2_ONLY
-This will cause a compilation error to be generated if you #include
-any code that is LGPL licensed.
-
-----------------------------------------------------------------------
-Following applies to:
-./test/mapstaticmethods.cpp
-./test/schur_real.cpp
-./test/prec_inverse_4x4.cpp
-./test/smallvectors.cpp
-./test/redux.cpp
-./test/special_numbers.cpp
-./test/adjoint.cpp
-./test/resize.cpp
-./test/mixingtypes.cpp
-./test/product_trmv.cpp
-./test/sparse_solvers.cpp
-./test/cholesky.cpp
-./test/geo_quaternion.cpp
-./test/miscmatrices.cpp
-./test/stddeque.cpp
-./test/integer_types.cpp
-./test/product_large.cpp
-./test/eigensolver_generic.cpp
-./test/householder.cpp
-./test/geo_orthomethods.cpp
-./test/array_for_matrix.cpp
-./test/sparseLM.cpp
-./test/upperbidiagonalization.cpp
-./test/nomalloc.cpp
-./test/packetmath.cpp
-./test/jacobisvd.cpp
-./test/geo_transformations.cpp
-./test/swap.cpp
-./test/eigensolver_selfadjoint.cpp
-./test/inverse.cpp
-./test/product_selfadjoint.cpp
-./test/product_trsolve.cpp
-./test/product_extra.cpp
-./test/sparse_solver.h
-./test/mapstride.cpp
-./test/mapped_matrix.cpp
-./test/geo_eulerangles.cpp
-./test/eigen2support.cpp
-./test/denseLM.cpp
-./test/stdvector.cpp
-./test/nesting_ops.cpp
-./test/sparse_permutations.cpp
-./test/zerosized.cpp
-./test/exceptions.cpp
-./test/vectorwiseop.cpp
-./test/cwiseop.cpp
-./test/basicstuff.cpp
-./test/product_trmm.cpp
-./test/linearstructure.cpp
-./test/sparse_product.cpp
-./test/stdvector_overload.cpp
-./test/stable_norm.cpp
-./test/umeyama.cpp
-./test/unalignedcount.cpp
-./test/triangular.cpp
-./test/product_mmtr.cpp
-./test/sparse_basic.cpp
-./test/sparse_vector.cpp
-./test/meta.cpp
-./test/real_qz.cpp
-./test/ref.cpp
-./test/eigensolver_complex.cpp
-./test/cholmod_support.cpp
-./test/conjugate_gradient.cpp
-./test/sparse.h
-./test/simplicial_cholesky.cpp
-./test/bicgstab.cpp
-./test/dynalloc.cpp
-./test/product_notemporary.cpp
-./test/geo_hyperplane.cpp
-./test/lu.cpp
-./test/qr.cpp
-./test/hessenberg.cpp
-./test/sizeof.cpp
-./test/main.h
-./test/selfadjoint.cpp
-./test/permutationmatrices.cpp
-./test/superlu_support.cpp
-./test/qtvector.cpp
-./test/geo_homogeneous.cpp
-./test/determinant.cpp
-./test/array_reverse.cpp
-./test/unalignedassert.cpp
-./test/stdlist.cpp
-./test/product_symm.cpp
-./test/corners.cpp
-./test/dontalign.cpp
-./test/visitor.cpp
-./test/geo_alignedbox.cpp
-./test/diagonalmatrices.cpp
-./test/product_small.cpp
-./test/eigensolver_generalized_real.cpp
-./test/umfpack_support.cpp
-./test/first_aligned.cpp
-./test/qr_fullpivoting.cpp
-./test/array_replicate.cpp
-./test/geo_parametrizedline.cpp
-./test/eigen2/eigen2_unalignedassert.cpp
-./test/eigen2/eigen2_prec_inverse_4x4.cpp
-./test/eigen2/eigen2_alignedbox.cpp
-./test/eigen2/eigen2_sparse_product.cpp
-./test/eigen2/eigen2_meta.cpp
-./test/eigen2/eigen2_nomalloc.cpp
-./test/eigen2/eigen2_visitor.cpp
-./test/eigen2/eigen2_packetmath.cpp
-./test/eigen2/eigen2_svd.cpp
-./test/eigen2/eigen2_mixingtypes.cpp
-./test/eigen2/eigen2_qr.cpp
-./test/eigen2/eigen2_cwiseop.cpp
-./test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp
-./test/eigen2/eigen2_smallvectors.cpp
-./test/eigen2/eigen2_commainitializer.cpp
-./test/eigen2/eigen2_sparse_solvers.cpp
-./test/eigen2/eigen2_hyperplane.cpp
-./test/eigen2/eigen2_eigensolver.cpp
-./test/eigen2/eigen2_linearstructure.cpp
-./test/eigen2/eigen2_sizeof.cpp
-./test/eigen2/eigen2_parametrizedline.cpp
-./test/eigen2/eigen2_lu.cpp
-./test/eigen2/eigen2_adjoint.cpp
-./test/eigen2/eigen2_geometry.cpp
-./test/eigen2/eigen2_stdvector.cpp
-./test/eigen2/eigen2_newstdvector.cpp
-./test/eigen2/eigen2_submatrices.cpp
-./test/eigen2/sparse.h
-./test/eigen2/eigen2_swap.cpp
-./test/eigen2/eigen2_triangular.cpp
-./test/eigen2/eigen2_basicstuff.cpp
-./test/eigen2/gsl_helper.h
-./test/eigen2/eigen2_dynalloc.cpp
-./test/eigen2/eigen2_array.cpp
-./test/eigen2/eigen2_map.cpp
-./test/eigen2/main.h
-./test/eigen2/eigen2_miscmatrices.cpp
-./test/eigen2/eigen2_product_large.cpp
-./test/eigen2/eigen2_first_aligned.cpp
-./test/eigen2/eigen2_cholesky.cpp
-./test/eigen2/eigen2_determinant.cpp
-./test/eigen2/eigen2_sum.cpp
-./test/eigen2/eigen2_inverse.cpp
-./test/eigen2/eigen2_regression.cpp
-./test/eigen2/eigen2_product_small.cpp
-./test/eigen2/eigen2_qtvector.cpp
-./test/eigen2/eigen2_sparse_vector.cpp
-./test/eigen2/product.h
-./test/eigen2/eigen2_sparse_basic.cpp
-./test/eigen2/eigen2_bug_132.cpp
-./test/array.cpp
-./test/product_syrk.cpp
-./test/commainitializer.cpp
-./test/conservative_resize.cpp
-./test/qr_colpivoting.cpp
-./test/nullary.cpp
-./test/bandmatrix.cpp
-./test/pastix_support.cpp
-./test/product.h
-./test/block.cpp
-./test/vectorization_logic.cpp
-./test/jacobi.cpp
-./test/diagonal.cpp
-./test/schur_complex.cpp
-./test/sizeoverflow.cpp
-./bench/BenchTimer.h
-./bench/benchFFT.cpp
-./bench/eig33.cpp
-./bench/spbench/spbenchsolver.h
-./bench/spbench/spbenchstyle.h
-./lapack/complex_double.cpp
-./lapack/cholesky.cpp
-./lapack/lapack_common.h
-./lapack/eigenvalues.cpp
-./lapack/single.cpp
-./lapack/lu.cpp
-./lapack/complex_single.cpp
-./lapack/double.cpp
-./demos/mix_eigen_and_c/binary_library.cpp
-./demos/mix_eigen_and_c/binary_library.h
-./demos/mix_eigen_and_c/example.c
-./demos/mandelbrot/mandelbrot.cpp
-./demos/mandelbrot/mandelbrot.h
-./demos/opengl/icosphere.cpp
-./demos/opengl/icosphere.h
-./demos/opengl/camera.cpp
-./demos/opengl/quaternion_demo.h
-./demos/opengl/camera.h
-./demos/opengl/trackball.h
-./demos/opengl/gpuhelper.h
-./demos/opengl/trackball.cpp
-./demos/opengl/gpuhelper.cpp
-./demos/opengl/quaternion_demo.cpp
-./debug/gdb/printers.py
-./unsupported/test/minres.cpp
-./unsupported/test/openglsupport.cpp
-./unsupported/test/jacobisvd.cpp
-./unsupported/test/dgmres.cpp
-./unsupported/test/matrix_square_root.cpp
-./unsupported/test/bdcsvd.cpp
-./unsupported/test/matrix_exponential.cpp
-./unsupported/test/forward_adolc.cpp
-./unsupported/test/polynomialsolver.cpp
-./unsupported/test/matrix_function.cpp
-./unsupported/test/sparse_extra.cpp
-./unsupported/test/matrix_functions.h
-./unsupported/test/svd_common.h
-./unsupported/test/FFTW.cpp
-./unsupported/test/alignedvector3.cpp
-./unsupported/test/autodiff.cpp
-./unsupported/test/gmres.cpp
-./unsupported/test/BVH.cpp
-./unsupported/test/levenberg_marquardt.cpp
-./unsupported/test/matrix_power.cpp
-./unsupported/test/kronecker_product.cpp
-./unsupported/test/splines.cpp
-./unsupported/test/polynomialutils.cpp
-./unsupported/bench/bench_svd.cpp
-./unsupported/Eigen/IterativeSolvers
-./unsupported/Eigen/src/IterativeSolvers/DGMRES.h
-./unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h
-./unsupported/Eigen/src/IterativeSolvers/GMRES.h
-./unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h
-./unsupported/Eigen/src/IterativeSolvers/Scaling.h
-./unsupported/Eigen/src/IterativeSolvers/MINRES.h
-./unsupported/Eigen/src/SparseExtra/RandomSetter.h
-./unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h
-./unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h
-./unsupported/Eigen/src/SparseExtra/MarketIO.h
-./unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h
-./unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h
-./unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
-./unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
-./unsupported/Eigen/src/BVH/BVAlgorithms.h
-./unsupported/Eigen/src/BVH/KdBVH.h
-./unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
-./unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h
-./unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
-./unsupported/Eigen/src/Splines/Spline.h
-./unsupported/Eigen/src/Splines/SplineFitting.h
-./unsupported/Eigen/src/Splines/SplineFwd.h
-./unsupported/Eigen/src/SVD/JacobiSVD.h
-./unsupported/Eigen/src/SVD/BDCSVD.h
-./unsupported/Eigen/src/SVD/SVDBase.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
-./unsupported/Eigen/src/MatrixFunctions/StemFunction.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
-./unsupported/Eigen/src/MatrixFunctions/MatrixFunctionAtomic.h
-./unsupported/Eigen/src/MoreVectorization/MathFunctions.h
-./unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
-./unsupported/Eigen/src/FFT/ei_fftw_impl.h
-./unsupported/Eigen/src/FFT/ei_kissfft_impl.h
-./unsupported/Eigen/src/Polynomials/PolynomialSolver.h
-./unsupported/Eigen/src/Polynomials/Companion.h
-./unsupported/Eigen/src/Polynomials/PolynomialUtils.h
-./unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
-./unsupported/Eigen/src/Skyline/SkylineProduct.h
-./unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
-./unsupported/Eigen/src/Skyline/SkylineStorage.h
-./unsupported/Eigen/src/Skyline/SkylineUtil.h
-./unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
-./unsupported/Eigen/src/Skyline/SkylineMatrix.h
-./unsupported/Eigen/SparseExtra
-./unsupported/Eigen/AdolcForward
-./unsupported/Eigen/KroneckerProduct
-./unsupported/Eigen/NonLinearOptimization
-./unsupported/Eigen/BVH
-./unsupported/Eigen/OpenGLSupport
-./unsupported/Eigen/ArpackSupport
-./unsupported/Eigen/AutoDiff
-./unsupported/Eigen/Splines
-./unsupported/Eigen/MPRealSupport
-./unsupported/Eigen/MatrixFunctions
-./unsupported/Eigen/MoreVectorization
-./unsupported/Eigen/LevenbergMarquardt
-./unsupported/Eigen/AlignedVector3
-./unsupported/Eigen/FFT
-./unsupported/Eigen/Polynomials
-./unsupported/Eigen/NumericalDiff
-./unsupported/Eigen/Skyline
-./COPYING.README
-./COPYING.README
-./LICENSE
-./LICENSE
-./LICENSE
-./Eigen/Eigen2Support
-./Eigen/src/Eigen2Support/VectorBlock.h
-./Eigen/src/Eigen2Support/Cwise.h
-./Eigen/src/Eigen2Support/Minor.h
-./Eigen/src/Eigen2Support/Lazy.h
-./Eigen/src/Eigen2Support/Memory.h
-./Eigen/src/Eigen2Support/MathFunctions.h
-./Eigen/src/Eigen2Support/Geometry/AlignedBox.h
-./Eigen/src/Eigen2Support/Geometry/Hyperplane.h
-./Eigen/src/Eigen2Support/Geometry/Quaternion.h
-./Eigen/src/Eigen2Support/Geometry/Rotation2D.h
-./Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
-./Eigen/src/Eigen2Support/Geometry/RotationBase.h
-./Eigen/src/Eigen2Support/Geometry/Translation.h
-./Eigen/src/Eigen2Support/Geometry/Scaling.h
-./Eigen/src/Eigen2Support/Geometry/AngleAxis.h
-./Eigen/src/Eigen2Support/Geometry/Transform.h
-./Eigen/src/Eigen2Support/TriangularSolver.h
-./Eigen/src/Eigen2Support/LU.h
-./Eigen/src/Eigen2Support/QR.h
-./Eigen/src/Eigen2Support/SVD.h
-./Eigen/src/Eigen2Support/Meta.h
-./Eigen/src/Eigen2Support/Block.h
-./Eigen/src/Eigen2Support/Macros.h
-./Eigen/src/Eigen2Support/LeastSquares.h
-./Eigen/src/Eigen2Support/CwiseOperators.h
-./Eigen/src/Jacobi/Jacobi.h
-./Eigen/src/misc/Kernel.h
-./Eigen/src/misc/SparseSolve.h
-./Eigen/src/misc/Solve.h
-./Eigen/src/misc/Image.h
-./Eigen/src/SparseCore/SparseColEtree.h
-./Eigen/src/SparseCore/SparseTranspose.h
-./Eigen/src/SparseCore/SparseUtil.h
-./Eigen/src/SparseCore/SparseCwiseBinaryOp.h
-./Eigen/src/SparseCore/SparseDiagonalProduct.h
-./Eigen/src/SparseCore/SparseProduct.h
-./Eigen/src/SparseCore/SparseDot.h
-./Eigen/src/SparseCore/SparseCwiseUnaryOp.h
-./Eigen/src/SparseCore/SparseSparseProductWithPruning.h
-./Eigen/src/SparseCore/SparseBlock.h
-./Eigen/src/SparseCore/SparseDenseProduct.h
-./Eigen/src/SparseCore/CompressedStorage.h
-./Eigen/src/SparseCore/SparseMatrixBase.h
-./Eigen/src/SparseCore/MappedSparseMatrix.h
-./Eigen/src/SparseCore/SparseTriangularView.h
-./Eigen/src/SparseCore/SparseView.h
-./Eigen/src/SparseCore/SparseFuzzy.h
-./Eigen/src/SparseCore/TriangularSolver.h
-./Eigen/src/SparseCore/SparseSelfAdjointView.h
-./Eigen/src/SparseCore/SparseMatrix.h
-./Eigen/src/SparseCore/SparseVector.h
-./Eigen/src/SparseCore/AmbiVector.h
-./Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
-./Eigen/src/SparseCore/SparseRedux.h
-./Eigen/src/SparseCore/SparsePermutation.h
-./Eigen/src/Eigenvalues/RealSchur.h
-./Eigen/src/Eigenvalues/ComplexEigenSolver.h
-./Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
-./Eigen/src/Eigenvalues/ComplexSchur.h
-./Eigen/src/Eigenvalues/RealQZ.h
-./Eigen/src/Eigenvalues/EigenSolver.h
-./Eigen/src/Eigenvalues/HessenbergDecomposition.h
-./Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
-./Eigen/src/Eigenvalues/Tridiagonalization.h
-./Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
-./Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
-./Eigen/src/SuperLUSupport/SuperLUSupport.h
-./Eigen/src/StlSupport/StdDeque.h
-./Eigen/src/StlSupport/StdVector.h
-./Eigen/src/StlSupport/StdList.h
-./Eigen/src/StlSupport/details.h
-./Eigen/src/SparseQR/SparseQR.h
-./Eigen/src/LU/Inverse.h
-./Eigen/src/LU/arch/Inverse_SSE.h
-./Eigen/src/LU/Determinant.h
-./Eigen/src/LU/PartialPivLU.h
-./Eigen/src/LU/FullPivLU.h
-./Eigen/src/UmfPackSupport/UmfPackSupport.h
-./Eigen/src/OrderingMethods/Ordering.h
-./Eigen/src/OrderingMethods/Eigen_Colamd.h
-./Eigen/src/QR/HouseholderQR.h
-./Eigen/src/QR/ColPivHouseholderQR.h
-./Eigen/src/QR/FullPivHouseholderQR.h
-./Eigen/src/SVD/JacobiSVD.h
-./Eigen/src/SVD/UpperBidiagonalization.h
-./Eigen/src/Geometry/OrthoMethods.h
-./Eigen/src/Geometry/AlignedBox.h
-./Eigen/src/Geometry/Hyperplane.h
-./Eigen/src/Geometry/Quaternion.h
-./Eigen/src/Geometry/EulerAngles.h
-./Eigen/src/Geometry/Rotation2D.h
-./Eigen/src/Geometry/ParametrizedLine.h
-./Eigen/src/Geometry/RotationBase.h
-./Eigen/src/Geometry/arch/Geometry_SSE.h
-./Eigen/src/Geometry/Umeyama.h
-./Eigen/src/Geometry/Homogeneous.h
-./Eigen/src/Geometry/Translation.h
-./Eigen/src/Geometry/Scaling.h
-./Eigen/src/Geometry/AngleAxis.h
-./Eigen/src/Geometry/Transform.h
-./Eigen/src/plugins/BlockMethods.h
-./Eigen/src/plugins/CommonCwiseUnaryOps.h
-./Eigen/src/plugins/CommonCwiseBinaryOps.h
-./Eigen/src/plugins/MatrixCwiseUnaryOps.h
-./Eigen/src/plugins/MatrixCwiseBinaryOps.h
-./Eigen/src/Householder/Householder.h
-./Eigen/src/Householder/HouseholderSequence.h
-./Eigen/src/Householder/BlockHouseholder.h
-./Eigen/src/Core/VectorBlock.h
-./Eigen/src/Core/Matrix.h
-./Eigen/src/Core/Ref.h
-./Eigen/src/Core/SelfAdjointView.h
-./Eigen/src/Core/MathFunctions.h
-./Eigen/src/Core/GlobalFunctions.h
-./Eigen/src/Core/MapBase.h
-./Eigen/src/Core/EigenBase.h
-./Eigen/src/Core/GenericPacketMath.h
-./Eigen/src/Core/NestByValue.h
-./Eigen/src/Core/CwiseUnaryOp.h
-./Eigen/src/Core/SolveTriangular.h
-./Eigen/src/Core/Fuzzy.h
-./Eigen/src/Core/Visitor.h
-./Eigen/src/Core/Map.h
-./Eigen/src/Core/NoAlias.h
-./Eigen/src/Core/Diagonal.h
-./Eigen/src/Core/StableNorm.h
-./Eigen/src/Core/CoreIterators.h
-./Eigen/src/Core/products/Parallelizer.h
-./Eigen/src/Core/products/SelfadjointMatrixVector.h
-./Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
-./Eigen/src/Core/products/TriangularSolverMatrix.h
-./Eigen/src/Core/products/GeneralMatrixMatrix.h
-./Eigen/src/Core/products/SelfadjointProduct.h
-./Eigen/src/Core/products/CoeffBasedProduct.h
-./Eigen/src/Core/products/TriangularMatrixVector.h
-./Eigen/src/Core/products/SelfadjointMatrixMatrix.h
-./Eigen/src/Core/products/TriangularSolverVector.h
-./Eigen/src/Core/products/SelfadjointRank2Update.h
-./Eigen/src/Core/products/GeneralBlockPanelKernel.h
-./Eigen/src/Core/products/GeneralMatrixVector.h
-./Eigen/src/Core/products/TriangularMatrixMatrix.h
-./Eigen/src/Core/Reverse.h
-./Eigen/src/Core/BooleanRedux.h
-./Eigen/src/Core/Replicate.h
-./Eigen/src/Core/arch/AltiVec/PacketMath.h
-./Eigen/src/Core/arch/AltiVec/Complex.h
-./Eigen/src/Core/arch/SSE/PacketMath.h
-./Eigen/src/Core/arch/SSE/Complex.h
-./Eigen/src/Core/arch/SSE/MathFunctions.h
-./Eigen/src/Core/arch/NEON/PacketMath.h
-./Eigen/src/Core/arch/NEON/Complex.h
-./Eigen/src/Core/arch/Default/Settings.h
-./Eigen/src/Core/CwiseUnaryView.h
-./Eigen/src/Core/Array.h
-./Eigen/src/Core/ArrayWrapper.h
-./Eigen/src/Core/Swap.h
-./Eigen/src/Core/Transpositions.h
-./Eigen/src/Core/Random.h
-./Eigen/src/Core/IO.h
-./Eigen/src/Core/SelfCwiseBinaryOp.h
-./Eigen/src/Core/VectorwiseOp.h
-./Eigen/src/Core/Select.h
-./Eigen/src/Core/ArrayBase.h
-./Eigen/src/Core/DenseCoeffsBase.h
-./Eigen/src/Core/DiagonalProduct.h
-./Eigen/src/Core/Assign.h
-./Eigen/src/Core/Redux.h
-./Eigen/src/Core/ForceAlignedAccess.h
-./Eigen/src/Core/BandMatrix.h
-./Eigen/src/Core/PlainObjectBase.h
-./Eigen/src/Core/DenseBase.h
-./Eigen/src/Core/Flagged.h
-./Eigen/src/Core/CwiseBinaryOp.h
-./Eigen/src/Core/ProductBase.h
-./Eigen/src/Core/TriangularMatrix.h
-./Eigen/src/Core/Transpose.h
-./Eigen/src/Core/DiagonalMatrix.h
-./Eigen/src/Core/Dot.h
-./Eigen/src/Core/Functors.h
-./Eigen/src/Core/PermutationMatrix.h
-./Eigen/src/Core/NumTraits.h
-./Eigen/src/Core/MatrixBase.h
-./Eigen/src/Core/DenseStorage.h
-./Eigen/src/Core/util/Memory.h
-./Eigen/src/Core/util/StaticAssert.h
-./Eigen/src/Core/util/BlasUtil.h
-./Eigen/src/Core/util/MatrixMapper.h
-./Eigen/src/Core/util/XprHelper.h
-./Eigen/src/Core/util/ForwardDeclarations.h
-./Eigen/src/Core/util/Meta.h
-./Eigen/src/Core/util/Macros.h
-./Eigen/src/Core/util/Constants.h
-./Eigen/src/Core/CwiseNullaryOp.h
-./Eigen/src/Core/Block.h
-./Eigen/src/Core/GeneralProduct.h
-./Eigen/src/Core/CommaInitializer.h
-./Eigen/src/Core/ReturnByValue.h
-./Eigen/src/Core/Stride.h
-./Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
-./Eigen/src/SparseLU/SparseLU_column_dfs.h
-./Eigen/src/SparseLU/SparseLU_panel_dfs.h
-./Eigen/src/SparseLU/SparseLU_relax_snode.h
-./Eigen/src/SparseLU/SparseLU_panel_bmod.h
-./Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
-./Eigen/src/SparseLU/SparseLU_Utils.h
-./Eigen/src/SparseLU/SparseLU_gemm_kernel.h
-./Eigen/src/SparseLU/SparseLU_kernel_bmod.h
-./Eigen/src/SparseLU/SparseLU_pivotL.h
-./Eigen/src/SparseLU/SparseLU_Memory.h
-./Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
-./Eigen/src/SparseLU/SparseLUImpl.h
-./Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
-./Eigen/src/SparseLU/SparseLU_Structs.h
-./Eigen/src/SparseLU/SparseLU.h
-./Eigen/src/SparseLU/SparseLU_column_bmod.h
-./Eigen/src/SparseLU/SparseLU_pruneL.h
-./Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
-./Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
-./Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
-./Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
-./Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
-./Eigen/src/SparseCholesky/SimplicialCholesky.h
-./Eigen/src/Cholesky/LDLT.h
-./Eigen/src/Cholesky/LLT.h
-./Eigen/src/CholmodSupport/CholmodSupport.h
-./Eigen/src/PaStiXSupport/PaStiXSupport.h
-./Eigen/src/MetisSupport/MetisSupport.h
-./Eigen/StdVector
-./Eigen/Core
-./Eigen/SparseLU
-./Eigen/StdList
-./Eigen/StdDeque
-./Eigen/SparseCholesky
-./scripts/relicense.py
-./scripts/relicense.py
-./blas/BandTriangularSolver.h
-./blas/PackedTriangularMatrixVector.h
-./blas/complex_double.cpp
-./blas/level2_real_impl.h
-./blas/level1_cplx_impl.h
-./blas/level1_impl.h
-./blas/level1_real_impl.h
-./blas/level3_impl.h
-./blas/single.cpp
-./blas/level2_cplx_impl.h
-./blas/PackedSelfadjointProduct.h
-./blas/Rank2Update.h
-./blas/complex_single.cpp
-./blas/PackedTriangularSolverVector.h
-./blas/double.cpp
-./blas/common.h
-./blas/level2_impl.h
-./blas/GeneralRank1Update.h
-
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
-    means each individual or legal entity that creates, contributes to
-    the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
-    means the combination of the Contributions of others (if any) used
-    by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
-    means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
-    means Source Code Form to which the initial Contributor has attached
-    the notice in Exhibit A, the Executable Form of such Source Code
-    Form, and Modifications of such Source Code Form, in each case
-    including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
-    means
-
-    (a) that the initial Contributor has attached the notice described
-        in Exhibit B to the Covered Software; or
-
-    (b) that the Covered Software was made available under the terms of
-        version 1.1 or earlier of the License, but not also under the
-        terms of a Secondary License.
-
-1.6. "Executable Form"
-    means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
-    means a work that combines Covered Software with other material, in
-    a separate file or files, that is not Covered Software.
-
-1.8. "License"
-    means this document.
-
-1.9. "Licensable"
-    means having the right to grant, to the maximum extent possible,
-    whether at the time of the initial grant or subsequently, any and
-    all of the rights conveyed by this License.
-
-1.10. "Modifications"
-    means any of the following:
-
-    (a) any file in Source Code Form that results from an addition to,
-        deletion from, or modification of the contents of Covered
-        Software; or
-
-    (b) any new file in Source Code Form that contains any Covered
-        Software.
-
-1.11. "Patent Claims" of a Contributor
-    means any patent claim(s), including without limitation, method,
-    process, and apparatus claims, in any patent Licensable by such
-    Contributor that would be infringed, but for the grant of the
-    License, by the making, using, selling, offering for sale, having
-    made, import, or transfer of either its Contributions or its
-    Contributor Version.
-
-1.12. "Secondary License"
-    means either the GNU General Public License, Version 2.0, the GNU
-    Lesser General Public License, Version 2.1, the GNU Affero General
-    Public License, Version 3.0, or any later versions of those
-    licenses.
-
-1.13. "Source Code Form"
-    means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
-    means an individual or a legal entity exercising rights under this
-    License. For legal entities, "You" includes any entity that
-    controls, is controlled by, or is under common control with You. For
-    purposes of this definition, "control" means (a) the power, direct
-    or indirect, to cause the direction or management of such entity,
-    whether by contract or otherwise, or (b) ownership of more than
-    fifty percent (50%) of the outstanding shares or beneficial
-    ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
-    Licensable by such Contributor to use, reproduce, make available,
-    modify, display, perform, distribute, and otherwise exploit its
-    Contributions, either on an unmodified basis, with Modifications, or
-    as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
-    for sale, have made, import, and otherwise transfer either its
-    Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
-    or
-
-(b) for infringements caused by: (i) Your and any other third party's
-    modifications of Covered Software, or (ii) the combination of its
-    Contributions with other software (except as part of its Contributor
-    Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
-    its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
-    Form, as described in Section 3.1, and You must inform recipients of
-    the Executable Form how they can obtain a copy of such Source Code
-    Form by reasonable means in a timely manner, at a charge no more
-    than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
-    License, or sublicense it under different terms, provided that the
-    license for the Executable Form does not attempt to limit or alter
-    the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-*                                                                      *
-*  6. Disclaimer of Warranty                                           *
-*  -------------------------                                           *
-*                                                                      *
-*  Covered Software is provided under this License on an "as is"       *
-*  basis, without warranty of any kind, either expressed, implied, or  *
-*  statutory, including, without limitation, warranties that the       *
-*  Covered Software is free of defects, merchantable, fit for a        *
-*  particular purpose or non-infringing. The entire risk as to the     *
-*  quality and performance of the Covered Software is with You.        *
-*  Should any Covered Software prove defective in any respect, You     *
-*  (not any Contributor) assume the cost of any necessary servicing,   *
-*  repair, or correction. This disclaimer of warranty constitutes an   *
-*  essential part of this License. No use of any Covered Software is   *
-*  authorized under this License except under this disclaimer.         *
-*                                                                      *
-************************************************************************
-
-************************************************************************
-*                                                                      *
-*  7. Limitation of Liability                                          *
-*  --------------------------                                          *
-*                                                                      *
-*  Under no circumstances and under no legal theory, whether tort      *
-*  (including negligence), contract, or otherwise, shall any           *
-*  Contributor, or anyone who distributes Covered Software as          *
-*  permitted above, be liable to You for any direct, indirect,         *
-*  special, incidental, or consequential damages of any character      *
-*  including, without limitation, damages for lost profits, loss of    *
-*  goodwill, work stoppage, computer failure or malfunction, or any    *
-*  and all other commercial damages or losses, even if such party      *
-*  shall have been informed of the possibility of such damages. This   *
-*  limitation of liability shall not apply to liability for death or   *
-*  personal injury resulting from such party's negligence to the       *
-*  extent applicable law prohibits such limitation. Some               *
-*  jurisdictions do not allow the exclusion or limitation of           *
-*  incidental or consequential damages, so this exclusion and          *
-*  limitation may not apply to You.                                    *
-*                                                                      *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
-  This Source Code Form is subject to the terms of the Mozilla Public
-  License, v. 2.0. If a copy of the MPL was not distributed with this
-  file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
-  This Source Code Form is "Incompatible With Secondary Licenses", as
-  defined by the Mozilla Public License, v. 2.0.
-
-----------------------------------------------------------------------
-Following applies to:
-./doc/UsingIntelMKL.dox
-./doc/UsingIntelMKL.dox
-./Eigen/src/Eigenvalues/ComplexSchur_MKL.h
-./Eigen/src/Eigenvalues/ComplexSchur_MKL.h
-./Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
-./Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
-./Eigen/src/Eigenvalues/RealSchur_MKL.h
-./Eigen/src/Eigenvalues/RealSchur_MKL.h
-./Eigen/src/LU/arch/Inverse_SSE.h
-./Eigen/src/LU/arch/Inverse_SSE.h
-./Eigen/src/LU/PartialPivLU_MKL.h
-./Eigen/src/LU/PartialPivLU_MKL.h
-./Eigen/src/QR/HouseholderQR_MKL.h
-./Eigen/src/QR/HouseholderQR_MKL.h
-./Eigen/src/QR/ColPivHouseholderQR_MKL.h
-./Eigen/src/QR/ColPivHouseholderQR_MKL.h
-./Eigen/src/SVD/JacobiSVD_MKL.h
-./Eigen/src/SVD/JacobiSVD_MKL.h
-./Eigen/src/PardisoSupport/PardisoSupport.h
-./Eigen/src/PardisoSupport/PardisoSupport.h
-./Eigen/src/Core/Assign_MKL.h
-./Eigen/src/Core/Assign_MKL.h
-./Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
-./Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
-./Eigen/src/Core/products/GeneralMatrixVector_MKL.h
-./Eigen/src/Core/products/GeneralMatrixVector_MKL.h
-./Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
-./Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
-./Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
-./Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
-./Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h
-./Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h
-./Eigen/src/Core/products/TriangularMatrixVector_MKL.h
-./Eigen/src/Core/products/TriangularMatrixVector_MKL.h
-./Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h
-./Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h
-./Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
-./Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
-./Eigen/src/Core/util/MKL_support.h
-./Eigen/src/Core/util/MKL_support.h
-./Eigen/src/Cholesky/LLT_MKL.h
-./Eigen/src/Cholesky/LLT_MKL.h
-
-/*
- Copyright (c) 2011, Intel Corporation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.  *
-   Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the
-   distribution.  * Neither the name of Intel Corporation nor the
-   names of its contributors may be used to endorse or promote
-   products derived from this software without specific prior written
-   permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-----------------------------------------------------------------------
-Following applies to:
-  everything under ./bench/btl
-
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds
-of works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal,
-family, or household purposes, or (2) anything designed or sold for
-incorporation into a dwelling.  In determining whether a product is a
-consumer product, doubtful cases shall be resolved in favor of
-coverage.  For a particular product received by a particular user,
-"normally used" refers to a typical or common use of that class of
-product, regardless of the status of the particular user or of the way
-in which the particular user actually uses, or expects or is expected
-to use, the product.  A product is a consumer product regardless of
-whether the product has substantial commercial, industrial or
-non-consumer uses, unless such uses represent the only significant
-mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to
-install and execute modified versions of a covered work in that User
-Product from a modified version of its Corresponding Source.  The
-information must suffice to ensure that the continued functioning of
-the modified object code is in no case prevented or interfered with
-solely because modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include
-a requirement to continue to provide support service, warranty, or
-updates for a work that has been modified or installed by the
-recipient, or for the User Product in which it has been modified or
-installed.  Access to a network may be denied when the modification
-itself materially and adversely affects the operation of the network
-or violates the rules and protocols for communication across the
-network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material
-you add to a covered work, you may (if authorized by the copyright
-holders of that material) supplement the terms of this License with
-terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions
-    of it) with contractual assumptions of liability to the recipient,
-    for any liability that these contractual assumptions directly
-    impose on those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement
-or otherwise) that contradict the conditions of this License, they do
-not excuse you from the conditions of this License.  If you cannot
-convey a covered work so as to satisfy simultaneously your obligations
-under this License and any other pertinent obligations, then as a
-consequence you may not convey it at all.  For example, if you agree
-to terms that obligate you to collect a royalty for further conveying
-from those to whom you convey the Program, the only way you could
-satisfy both those terms and this License would be to refrain entirely
-from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU General Public License from time to time.  Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
-DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
-CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
-AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
-DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
-DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
-(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
-THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
-OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it
-    does.>
-    Copyright (C) <year> <name of author>
-
-    This program is free software: you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation, either version 3 of the
-    License, or (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see
-    <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program> Copyright (C) <year> <name of author> This program comes
-    with ABSOLUTELY NO WARRANTY; for details type `show w'.  This is
-    free software, and you are welcome to redistribute it under
-    certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the
-appropriate parts of the General Public License.  Of course, your
-program's commands might be different; for a GUI interface, you would
-use an "about box".
-
-  You should also get your employer (if you work as a programmer) or
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  For more information on this, and how to apply and follow
-the GNU GPL, see <http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your
-program into proprietary programs.  If your program is a subroutine
-library, you may consider it more useful to permit linking proprietary
-applications with the library.  If this is what you want to do, use
-the GNU Lesser General Public License instead of this License.  But
-first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
-
-----------------------------------------------------------------------
-Following applies to:
-./test/metis_support.cpp
-./test/sparselu.cpp
-./unsupported/test/mpreal/mpreal.h
-./unsupported/Eigen/src/IterativeSolvers/IterationController.h
-./unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h
-./unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
-./Eigen/src/OrderingMethods/Amd.h
-./Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
-
-                  GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions.
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the
-GNU General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this
-   license document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this
-   license document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of
-       this License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
-
-
-----------------------------------------------------------------------
-Following applies to:
-./unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
-./unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h
-./unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
-./unsupported/Eigen/src/LevenbergMarquardt/LMpar.h
-./unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h
-
-Minpack Copyright Notice (1999) University of Chicago.  All rights
-reserved
-
-Redistribution and use in source and binary forms, with or
-without modification, are permitted provided that the
-following conditions are met:
-
-1. Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer.
-
-2. Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials
-provided with the distribution.
-
-3. The end-user documentation included with the
-redistribution, if any, must include the following
-acknowledgment:
-
-   "This product includes software developed by the
-   University of Chicago, as Operator of Argonne National
-   Laboratory.
-
-Alternately, this acknowledgment may appear in the software
-itself, if and wherever such third-party acknowledgments
-normally appear.
-
-4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
-WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
-UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
-THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
-OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
-OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
-USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
-THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
-DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
-UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
-BE CORRECTED.
-
-5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
-HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
-ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
-INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
-ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
-PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
-SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
-(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
-EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
-POSSIBILITY OF SUCH LOSS OR DAMAGES.
-
-
-****************************
-freetype2
-****************************
-FreeType
-
-Quoth http://freetype.sourceforge.net/license.html:
-
-FreeType comes with two licenses from which you can choose the one
-which fits your needs best.
-
-   * The FreeType License is the most commonly used one.
-    It is a BSD-style license with a credit clause (and thus not
-    compatible with the GPL).
-
-  * The GNU General Public License (GPL).
-    For all projects which use the GPL also or which need a license
-    compatible to the GPL.
-
-FTL.TXT:
----
-
-                    The FreeType Project LICENSE
-                    ----------------------------
-
-                            2006-Jan-27
-
-                    Copyright 1996-2002, 2006 by
-          David Turner, Robert Wilhelm, and Werner Lemberg
-
-
-
-Introduction
-============
-
-  The FreeType  Project is distributed in  several archive packages;
-  some of them may contain, in addition to the FreeType font engine,
-  various tools and  contributions which rely on, or  relate to, the
-  FreeType Project.
-
-  This  license applies  to all  files found  in such  packages, and
-  which do not  fall under their own explicit  license.  The license
-  affects  thus  the  FreeType   font  engine,  the  test  programs,
-  documentation and makefiles, at the very least.
-
-  This  license   was  inspired  by  the  BSD,   Artistic,  and  IJG
-  (Independent JPEG  Group) licenses, which  all encourage inclusion
-  and  use of  free  software in  commercial  and freeware  products
-  alike.  As a consequence, its main points are that:
-
-    o We don't promise that this software works. However, we will be
-      interested in any kind of bug reports. (`as is' distribution)
-
-    o You can  use this software for whatever you  want, in parts or
-      full form, without having to pay us. (`royalty-free' usage)
-
-    o You may not pretend that  you wrote this software.  If you use
-      it, or  only parts of it,  in a program,  you must acknowledge
-      somewhere  in  your  documentation  that  you  have  used  the
-      FreeType code. (`credits')
-
-  We  specifically  permit  and  encourage  the  inclusion  of  this
-  software, with  or without modifications,  in commercial products.
-  We  disclaim  all warranties  covering  The  FreeType Project  and
-  assume no liability related to The FreeType Project.
-
-
-  Finally,  many  people  asked  us  for  a  preferred  form  for  a
-  credit/disclaimer to use in compliance with this license.  We thus
-  encourage you to use the following text:
-
-   """
-    Portions of this software are copyright (C) <year> The FreeType
-    Project (www.freetype.org).  All rights reserved.
-   """
-
-  Please replace <year> with the value from the FreeType version you
-  actually use.
-
-
-Legal Terms
-===========
-
-0. Definitions
---------------
-
-  Throughout this license,  the terms `package', `FreeType Project',
-  and  `FreeType  archive' refer  to  the  set  of files  originally
-  distributed  by the  authors  (David Turner,  Robert Wilhelm,  and
-  Werner Lemberg) as the `FreeType Project', be they named as alpha,
-  beta or final release.
-
-  `You' refers to  the licensee, or person using  the project, where
-  `using' is a generic term including compiling the project's source
-  code as  well as linking it  to form a  `program' or `executable'.
-  This  program is  referred to  as  `a program  using the  FreeType
-  engine'.
-
-  This  license applies  to all  files distributed  in  the original
-  FreeType  Project,   including  all  source   code,  binaries  and
-  documentation,  unless  otherwise  stated   in  the  file  in  its
-  original, unmodified form as  distributed in the original archive.
-  If you are  unsure whether or not a particular  file is covered by
-  this license, you must contact us to verify this.
-
-  The FreeType  Project is copyright (C) 1996-2000  by David Turner,
-  Robert Wilhelm, and Werner Lemberg.  All rights reserved except as
-  specified below.
-
-1. No Warranty
---------------
-
-  THE FREETYPE PROJECT  IS PROVIDED `AS IS' WITHOUT  WARRANTY OF ANY
-  KIND, EITHER  EXPRESS OR IMPLIED,  INCLUDING, BUT NOT  LIMITED TO,
-  WARRANTIES  OF  MERCHANTABILITY   AND  FITNESS  FOR  A  PARTICULAR
-  PURPOSE.  IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
-  BE LIABLE  FOR ANY DAMAGES CAUSED  BY THE USE OR  THE INABILITY TO
-  USE, OF THE FREETYPE PROJECT.
-
-2. Redistribution
------------------
-
-  This  license  grants  a  worldwide, royalty-free,  perpetual  and
-  irrevocable right  and license to use,  execute, perform, compile,
-  display,  copy,   create  derivative  works   of,  distribute  and
-  sublicense the  FreeType Project (in  both source and  object code
-  forms)  and  derivative works  thereof  for  any  purpose; and  to
-  authorize others  to exercise  some or all  of the  rights granted
-  herein, subject to the following conditions:
-
-    o Redistribution of  source code  must retain this  license file
-      (`FTL.TXT') unaltered; any  additions, deletions or changes to
-      the original  files must be clearly  indicated in accompanying
-      documentation.   The  copyright   notices  of  the  unaltered,
-      original  files must  be  preserved in  all  copies of  source
-      files.
-
-    o Redistribution in binary form must provide a  disclaimer  that
-      states  that  the software is based in part of the work of the
-      FreeType Team,  in  the  distribution  documentation.  We also
-      encourage you to put an URL to the FreeType web page  in  your
-      documentation, though this isn't mandatory.
-
-  These conditions  apply to any  software derived from or  based on
-  the FreeType Project,  not just the unmodified files.   If you use
-  our work, you  must acknowledge us.  However, no  fee need be paid
-  to us.
-
-3. Advertising
---------------
-
-  Neither the  FreeType authors and  contributors nor you  shall use
-  the name of the  other for commercial, advertising, or promotional
-  purposes without specific prior written permission.
-
-  We suggest,  but do not require, that  you use one or  more of the
-  following phrases to refer  to this software in your documentation
-  or advertising  materials: `FreeType Project',  `FreeType Engine',
-  `FreeType library', or `FreeType Distribution'.
-
-  As  you have  not signed  this license,  you are  not  required to
-  accept  it.   However,  as  the FreeType  Project  is  copyrighted
-  material, only  this license, or  another one contracted  with the
-  authors, grants you  the right to use, distribute,  and modify it.
-  Therefore,  by  using,  distributing,  or modifying  the  FreeType
-  Project, you indicate that you understand and accept all the terms
-  of this license.
-
-4. Contacts
------------
-
-  There are two mailing lists related to FreeType:
-
-    o freetype@nongnu.org
-
-      Discusses general use and applications of FreeType, as well as
-      future and  wanted additions to the  library and distribution.
-      If  you are looking  for support,  start in  this list  if you
-      haven't found anything to help you in the documentation.
-
-    o freetype-devel@nongnu.org
-
-      Discusses bugs,  as well  as engine internals,  design issues,
-      specific licenses, porting, etc.
-
-  Our home page can be found at
-
-    http://www.freetype.org
-
-
---- end of FTL.TXT ---
-
-
-****************************
-GL
-****************************
-Mesa Component Licenses
-
-Component         Location               Primary Author      License
-----------------------------------------------------------------------------
-Main Mesa code    src/mesa/              Brian Paul          Mesa (MIT)
-
-Device drivers    src/mesa/drivers/*     See drivers         See drivers
-
-Ext headers       include/GL/glext.h     SGI                 SGI Free B
-                  include/GL/glxext.h
-
-GLUT              src/glut/              Mark Kilgard        Mark's copyright
-
-GLEW              src/glew-1.13.0        Nigel Stewart       Modified BSD
-
-Mesa GLU library  src/glu/mesa/          Brian Paul          GNU-LGPL
-
-SGI GLU library   src/glu/sgi/           SGI                 SGI Free B
-
-demo programs     progs/demos/           various             see source files
-
-X demos           progs/xdemos/          Brian Paul          see source files
-
-SGI demos         progs/samples/         SGI                 SGI copyright
-
-RedBook demos     progs/redbook/         SGI                 SGI copyright
-
----------------------
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of Alan Hourihane not be used in
-advertising or publicity pertaining to distribution of the software without
-specific, written prior permission.  Alan Hourihane makes no representations
-about the suitability of this software for any purpose.  It is provided
-"as is" without express or implied warranty.
-
-ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-
-----------------------------------------------------------------------
-
-
-      GNU LIBRARY GENERAL PUBLIC LICENSE
-           Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
-                    675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-          Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-      GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-          NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-         END OF TERMS AND CONDITIONS
-
-     Appendix: How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
----------------------
-
-The OpenGL Extension Wrangler Library
-Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
-Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
-Copyright (C) 2002, Lev Povalahev
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-* The name of the author may be used to endorse or promote products
-  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-gradle
-****************************
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-------------------------------------------------------------------------------
-License for the slf4j package
-------------------------------------------------------------------------------
-SLF4J License
-
-Copyright (c) 2004-2007 QOS.ch
-All rights reserved.
-
-Permission is hereby granted, free  of charge, to any person obtaining
-a  copy  of this  software  and  associated  documentation files  (the
-"Software"), to  deal in  the Software without  restriction, including
-without limitation  the rights to  use, copy, modify,  merge, publish,
-distribute,  sublicense, and/or sell  copies of  the Software,  and to
-permit persons to whom the Software  is furnished to do so, subject to
-the following conditions:
-
-The  above  copyright  notice  and  this permission  notice  shall  be
-included in all copies or substantial portions of the Software.
-
-THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
-EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
-MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-These terms are identical to those of the MIT License, also called the X License or the X11 License,
-which is a simple, permissive non-copyleft free software license. It is deemed compatible with virtually
-all types of licenses, commercial or otherwise. In particular, the Free Software Foundation has declared it
-compatible with GNU GPL. It is also known to be approved by the Apache Software Foundation as compatible
-with Apache Software License.
-
-
-------------------------------------------------------------------------------
-License for the JUnit package
-------------------------------------------------------------------------------
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC
-LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
-CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-a) in the case of the initial Contributor, the initial code and
-documentation distributed under this Agreement, and
-
-b) in the case of each subsequent Contributor:
-
-i) changes to the Program, and
-
-ii) additions to the Program;
-
-where such changes and/or additions to the Program originate from and are
-distributed by that particular Contributor. A Contribution 'originates' from a
-Contributor if it was added to the Program by such Contributor itself or anyone
-acting on such Contributor's behalf. Contributions do not include additions to
-the Program which: (i) are separate modules of software distributed in
-conjunction with the Program under their own license agreement, and (ii) are not
-derivative works of the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor which are
-necessarily infringed by the use or sale of its Contribution alone or when
-combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement,
-including all Contributors.
-
-2. GRANT OF RIGHTS
-
-a) Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide, royalty-free copyright license to
-reproduce, prepare derivative works of, publicly display, publicly perform,
-distribute and sublicense the Contribution of such Contributor, if any, and such
-derivative works, in source code and object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
-Patents to make, use, sell, offer to sell, import and otherwise transfer the
-Contribution of such Contributor, if any, in source code and object code form.
-This patent license shall apply to the combination of the Contribution and the
-Program if, at the time the Contribution is added by the Contributor, such
-addition of the Contribution causes such combination to be covered by the
-Licensed Patents. The patent license shall not apply to any other combinations
-which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the licenses
-to its Contributions set forth herein, no assurances are provided by any
-Contributor that the Program does not infringe the patent or other intellectual
-property rights of any other entity. Each Contributor disclaims any liability to
-Recipient for claims brought by any other entity based on infringement of
-intellectual property rights or otherwise. As a condition to exercising the
-rights and licenses granted hereunder, each Recipient hereby assumes sole
-responsibility to secure any other intellectual property rights needed, if any.
-For example, if a third party patent license is required to allow Recipient to
-distribute the Program, it is Recipient's responsibility to acquire that license
-before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient
-copyright rights in its Contribution, if any, to grant the copyright license set
-forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its
-own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-
-b) its license agreement:
-
-i) effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title and
-non-infringement, and implied warranties or conditions of merchantability and
-fitness for a particular purpose;
-
-ii) effectively excludes on behalf of all Contributors all liability for
-damages, including direct, indirect, special, incidental and consequential
-damages, such as lost profits;
-
-iii) states that any provisions which differ from this Agreement are offered
-by that Contributor alone and not by any other party; and
-
-iv) states that source code for the Program is available from such
-Contributor, and informs licensees how to obtain it in a reasonable manner on or
-through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-
-b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained within the
-Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if
-any, in a manner that reasonably allows subsequent Recipients to identify the
-originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with
-respect to end users, business partners and the like. While this license is
-intended to facilitate the commercial use of the Program, the Contributor who
-includes the Program in a commercial product offering should do so in a manner
-which does not create potential liability for other Contributors. Therefore, if
-a Contributor includes the Program in a commercial product offering, such
-Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
-every other Contributor ("Indemnified Contributor") against any losses, damages
-and costs (collectively "Losses") arising from claims, lawsuits and other legal
-actions brought by a third party against the Indemnified Contributor to the
-extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor to
-control, and cooperate with the Commercial Contributor in, the defense and any
-related settlement negotiations. The Indemnified Contributor may participate in
-any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product
-offering, Product X. That Contributor is then a Commercial Contributor. If that
-Commercial Contributor then makes performance claims, or offers warranties
-related to Product X, those performance claims and warranties are such
-Commercial Contributor's responsibility alone. Under this section, the
-Commercial Contributor would have to defend claims against the other
-Contributors related to those performance claims and warranties, and if a court
-requires any other Contributor to pay any damages as a result, the Commercial
-Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
-IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
-Recipient is solely responsible for determining the appropriateness of using and
-distributing the Program and assumes all risks associated with its exercise of
-rights under this Agreement, including but not limited to the risks and costs of
-program errors, compliance with applicable laws, damage to or loss of data,
-programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
-CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
-PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
-GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable
-law, it shall not affect the validity or enforceability of the remainder of the
-terms of this Agreement, and without further action by the parties hereto, such
-provision shall be reformed to the minimum extent necessary to make such
-provision valid and enforceable.
-
-If Recipient institutes patent litigation against a Contributor with respect to
-a patent applicable to software (including a cross-claim or counterclaim in a
-lawsuit), then any patent licenses granted by that Contributor to such Recipient
-under this Agreement shall terminate as of the date such litigation is filed. In
-addition, if Recipient institutes patent litigation against any entity
-(including a cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or hardware)
-infringes such Recipient's patent(s), then such Recipient's rights granted under
-Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails to
-comply with any of the material terms or conditions of this Agreement and does
-not cure such failure in a reasonable period of time after becoming aware of
-such noncompliance. If all Recipient's rights under this Agreement terminate,
-Recipient agrees to cease use and distribution of the Program as soon as
-reasonably practicable. However, Recipient's obligations under this Agreement
-and any licenses granted by Recipient relating to the Program shall continue and
-survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in
-order to avoid inconsistency the Agreement is copyrighted and may only be
-modified in the following manner. The Agreement Steward reserves the right to
-publish new versions (including revisions) of this Agreement from time to time.
-No one other than the Agreement Steward has the right to modify this Agreement.
-IBM is the initial Agreement Steward. IBM may assign the responsibility to serve
-as the Agreement Steward to a suitable separate entity. Each new version of the
-Agreement will be given a distinguishing version number. The Program (including
-Contributions) may always be distributed subject to the version of the Agreement
-under which it was received. In addition, after a new version of the Agreement
-is published, Contributor may elect to distribute the Program (including its
-Contributions) under the new version. Except as expressly stated in Sections
-2(a) and 2(b) above, Recipient receives no rights or licenses to the
-intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the
-intellectual property laws of the United States of America. No party to this
-Agreement will bring a legal action under this Agreement more than one year
-after the cause of action arose. Each party waives its rights to a jury trial in
-any resulting litigation.
-
-------------------------------------------------------------------------------
-License for the JCIFS package
-------------------------------------------------------------------------------
-JCIFS License
-
-          GNU LESSER GENERAL PUBLIC LICENSE
-               Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-          GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-             END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
-
-****************************
-icu
-****************************
-ICU
-
-There are two licenses here:
-- ICU license
-- Unicode Terms of Use
-------------------------------------------------------------------------------
-ICU License - ICU 1.8.1 and later
-From http://source.icu-project.org/repos/icu/icu/trunk/license.html
-X License (old version). For license pedigree see the
-ICU FAQ at http://icu-project.org/userguide/icufaq.html
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1995-2006 International Business Machines Corporation and others
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, and/or sell copies of the
-Software, and to permit persons to whom the Software is furnished to do so,
-provided that the above copyright notice(s) and this permission notice appear
-in all copies of the Software and that both the above copyright notice(s) and
-this permission notice appear in supporting documentation.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
-LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not
-be used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization of the copyright holder.
-
-All trademarks and registered trademarks mentioned herein are the property of their respective owners.
-
-------------------------------------------------------------------------------
-Unicode Terms of Use, from http://www.unicode.org/copyright.html
-
-    For the general privacy policy governing access to this site, see the
-Unicode Privacy Policy. For trademark usage, see the Unicode Consortium
-Trademarks and Logo Policy.
-    Notice to End User: Terms of Use
-    Carefully read the following legal agreement ("Agreement"). Use or copying
-of the software and/or codes provided with this agreement (The "Software")
-constitutes your acceptance of these terms
-
-       1. Unicode Copyright.
-             1. Copyright  1991-2007 Unicode, Inc. All rights reserved.
-             2. Certain documents and files on this website contain a legend
-indicating that "Modification is permitted." Any person is hereby authorized,
-without fee, to modify such documents and files to create derivative works
-conforming to the Unicode Standard, subject to Terms and Conditions herein.
-             3. Any person is hereby authorized, without fee, to view, use,
-reproduce, and distribute all documents and files solely for informational
-purposes in the creation of products supporting the Unicode Standard, subject
-to the Terms and Conditions herein.
-             4. Further specifications of rights and restrictions pertaining
-to the use of the particular set of data files known as the "Unicode Character
-Database" can be found in Exhibit 1.
-             5. Each version of the Unicode Standard has further specifications
-of rights and restrictions of use. For the book editions, these are found on
-the back of the title page. For the online edition, certain files (such as the
-PDF files for book chapters and code charts) carry specific restrictions. All
-other files are covered under these general Terms of Use.  To request a
-permission to reproduce any part of the Unicode Standard, please contact the
-Unicode Consortium.
-             6. No license is granted to "mirror" the Unicode website where a
-fee is charged for access to the "mirror" site.
-             7. Modification is not permitted with respect to this document.
-All copies of this document must be verbatim.
-       2. Restricted Rights Legend. Any technical data or software which is
-licensed to the United States of America, its agencies and/or instrumentalities
-under this Agreement is commercial technical data or commercial computer
-software developed exclusively at private expense as defined in FAR 2.101, or
-DFARS 252.227-7014 (June 1995), as applicable. For technical data, use,
-duplication, or disclosure by the Government is subject to restrictions as set
-forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995)
-and this Agreement. For Software, in accordance with FAR 12-212 or
-DFARS 227-7202, as applicable, use, duplication or disclosure by the Government
-is subject to the restrictions set forth in this Agreement.
-       3. Warranties and Disclaimers.
-             1. This publication and/or website may include technical or
-typographical errors or other inaccuracies . Changes are periodically added to
-the information herein; these changes will be incorporated in new editions of
-the publication and/or website. Unicode may make improvements and/or changes
-in the product(s) and/or program(s) described in this publication and/or
-website at any time.
-             2. If this file has been purchased on magnetic or optical media
-from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange
-of the defective media within ninety (90) days of original purchase.
-             3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR
-SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS,
-IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
-UNICODE AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN
-THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR
-LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE.
-       4. Waiver of Damages. In no event shall Unicode or its licensors be
-liable for any special, incidental, indirect or consequential damages of any
-kind, or any damages whatsoever, whether or not Unicode was advised of the
-possibility of the damage, including, without limitation, those resulting from
-the following: loss of use, data or profits, in connection with the use,
-modification or distribution of this information or its derivatives.
-       5. Trademarks.
-             1. Unicode and the Unicode logo are registered trademarks of
-Unicode, Inc.
-             2. This site contains product names and corporate names of other
-companies. All product names and company names and logos mentioned herein are
-the trademarks or registered trademarks of their respective owners. Other
-products and corporate names mentioned herein which are trademarks of a third
-party are used only for explanation and for the owners' benefit and with no
-intent to infringe.
-             3. Use of third party products or information referred to herein
-is at the user\x{2019}s risk.
-       6. Miscellaneous.
-             1. Jurisdiction and Venue. This server is operated from a location
-in the State of California, United States of America. Unicode makes no
-representation that the materials are appropriate for use in other locations.
-If you access this server from other locations, you are responsible for
-compliance with local laws. This Agreement, all use of this site and any
-claims and damages resulting from use of this site are governed solely by the
-laws of the State of California without regard to any principles which would
-apply the laws of a different jurisdiction. The user agrees that any disputes
-regarding this site shall be resolved solely in the courts located in Santa
-Clara County, California. The user agrees said courts have personal
-jurisdiction and agree to waive any right to transfer the dispute to any other
-forum.
-             2. Modification by Unicode Unicode shall have the right to modify
-this Agreement at any time by posting it to this site. The user may not assign
-any part of this Agreement without Unicode\x{2019}s prior written consent.
-             3. Taxes. The user agrees to pay any taxes arising from access to
-this website or use of the information herein, except for those based on
-Unicode\x{2019}s net income.
-             4. Severability.  If any provision of this Agreement is declared
-invalid or unenforceable, the remaining provisions of this Agreement shall
-remain in effect.
-             5. Entire Agreement. This Agreement constitutes the entire
-agreement between the parties.
-
-EXHIBIT 1
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-    Unicode Data Files include all data files under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
-http://www.unicode.org/cldr/data/ . Unicode Software includes any source code
-published in the Unicode Standard or under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
-http://www.unicode.org/cldr/data/.
-
-    NOTICE TO USER: Carefully read the following legal agreement. BY
-DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES
-("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND
-AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF
-YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA
-FILES OR SOFTWARE.
-
-    COPYRIGHT AND PERMISSION NOTICE
-
-    Copyright  1991-2007 Unicode, Inc. All rights reserved. Distributed under
-the Terms of Use in http://www.unicode.org/copyright.html.
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-copy of the Unicode data files and any associated documentation (the "Data
-Files") or Unicode software and any associated documentation (the "Software")
-to deal in the Data Files or Software without restriction, including without
-limitation the rights to use, copy, modify, merge, publish, distribute, and/or
-sell copies of the Data Files or Software, and to permit persons to whom the
-Data Files or Software are furnished to do so, provided that (a) the above
-copyright notice(s) and this permission notice appear with all copies of the
-Data Files or Software, (b) both the above copyright notice(s) and this
-permission notice appear in associated documentation, and (c) there is clear
-notice in each modified Data File or in the Software as well as in the
-documentation associated with the Data File(s) or Software that the data or
-software has been modified.
-
-    THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
-PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
-THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
-DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
-SOFTWARE.
-
-    Except as contained in this notice, the name of a copyright holder shall
-not be used in advertising or otherwise to promote the sale, use or other
-dealings in these Data Files or Software without prior written authorization
-of the copyright holder.
-
-    Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
-registered in some jurisdictions. All other trademarks and registered
-trademarks mentioned herein are the property of their respective owners.
-
-
-****************************
-icu
-****************************
-ICU
-
-There are two licenses here:
-- ICU license
-- Unicode Terms of Use
-------------------------------------------------------------------------------
-ICU License - ICU 1.8.1 and later
-From http://source.icu-project.org/repos/icu/icu/trunk/license.html
-X License (old version). For license pedigree see the
-ICU FAQ at http://icu-project.org/userguide/icufaq.html
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1995-2006 International Business Machines Corporation and others
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, and/or sell copies of the
-Software, and to permit persons to whom the Software is furnished to do so,
-provided that the above copyright notice(s) and this permission notice appear
-in all copies of the Software and that both the above copyright notice(s) and
-this permission notice appear in supporting documentation.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
-LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not
-be used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization of the copyright holder.
-
-All trademarks and registered trademarks mentioned herein are the property of their respective owners.
-
-------------------------------------------------------------------------------
-Unicode Terms of Use, from http://www.unicode.org/copyright.html
-
-    For the general privacy policy governing access to this site, see the
-Unicode Privacy Policy. For trademark usage, see the Unicode Consortium
-Trademarks and Logo Policy.
-    Notice to End User: Terms of Use
-    Carefully read the following legal agreement ("Agreement"). Use or copying
-of the software and/or codes provided with this agreement (The "Software")
-constitutes your acceptance of these terms
-
-       1. Unicode Copyright.
-             1. Copyright  1991-2007 Unicode, Inc. All rights reserved.
-             2. Certain documents and files on this website contain a legend
-indicating that "Modification is permitted." Any person is hereby authorized,
-without fee, to modify such documents and files to create derivative works
-conforming to the Unicode Standard, subject to Terms and Conditions herein.
-             3. Any person is hereby authorized, without fee, to view, use,
-reproduce, and distribute all documents and files solely for informational
-purposes in the creation of products supporting the Unicode Standard, subject
-to the Terms and Conditions herein.
-             4. Further specifications of rights and restrictions pertaining
-to the use of the particular set of data files known as the "Unicode Character
-Database" can be found in Exhibit 1.
-             5. Each version of the Unicode Standard has further specifications
-of rights and restrictions of use. For the book editions, these are found on
-the back of the title page. For the online edition, certain files (such as the
-PDF files for book chapters and code charts) carry specific restrictions. All
-other files are covered under these general Terms of Use.  To request a
-permission to reproduce any part of the Unicode Standard, please contact the
-Unicode Consortium.
-             6. No license is granted to "mirror" the Unicode website where a
-fee is charged for access to the "mirror" site.
-             7. Modification is not permitted with respect to this document.
-All copies of this document must be verbatim.
-       2. Restricted Rights Legend. Any technical data or software which is
-licensed to the United States of America, its agencies and/or instrumentalities
-under this Agreement is commercial technical data or commercial computer
-software developed exclusively at private expense as defined in FAR 2.101, or
-DFARS 252.227-7014 (June 1995), as applicable. For technical data, use,
-duplication, or disclosure by the Government is subject to restrictions as set
-forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995)
-and this Agreement. For Software, in accordance with FAR 12-212 or
-DFARS 227-7202, as applicable, use, duplication or disclosure by the Government
-is subject to the restrictions set forth in this Agreement.
-       3. Warranties and Disclaimers.
-             1. This publication and/or website may include technical or
-typographical errors or other inaccuracies . Changes are periodically added to
-the information herein; these changes will be incorporated in new editions of
-the publication and/or website. Unicode may make improvements and/or changes
-in the product(s) and/or program(s) described in this publication and/or
-website at any time.
-             2. If this file has been purchased on magnetic or optical media
-from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange
-of the defective media within ninety (90) days of original purchase.
-             3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR
-SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS,
-IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
-UNICODE AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN
-THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR
-LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE.
-       4. Waiver of Damages. In no event shall Unicode or its licensors be
-liable for any special, incidental, indirect or consequential damages of any
-kind, or any damages whatsoever, whether or not Unicode was advised of the
-possibility of the damage, including, without limitation, those resulting from
-the following: loss of use, data or profits, in connection with the use,
-modification or distribution of this information or its derivatives.
-       5. Trademarks.
-             1. Unicode and the Unicode logo are registered trademarks of
-Unicode, Inc.
-             2. This site contains product names and corporate names of other
-companies. All product names and company names and logos mentioned herein are
-the trademarks or registered trademarks of their respective owners. Other
-products and corporate names mentioned herein which are trademarks of a third
-party are used only for explanation and for the owners' benefit and with no
-intent to infringe.
-             3. Use of third party products or information referred to herein
-is at the user\x{2019}s risk.
-       6. Miscellaneous.
-             1. Jurisdiction and Venue. This server is operated from a location
-in the State of California, United States of America. Unicode makes no
-representation that the materials are appropriate for use in other locations.
-If you access this server from other locations, you are responsible for
-compliance with local laws. This Agreement, all use of this site and any
-claims and damages resulting from use of this site are governed solely by the
-laws of the State of California without regard to any principles which would
-apply the laws of a different jurisdiction. The user agrees that any disputes
-regarding this site shall be resolved solely in the courts located in Santa
-Clara County, California. The user agrees said courts have personal
-jurisdiction and agree to waive any right to transfer the dispute to any other
-forum.
-             2. Modification by Unicode Unicode shall have the right to modify
-this Agreement at any time by posting it to this site. The user may not assign
-any part of this Agreement without Unicode\x{2019}s prior written consent.
-             3. Taxes. The user agrees to pay any taxes arising from access to
-this website or use of the information herein, except for those based on
-Unicode\x{2019}s net income.
-             4. Severability.  If any provision of this Agreement is declared
-invalid or unenforceable, the remaining provisions of this Agreement shall
-remain in effect.
-             5. Entire Agreement. This Agreement constitutes the entire
-agreement between the parties.
-
-EXHIBIT 1
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-    Unicode Data Files include all data files under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
-http://www.unicode.org/cldr/data/ . Unicode Software includes any source code
-published in the Unicode Standard or under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
-http://www.unicode.org/cldr/data/.
-
-    NOTICE TO USER: Carefully read the following legal agreement. BY
-DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES
-("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND
-AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF
-YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA
-FILES OR SOFTWARE.
-
-    COPYRIGHT AND PERMISSION NOTICE
-
-    Copyright  1991-2007 Unicode, Inc. All rights reserved. Distributed under
-the Terms of Use in http://www.unicode.org/copyright.html.
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-copy of the Unicode data files and any associated documentation (the "Data
-Files") or Unicode software and any associated documentation (the "Software")
-to deal in the Data Files or Software without restriction, including without
-limitation the rights to use, copy, modify, merge, publish, distribute, and/or
-sell copies of the Data Files or Software, and to permit persons to whom the
-Data Files or Software are furnished to do so, provided that (a) the above
-copyright notice(s) and this permission notice appear with all copies of the
-Data Files or Software, (b) both the above copyright notice(s) and this
-permission notice appear in associated documentation, and (c) there is clear
-notice in each modified Data File or in the Software as well as in the
-documentation associated with the Data File(s) or Software that the data or
-software has been modified.
-
-    THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
-PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
-THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
-DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
-SOFTWARE.
-
-    Except as contained in this notice, the name of a copyright holder shall
-not be used in advertising or otherwise to promote the sale, use or other
-dealings in these Data Files or Software without prior written authorization
-of the copyright holder.
-
-    Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
-registered in some jurisdictions. All other trademarks and registered
-trademarks mentioned herein are the property of their respective owners.
-
-
-****************************
-java/android_libs/exoplayer
-****************************
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-****************************
-java/android_libs/protobuf_nano
-****************************
-Copyright 2008, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Code generated by the Protocol Buffer compiler is owned by the owner
-of the input file used when generating it.  This code is not
-standalone and requires a support library to be linked with it.  This
-support library is itself covered by the above license.
-
-
-****************************
-javascript/jquery_ui
-****************************
-The MIT License (MIT)
-
-Copyright (c) 2015 jQuery Foundation and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-****************************
-javascript/jquery/v2_0_1
-****************************
-Copyright 2013 jQuery Foundation and other contributors
-http://jquery.com/
-
-https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt
-https://github.com/jquery/sizzle/blob/master/LICENSE
-
-jQuery and Sizzle are released under MIT Licence.
-
-The text is provided below.
-
-MIT License
-----
-
-Copyright 2013 jQuery Foundation and other contributors
-http://jquery.com/
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-****************************
-javascript/tracing_framework
-****************************
-Copyright 2012, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-java_src/android_libs/exoplayer
-****************************
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-****************************
-java_src/android_libs/protobuf_nano/v2
-****************************
-Copyright 2008, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Code generated by the Protocol Buffer compiler is owned by the owner
-of the input file used when generating it.  This code is not
-standalone and requires a support library to be linked with it.  This
-support library is itself covered by the above license.
-
-
-****************************
-jpeg
-****************************
-(extracted from src/README)
-
-LEGAL ISSUES
-============
-
-In plain English:
-
-1. We don't promise that this software works.  (But if you find any bugs,
-   please let us know!)
-2. You can use this software for whatever you want.  You don't have to pay us.
-3. You may not pretend that you wrote this software.  If you use it in a
-   program, you must acknowledge somewhere in your documentation that
-   you've used the IJG code.
-
-In legalese:
-
-The authors make NO WARRANTY or representation, either express or implied,
-with respect to this software, its quality, accuracy, merchantability, or
-fitness for a particular purpose.  This software is provided "AS IS", and you,
-its user, assume the entire risk as to its quality and accuracy.
-
-This software is copyright (C) 1991-1998, Thomas G. Lane.
-All Rights Reserved except as specified below.
-
-Permission is hereby granted to use, copy, modify, and distribute this
-software (or portions thereof) for any purpose, without fee, subject to these
-conditions:
-(1) If any part of the source code for this software is distributed, then this
-README file must be included, with this copyright and no-warranty notice
-unaltered; and any additions, deletions, or changes to the original files
-must be clearly indicated in accompanying documentation.
-(2) If only executable code is distributed, then the accompanying
-documentation must state that "this software is based in part on the work of
-the Independent JPEG Group".
-(3) Permission for use of this software is granted only if the user accepts
-full responsibility for any undesirable consequences; the authors accept
-NO LIABILITY for damages of any kind.
-
-These conditions apply to any software derived from or based on the IJG code,
-not just to the unmodified library.  If you use our work, you ought to
-acknowledge us.
-
-Permission is NOT granted for the use of any IJG author's name or company name
-in advertising or publicity relating to this software or products derived from
-it.  This software may be referred to only as "the Independent JPEG Group's
-software".
-
-We specifically permit and encourage the use of this software as the basis of
-commercial products, provided that all warranty or liability claims are
-assumed by the product vendor.
-
-
-ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
-sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
-ansi2knr.c is NOT covered by the above copyright and conditions, but instead
-by the usual distribution terms of the Free Software Foundation; principally,
-that you must include source code if you redistribute it.  (See the file
-ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
-of any program generated from the IJG code, this does not limit you more than
-the foregoing paragraphs do.
-
-The Unix configuration script "configure" was produced with GNU Autoconf.
-It is copyright by the Free Software Foundation but is freely distributable.
-The same holds for its supporting scripts (config.guess, config.sub,
-ltconfig, ltmain.sh).  Another support script, install-sh, is copyright
-by M.I.T. but is also freely distributable.
-
-It appears that the arithmetic coding option of the JPEG spec is covered by
-patents owned by IBM, AT&T, and Mitsubishi.  Hence arithmetic coding cannot
-legally be used without obtaining one or more licenses.  For this reason,
-support for arithmetic coding has been removed from the free JPEG software.
-(Since arithmetic coding provides only a marginal gain over the unpatented
-Huffman mode, it is unlikely that very many implementations will support it.)
-So far as we are aware, there are no patent restrictions on the remaining
-code.
-
-The IJG distribution formerly included code to read and write GIF files.
-To avoid entanglement with the Unisys LZW patent, GIF reading support has
-been removed altogether, and the GIF writer has been simplified to produce
-"uncompressed GIFs".  This technique does not use the LZW algorithm; the
-resulting GIF files are larger than usual, but are readable by all standard
-GIF decoders.
-
-We are required to state that
-    "The Graphics Interchange Format(c) is the Copyright property of
-    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
-    CompuServe Incorporated."
-
-
-****************************
-libogg
-****************************
-Copyright (c) 2002, Xiph.org Foundation
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-- Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-- Neither the name of the Xiph.org Foundation nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-****************************
-libunwind
-****************************
-Copyright (c) 2002 Hewlett-Packard Co.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-****************************
-libvorbis
-****************************
-Copyright (c) 2002-2008 Xiph.org Foundation
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-- Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-- Neither the name of the Xiph.org Foundation nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-libxcb
-****************************
-Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall
-be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the names of the authors
-or their institutions shall not be used in advertising or
-otherwise to promote the sale, use or other dealings in this
-Software without prior written authorization from the
-authors.
-
-
-****************************
-libxml
-****************************
-Libxml2, an XML C Parser
-
-Except where otherwise noted in the source code (e.g. the files hash.c,
-list.c and the trio files, which are covered by a similar licence but
-with different Copyright notices) all the files are:
-
- Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
---------------------------------------------------------------------
-
-Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-Author: breese@users.sourceforge.net
-
-(taken from hash.c)
-
---------------------------------------------------------------------
-
- Copyright (C) 2000 Gary Pennington and Daniel Veillard.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-Author: Gary.Pennington@uk.sun.com
-
-(taken from list.c)
-
---------------------------------------------------------------------
-
-Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-(taken from trio.h and trio.c)
-
---------------------------------------------------------------------
-
-Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-(taken from triodef.h, trionan.h, and trionan.c)
-
---------------------------------------------------------------------
-
-Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-(taken from triop.h)
-
---------------------------------------------------------------------
-
-Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-(taken from triostr.h and triostr.c)
-
-*************************************************************************
-
-http://ctrio.sourceforge.net/
-
-*************************************************************************
-
-
-****************************
-lodepng
-****************************
-LodePNG
-
-Copyright (c) 2005-2013 Lode Vandevenne
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-    1. The origin of this software must not be misrepresented; you must not
-    claim that you wrote the original software. If you use this software
-    in a product, an acknowledgment in the product documentation would be
-    appreciated but is not required.
-
-    2. Altered source versions must be plainly marked as such, and must not be
-    misrepresented as being the original software.
-
-    3. This notice may not be removed or altered from any source
-    distribution.
-
-
-****************************
-minizip
-****************************
-zlib
-
-(extracted from README, except for match.S)
-
-Copyright notice:
-
- (C) 1995-2004 Jean-loup Gailly and Mark Adler
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  Jean-loup Gailly        Mark Adler
-  jloup@gzip.org          madler@alumni.caltech.edu
-
-
-(extracted from match.S, for match.S only)
-
- Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
-
- This software is provided 'as-is', without any express or implied
- warranty.  In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
-    claim that you wrote the original software. If you use this software
-    in a product, an acknowledgment in the product documentation would be
-    appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
-    misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-****************************
-mongoose
-****************************
-Copyright (c) 2004-2013 Sergey Lyubka
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-
-****************************
-objective_c/gtm_session_fetcher
-****************************
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-****************************
-openctm
-****************************
-Copyright (c) 2009-2010 Marcus Geelnard
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-    1. The origin of this software must not be misrepresented; you must not
-    claim that you wrote the original software. If you use this software
-    in a product, an acknowledgment in the product documentation would be
-    appreciated but is not required.
-
-    2. Altered source versions must be plainly marked as such, and must not
-    be misrepresented as being the original software.
-
-    3. This notice may not be removed or altered from any source
-    distribution.
-
-
-****************************
-OpenCV
-****************************
-IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-
-By downloading, copying, installing or using the software you agree to this license.
-If you do not agree to this license, do not download, install,
-copy or use the software.
-
-
-                       Intel License Agreement
-               For Open Source Computer Vision Library
-
-Copyright (C) 2000, 2001, Intel Corporation, all rights reserved.
-Copyright (C) 2013, OpenCV Foundation, all rights reserved.
-Third party copyrights are property of their respective owners.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-  * Redistribution's of source code must retain the above copyright notice,
-    this list of conditions and the following disclaimer.
-
-  * Redistribution's in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
-
-  * The name of Intel Corporation may not be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-This software is provided by the copyright holders and contributors "as is" and
-any express or implied warranties, including, but not limited to, the implied
-warranties of merchantability and fitness for a particular purpose are disclaimed.
-In no event shall the Intel Corporation or contributors be liable for any direct,
-indirect, incidental, special, exemplary, or consequential damages
-(including, but not limited to, procurement of substitute goods or services;
-loss of use, data, or profits; or business interruption) however caused
-and on any theory of liability, whether in contract, strict liability,
-or tort (including negligence or otherwise) arising in any way out of
-the use of this software, even if advised of the possibility of such damage.
-
-****************************
-openssl
-****************************
-BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
-licensing. Files that are completely new have a Google copyright and an ISC
-license. This license is reproduced at the bottom of this file.
-
-Contributors to BoringSSL are required to follow the CLA rules for Chromium:
-https://cla.developers.google.com/clas
-
-Some files from Intel are under yet another license, which is also included
-underneath.
-
-The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
-OpenSSL License and the original SSLeay license apply to the toolkit. See below
-for the actual license texts. Actually both licenses are BSD-style Open Source
-licenses. In case of any license issues related to OpenSSL please contact
-openssl-core@openssl.org.
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-
-ISC license used for completely new code in BoringSSL:
-
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-
-Some files from Intel carry the following license:
-
-# Copyright (c) 2012, Intel Corporation
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# *  Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-#
-# *  Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the
-#    distribution.
-#
-# *  Neither the name of the Intel Corporation nor the names of its
-#    contributors may be used to endorse or promote products derived from
-#    this software without specific prior written permission.
-#
-#
-# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-openssl/boringssl
-****************************
-BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
-licensing. Files that are completely new have a Google copyright and an ISC
-license. This license is reproduced at the bottom of this file.
-
-Contributors to BoringSSL are required to follow the CLA rules for Chromium:
-https://cla.developers.google.com/clas
-
-Some files from Intel are under yet another license, which is also included
-underneath.
-
-The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
-OpenSSL License and the original SSLeay license apply to the toolkit. See below
-for the actual license texts. Actually both licenses are BSD-style Open Source
-licenses. In case of any license issues related to OpenSSL please contact
-openssl-core@openssl.org.
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-
-ISC license used for completely new code in BoringSSL:
-
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-
-Some files from Intel carry the following license:
-
-# Copyright (c) 2012, Intel Corporation
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# *  Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-#
-# *  Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the
-#    distribution.
-#
-# *  Neither the name of the Intel Corporation nor the names of its
-#    contributors may be used to endorse or promote products derived from
-#    this software without specific prior written permission.
-#
-#
-# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-pcre
-****************************
-PCRE LICENCE
-------------
-
-PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
-Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
-specified below. The documentation for PCRE, supplied in the "doc"
-directory, is distributed under the same terms as the software itself. The data
-in the testdata directory is not copyrighted and is in the public domain.
-
-The basic library functions are written in C and are freestanding. Also
-included in the distribution is a set of C++ wrapper functions, and a
-just-in-time compiler that can be used to optimize pattern matching. These
-are both optional features that can be omitted when the library is built.
-
-
-THE BASIC LIBRARY FUNCTIONS
----------------------------
-
-Written by:       Philip Hazel
-Email local part: ph10
-Email domain:     cam.ac.uk
-
-University of Cambridge Computing Service,
-Cambridge, England.
-
-Copyright (c) 1997-2015 University of Cambridge
-All rights reserved.
-
-
-PCRE JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
-
-Written by:       Zoltan Herczeg
-Email local part: hzmester
-Emain domain:     freemail.hu
-
-Copyright(c) 2010-2015 Zoltan Herczeg
-All rights reserved.
-
-
-STACK-LESS JUST-IN-TIME COMPILER
---------------------------------
-
-Written by:       Zoltan Herczeg
-Email local part: hzmester
-Emain domain:     freemail.hu
-
-Copyright(c) 2009-2015 Zoltan Herczeg
-All rights reserved.
-
-
-THE C++ WRAPPER FUNCTIONS
--------------------------
-
-Contributed by:   Google Inc.
-
-Copyright (c) 2007-2012, Google Inc.
-All rights reserved.
-
-
-THE "BSD" LICENCE
------------------
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
-
-    * Neither the name of the University of Cambridge nor the name of Google
-      Inc. nor the names of their contributors may be used to endorse or
-      promote products derived from this software without specific prior
-      written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-End
-
-
-****************************
-pffft
-****************************
-Copyright (c) 2013  Julien Pommier ( pommier@modartt.com )
-
-Based on original fortran 77 code from FFTPACKv4 from NETLIB,
-authored by Dr Paul Swarztrauber of NCAR, in 1985.
-
-As confirmed by the NCAR fftpack software curators, the following
-FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
-released under the same terms.
-
-FFTPACK license:
-
-http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
-
-Copyright (c) 2004 the University Corporation for Atmospheric
-Research ("UCAR"). All rights reserved. Developed by NCAR's
-Computational and Information Systems Laboratory, UCAR,
-www.cisl.ucar.edu.
-
-Redistribution and use of the Software in source and binary forms,
-with or without modification, is permitted provided that the
-following conditions are met:
-
-- Neither the names of NCAR's Computational and Information Systems
-Laboratory, the University Corporation for Atmospheric Research,
-nor the names of its sponsors or contributors may be used to
-endorse or promote products derived from this Software without
-specific prior written permission.
-
-- Redistributions of source code must retain the above copyright
-notices, this list of conditions, and the disclaimer below.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions, and the disclaimer below in the
-documentation and/or other materials provided with the
-distribution.
-
-THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
-SOFTWARE.
-
-
-****************************
-png
-****************************
-libpng
-
-This copy of the libpng notices is provided for your convenience.  In case of
-any discrepancy between this copy and the notices in the file png.h that is
-included in the libpng distribution, the latter shall prevail.
-
-COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
-
-If you modify libpng you may insert additional notices immediately following
-this sentence.
-
-libpng versions 1.2.6, August 15, 2004, through 1.2.27, April 29, 2008, are
-Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson, and are
-distributed according to the same disclaimer and license as libpng-1.2.5
-with the following individual added to the list of Contributing Authors
-
-   Cosmin Truta
-
-libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
-Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
-distributed according to the same disclaimer and license as libpng-1.0.6
-with the following individuals added to the list of Contributing Authors
-
-   Simon-Pierre Cadieux
-   Eric S. Raymond
-   Gilles Vollant
-
-and with the following additions to the disclaimer:
-
-   There is no warranty against interference with your enjoyment of the
-   library or against infringement.  There is no warranty that our
-   efforts or the library will fulfill any of your particular purposes
-   or needs.  This library is provided with all faults, and the entire
-   risk of satisfactory quality, performance, accuracy, and effort is with
-   the user.
-
-libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
-Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
-distributed according to the same disclaimer and license as libpng-0.96,
-with the following individuals added to the list of Contributing Authors:
-
-   Tom Lane
-   Glenn Randers-Pehrson
-   Willem van Schaik
-
-libpng versions 0.89, June 1996, through 0.96, May 1997, are
-Copyright (c) 1996, 1997 Andreas Dilger
-Distributed according to the same disclaimer and license as libpng-0.88,
-with the following individuals added to the list of Contributing Authors:
-
-   John Bowler
-   Kevin Bracey
-   Sam Bushell
-   Magnus Holmgren
-   Greg Roelofs
-   Tom Tanner
-
-libpng versions 0.5, May 1995, through 0.88, January 1996, are
-Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
-
-For the purposes of this copyright and license, "Contributing Authors"
-is defined as the following set of individuals:
-
-   Andreas Dilger
-   Dave Martindale
-   Guy Eric Schalnat
-   Paul Schmidt
-   Tim Wegner
-
-The PNG Reference Library is supplied "AS IS".  The Contributing Authors
-and Group 42, Inc. disclaim all warranties, expressed or implied,
-including, without limitation, the warranties of merchantability and of
-fitness for any purpose.  The Contributing Authors and Group 42, Inc.
-assume no liability for direct, indirect, incidental, special, exemplary,
-or consequential damages, which may result from the use of the PNG
-Reference Library, even if advised of the possibility of such damage.
-
-Permission is hereby granted to use, copy, modify, and distribute this
-source code, or portions hereof, for any purpose, without fee, subject
-to the following restrictions:
-
-1. The origin of this source code must not be misrepresented.
-
-2. Altered versions must be plainly marked as such and must not
-   be misrepresented as being the original source.
-
-3. This Copyright notice may not be removed or altered from any
-   source or altered source distribution.
-
-The Contributing Authors and Group 42, Inc. specifically permit, without
-fee, and encourage the use of this source code as a component to
-supporting the PNG file format in commercial products.  If you use this
-source code in a product, acknowledgment is not required but would be
-appreciated.
-
-
-A "png_get_copyright" function is available, for convenient use in "about"
-boxes and the like:
-
-   printf("%s",png_get_copyright(NULL));
-
-Also, the PNG logo (in PNG format, of course) is supplied in the
-files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
-
-Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
-certification mark of the Open Source Initiative.
-
-Glenn Randers-Pehrson
-glennrp at users.sourceforge.net
-April 29, 2008
-
-
-****************************
-protobuf
-****************************
-Copyright 2008, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Code generated by the Protocol Buffer compiler is owned by the owner
-of the input file used when generating it.  This code is not
-standalone and requires a support library to be linked with it.  This
-support library is itself covered by the above license.
-
-
-****************************
-re2
-****************************
-// Copyright (c) 2009 The RE2 Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-stblib
-****************************
-        License for STBLIB - A collection of public-domain single-file C/C++
-        libraries, primarily aimed at game developers.
-
-The compilation and test files are licensed under the MIT license, but the
-single-file libraries themselves are in the public domain (free for use and
-modification for any purpose without legal friction).
-
-The MIT License (MIT)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
-
-****************************
-stl
-****************************
-SGI STL
-
-The STL portion of GNU libstdc++ that is used with gcc3 and gcc4 is licensed
-under the GPL, with the following exception:
-
-# As a special exception, you may use this file as part of a free software
-# library without restriction.  Specifically, if other files instantiate
-# templates or use macros or inline functions from this file, or you compile
-# this file and link it with other files to produce an executable, this
-# file does not by itself cause the resulting executable to be covered by
-# the GNU General Public License.  This exception does not however
-# invalidate any other reasons why the executable file might be covered by
-# the GNU General Public License.
-
-
-
-****************************
-tinyxml
-****************************
-TinyXml is released under the zlib license:
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-
-
-
-****************************
-tz
-****************************
-With a few exceptions, all files in the tz code and data (including
-this one) are in the public domain.  The exceptions are tzcode's
-date.c, newstrftime.3, and strftime.c, which contain material derived
-from BSD and which use the BSD 3-clause license.
-
-
-****************************
-utf
-****************************
-UTF-8 Library
-
-The authors of this software are Rob Pike and Ken Thompson.
-             Copyright (c) 1998-2002 by Lucent Technologies.
-Permission to use, copy, modify, and distribute this software for any
-purpose without fee is hereby granted, provided that this entire notice
-is included in all copies of any software which is or includes a copy
-or modification of this software and in all copies of the supporting
-documentation for such software.
-THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
-REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
-OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-
-
-****************************
-xmpmeta
-****************************
-xmpmeta. A fast XMP metadata parsing and writing library.
-Copyright 2016 Google Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-* Neither the name of Google Inc. nor the names of its contributors may be
-  used to endorse or promote products derived from this software without
-  specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-
-****************************
-Xorg
-****************************
-The following is the 'standard copyright' agreed upon by most contributors,
-and is currently the canonical license preferred by the X.Org Foundation.
-This is a slight variant of the common MIT license form published by the
-Open Source Initiative at http://www.opensource.org/licenses/mit-license.php
-
-Copyright holders of new code should use this license statement where
-possible, and insert their name to this list.  Please sort by surname
-for people, and by the full name for other entities (e.g.  Juliusz
-Chroboczek sorts before Intel Corporation sorts before Daniel Stone).
-
-See each individual source file or directory for the license that applies
-to that file.
-
-Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
-Copyright © 2009 Red Hat, Inc.
-Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
- ----------------------------------------------------------------------
-
-The following licenses are 'legacy' - usually MIT/X11 licenses with the name
-of the copyright holder(s) in the license statement:
-
-Copyright 1984-1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-X Window System is a trademark of The Open Group.
-
-    ----------------------------------------
-
-Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 X Consortium
-Copyright 2000 The XFree86 Project, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from the X Consortium.
-
-Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
-Digital Equipment Corporation
-
-Portions Copyright 1990, 1991 by Tektronix, Inc.
-
-Permission to use, copy, modify and distribute this documentation for
-any purpose and without fee is hereby granted, provided that the above
-copyright notice appears in all copies and that both that copyright notice
-and this permission notice appear in all copies, and that the names of
-Digital and Tektronix not be used in in advertising or publicity pertaining
-to this documentation without specific, written prior permission.
-Digital and Tektronix makes no representations about the suitability
-of this documentation for any purpose.
-It is provided ``as is'' without express or implied warranty.
-
-    ----------------------------------------
-
-Copyright (c) 1999-2000  Free Software Foundation, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-FREE SOFTWARE FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Free Software Foundation
-shall not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization from the
-Free Software Foundation.
-
-    ----------------------------------------
-
-Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
-  All Rights Reserved
-
-This file is a component of an X Window System-specific implementation
-of Xcms based on the TekColor Color Management System.  TekColor is a
-trademark of Tektronix, Inc.  The term "TekHVC" designates a particular
-color space that is the subject of U.S. Patent No. 4,985,853 (equivalent
-foreign patents pending).  Permission is hereby granted to use, copy,
-modify, sell, and otherwise distribute this software and its
-documentation for any purpose and without fee, provided that:
-
-1. This copyright, permission, and disclaimer notice is reproduced in
-   all copies of this software and any modification thereof and in
-   supporting documentation;
-2. Any color-handling application which displays TekHVC color
-   cooordinates identifies these as TekHVC color coordinates in any
-   interface that displays these coordinates and in any associated
-   documentation;
-3. The term "TekHVC" is always used, and is only used, in association
-   with the mathematical derivations of the TekHVC Color Space,
-   including those provided in this file and any equivalent pathways and
-   mathematical derivations, regardless of digital (e.g., floating point
-   or integer) representation.
-
-Tektronix makes no representation about the suitability of this software
-for any purpose.  It is provided "as is" and with all faults.
-
-TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
-INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
-RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
-CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-(c) Copyright 1995 FUJITSU LIMITED
-This is source code modified by FUJITSU LIMITED under the Joint
-Development Agreement for the CDE/Motif PST.
-
-    ----------------------------------------
-
-Copyright 1992 by Oki Technosystems Laboratory, Inc.
-Copyright 1992 by Fuji Xerox Co., Ltd.
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of Oki Technosystems
-Laboratory and Fuji Xerox not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-Oki Technosystems Laboratory and Fuji Xerox make no representations
-about the suitability of this software for any purpose.  It is provided
-"as is" without express or implied warranty.
-
-OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
-LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
-OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1990, 1991, 1992, 1993, 1994 by FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of FUJITSU LIMITED
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-FUJITSU LIMITED makes no representations about the suitability of
-this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-
-Copyright (c) 1995 David E. Wexelblat.  All rights reserved
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL DAVID E. WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of David E. Wexelblat shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from David E. Wexelblat.
-
-    ----------------------------------------
-
-Copyright 1990, 1991 by OMRON Corporation
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name OMRON not be used in
-advertising or publicity pertaining to distribution of the software without
-specific, written prior permission.  OMRON makes no representations
-about the suitability of this software for any purpose.  It is provided
-"as is" without express or implied warranty.
-
-OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
-Digital Equipment Corporation
-
-Portions Copyright 1990, 1991 by Tektronix, Inc
-
-Rewritten for X.org by Chris Lee <clee@freedesktop.org>
-
-Permission to use, copy, modify, distribute, and sell this documentation
-for any purpose and without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-Chris Lee makes no representations about the suitability for any purpose
-of the information in this document.  It is provided \`\`as-is'' without
-express or implied warranty.
-
-    ----------------------------------------
-
-Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
-Copyright 1994 by FUJITSU LIMITED
-Copyright 1994 by Sony Corporation
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Digital, FUJITSU
-LIMITED and Sony Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
-AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-
-Copyright 1991 by the Open Software Foundation
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of Open Software Foundation
-not be used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  Open Software
-Foundation makes no representations about the suitability of this
-software for any purpose.  It is provided "as is" without express or
-implied warranty.
-
-OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN BE
-LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1990, 1991, 1992,1993, 1994 by FUJITSU LIMITED
-Copyright 1993, 1994                  by Sony Corporation
-
-Permission to use, copy, modify, distribute, and sell this software and
-its documentation for any purpose is hereby granted without fee, provided
-that the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of FUJITSU LIMITED and Sony Corporation
-not be used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  FUJITSU LIMITED and
-Sony Corporation makes no representations about the suitability of this
-software for any purpose.  It is provided "as is" without express or
-implied warranty.
-
-FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
-TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL FUJITSU LIMITED OR SONY CORPORATION BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
-RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
-USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright (c) 1993, 1995 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1991, 1992, 1993, 1994 by FUJITSU LIMITED
-Copyright 1993 by Digital Equipment Corporation
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of FUJITSU LIMITED and
-Digital Equipment Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.  FUJITSU LIMITED and Digital Equipment Corporation
-makes no representations about the suitability of this software for
-any purpose.  It is provided "as is" without express or implied
-warranty.
-
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
-ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1992, 1993 by FUJITSU LIMITED
-Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
-Copyright 1994 by Sony Corporation
-
-Permission to use, copy, modify, distribute and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of FUJITSU LIMITED,
-Fujitsu Open Systems Solutions, Inc. and Sony Corporation  not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-FUJITSU LIMITED, Fujitsu Open Systems Solutions, Inc. and
-Sony Corporation make no representations about the suitability of
-this software for any purpose.  It is provided "as is" without
-express or implied warranty.
-
-FUJITSU LIMITED, FUJITSU OPEN SYSTEMS SOLUTIONS, INC. AND SONY
-CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL FUJITSU OPEN SYSTEMS SOLUTIONS, INC., FUJITSU LIMITED
-AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
-OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1987, 1988, 1990, 1993 by Digital Equipment Corporation,
-Maynard, Massachusetts,
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1993 by SunSoft, Inc.
-Copyright 1999-2000 by Bruno Haible
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the names of SunSoft, Inc. and
-Bruno Haible not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.  SunSoft, Inc. and Bruno Haible make no representations
-about the suitability of this software for any purpose.  It is
-provided "as is" without express or implied warranty.
-
-SunSoft Inc. AND Bruno Haible DISCLAIM ALL WARRANTIES WITH REGARD
-TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS, IN NO EVENT SHALL SunSoft, Inc. OR Bruno Haible BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1991 by the Open Software Foundation
-Copyright 1993 by the TOSHIBA Corp.
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the names of Open Software Foundation and TOSHIBA
-not be used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  Open Software
-Foundation and TOSHIBA make no representations about the suitability of this
-software for any purpose.  It is provided "as is" without express or
-implied warranty.
-
-OPEN SOFTWARE FOUNDATION AND TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN OR TOSHIBA BE
-LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1988 by Wyse Technology, Inc., San Jose, Ca.,
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name Wyse not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-WYSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-    ----------------------------------------
-
-
-Copyright 1991 by the Open Software Foundation
-Copyright 1993, 1994 by the Sony Corporation
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the names of Open Software Foundation and
-Sony Corporation not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior permission.
-Open Software Foundation and Sony Corporation make no
-representations about the suitability of this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-OPEN SOFTWARE FOUNDATION AND SONY CORPORATION DISCLAIM ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OPEN
-SOFTWARE FOUNDATIONN OR SONY CORPORATION BE LIABLE FOR ANY SPECIAL,
-INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1992, 1993 by FUJITSU LIMITED
-Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
-
-Permission to use, copy, modify, distribute and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of FUJITSU LIMITED and
-Fujitsu Open Systems Solutions, Inc. not be used in advertising or
-publicity pertaining to distribution of the software without specific,
-written prior permission.
-FUJITSU LIMITED and Fujitsu Open Systems Solutions, Inc. makes no
-representations about the suitability of this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-FUJITSU LIMITED AND FUJITSU OPEN SYSTEMS SOLUTIONS, INC. DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU OPEN SYSTEMS
-SOLUTIONS, INC. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
-OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1993, 1994 by Sony Corporation
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of Sony Corporation
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-Sony Corporation makes no representations about the suitability of
-this software for any purpose. It is provided "as is" without
-express or implied warranty.
-
-SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1986, 1998  The Open Group
-Copyright (c) 2000  The XFree86 Project, Inc.
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium or of the
-XFree86 Project shall not be used in advertising or otherwise to promote the
-sale, use or other dealings in this Software without prior written
-authorization from the X Consortium and the XFree86 Project.
-
-    ----------------------------------------
-
-Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
-                     and Nippon Telegraph and Telephone Corporation
-Copyright 1991 by the Open Software Foundation
-Copyright 1993 by the FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the names of OMRON, NTT Software, NTT, and
-Open Software Foundation not be used in advertising or publicity
-pertaining to distribution of the software without specific,
-written prior permission. OMRON, NTT Software, NTT, and Open Software
-Foundation make no representations about the suitability of this
-software for any purpose.  It is provided "as is" without express or
-implied warranty.
-
-OMRON, NTT SOFTWARE, NTT, AND OPEN SOFTWARE FOUNDATION
-DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
-SHALL OMRON, NTT SOFTWARE, NTT, OR OPEN SOFTWARE FOUNDATION BE
-LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-
-Copyright 1991, 1992 by Fuji Xerox Co., Ltd.
-Copyright 1992, 1993, 1994 by FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of Fuji Xerox,
-FUJITSU LIMITED not be used in advertising or publicity pertaining
-to distribution of the software without specific, written prior
-permission. Fuji Xerox, FUJITSU LIMITED make no representations
-about the suitability of this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
-FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
-OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 2006 Josh Triplett
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-    ----------------------------------------
-
-(c) Copyright 1996 by Sebastien Marineau and Holger Veit
-      <marineau@genie.uottawa.ca>
-                     <Holger.Veit@gmd.de>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-HOLGER VEIT  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
-OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-Except as contained in this notice, the name of Sebastien Marineau or Holger Veit
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Holger Veit or
-Sebastien Marineau.
-
-    ----------------------------------------
-
-Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
-                     and Nippon Telegraph and Telephone Corporation
-Copyright 1991 by the Open Software Foundation
-Copyright 1993 by the TOSHIBA Corp.
-Copyright 1993, 1994 by Sony Corporation
-Copyright 1993, 1994 by the FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the names of OMRON, NTT Software, NTT, Open
-Software Foundation, and Sony Corporation not be used in advertising
-or publicity pertaining to distribution of the software without specific,
-written prior permission. OMRON, NTT Software, NTT, Open Software
-Foundation, and Sony Corporation  make no representations about the
-suitability of this software for any purpose.  It is provided "as is"
-without express or implied warranty.
-
-OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, AND SONY
-CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
-SHALL OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, OR SONY
-CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 2000 by Bruno Haible
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of Bruno Haible not
-be used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  Bruno Haible
-makes no representations about the suitability of this software for
-any purpose.  It is provided "as is" without express or implied
-warranty.
-
-Bruno Haible DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-NO EVENT SHALL Bruno Haible BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
-OR PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright © 2003 Keith Packard
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of Keith Packard not be used in
-advertising or publicity pertaining to distribution of the software without
-specific, written prior permission.  Keith Packard makes no
-representations about the suitability of this software for any purpose.  It
-is provided "as is" without express or implied warranty.
-
-KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-    ----------------------------------------
-
-Copyright (c) 2007-2009, Troy D. Hanson
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    ----------------------------------------
-
-Copyright 1992, 1993 by TOSHIBA Corp.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted, provided
-that the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of TOSHIBA not be used in advertising
-or publicity pertaining to distribution of the software without specific,
-written prior permission. TOSHIBA make no representations about the
-suitability of this software for any purpose.  It is provided "as is"
-without express or implied warranty.
-
-TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-
-    ----------------------------------------
-
-Copyright IBM Corporation 1993
-
-All Rights Reserved
-
-License to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of IBM not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
-NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
-IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-    ----------------------------------------
-
-Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
-                     and Nippon Telegraph and Telephone Corporation
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the names of OMRON, NTT Software, and NTT
-not be used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission. OMRON, NTT Software,
-and NTT make no representations about the suitability of this
-software for any purpose.  It is provided "as is" without express or
-implied warranty.
-
-OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD
-TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, BE
-LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-
-****************************
-zlib
-****************************
-(extracted from README, except for match.S)
-
-Copyright notice:
-
- (C) 1995-2013 Jean-loup Gailly and Mark Adler
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  Jean-loup Gailly        Mark Adler
-  jloup@gzip.org          madler@alumni.caltech.edu
-
-If you use the zlib library in a product, we would appreciate *not* receiving
-lengthy legal documents to sign.  The sources are provided for free but without
-warranty of any kind.  The library has been entirely written by Jean-loup
-Gailly and Mark Adler; it does not include third-party code.
-
-If you redistribute modified sources, we would appreciate that you include in
-the file ChangeLog history information documenting your changes.  Please read
-the FAQ for more information on the distribution of modified source versions.
-
-(extracted from match.S, for match.S only)
-
-Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
-
-This software is provided 'as-is', without any express or implied
-warranty.  In no event will the author be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
-  claim that you wrote the original software. If you use this software
-  in a product, an acknowledgment in the product documentation would be
-  appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
-  misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-
-
-****************************
-googleurl
-****************************
-Copyright 2007, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------------------
-
-The file url_parse.cc is based on nsURLParsers.cc from Mozilla. This file is
-licensed separately as follows:
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is mozilla.org code.
-
-The Initial Developer of the Original Code is
-Netscape Communications Corporation.
-Portions created by the Initial Developer are Copyright (C) 1998
-the Initial Developer. All Rights Reserved.
-
-Contributor(s):
-  Darin Fisher (original author)
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
--------------------------------------------------------------------------------
-
-The file icu_utf.cc is from IBM. This file is licensed separately as follows:
-
-ICU License - ICU 1.8.1 and later
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1995-2009 International Business Machines Corporation and others
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, and/or sell copies of the Software, and to permit persons
-to whom the Software is furnished to do so, provided that the above
-copyright notice(s) and this permission notice appear in all copies of
-the Software and that both the above copyright notice(s) and this
-permission notice appear in supporting documentation.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
-SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
-RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
-CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-of the copyright holder.
-
-
-****************************
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-****************************
-jsoncpp
-****************************
-The JsonCpp library's source code, including accompanying documentation,
-tests and demonstration applications, are licensed under the following
-conditions...
-
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
-jurisdictions which recognize such a disclaimer. In such jurisdictions,
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this
-software may choose to accept it either as 1) Public Domain, 2) under the
-conditions of the MIT License (see below), or 3) under the terms of dual
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-
-****************************
-libwebp
-****************************
-Copyright (c) 2010, Google Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-  * Neither the name of Google nor the names of its contributors may
-    be used to endorse or promote products derived from this software
-    without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/gvr-android-sdk/OWNERS b/third_party/gvr-android-sdk/OWNERS
deleted file mode 100644
index e9a59ed0..0000000
--- a/third_party/gvr-android-sdk/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-file://components/webxr/OWNERS
-mthiesse@chromium.org
-vollick@chromium.org
-
-per-file *.sha1=file://build/OWNERS
diff --git a/third_party/gvr-android-sdk/README.chromium b/third_party/gvr-android-sdk/README.chromium
deleted file mode 100644
index 331f14c2..0000000
--- a/third_party/gvr-android-sdk/README.chromium
+++ /dev/null
@@ -1,46 +0,0 @@
-Name: GVR Android SDK
-Short Name: gvr
-URL: https://github.com/googlevr/gvr-android-sdk
-Version: 1.130.0
-Date: 1 March 2018
-Revision: 233e7fe922a543e0bc55382d64cacd047307d0e7
-License: Apache 2.0
-License File: LICENSE
-Security Critical: yes
-Shipped: yes
-
-Description:
-The GVR Android SDK supports both Daydream and Cardboard, including a simple API
-used for creating apps inserted into Cardboard viewers, and the more complex API
-for supporting Daydream-ready phones and the Daydream controller.
-
-Local Modifications:
-- Due to binary size concern, we have decided to use a static shim library
-instead of the shared library that comes with this checkout. The static
-libraries are downloaded from a public storage through gclient sync.
-
-- For Version 1.10.0, we have two date: 6 Dec 2016 and 10 Feb 2017. The latter
-version cherrypick a CL that fix a crash on K and L.
-
-- All JNI calls in the static library also needs to be manually registered. So
-we have 3 jni related files. These files were generated by
-base/android/jni_generator/jni_generator.py from Java files. Modifications to
-these generated files are documented in the files.
-
- - The files generated by jni_generator.py use base::size which is not available
- from third_party; std::extent<decltype> was used instead, which is standard C++
- and available.
-
-- In order to run automated end-to-end tests on VR features, VR Services
-(com.google.vr.vrcore) and in some cases Daydream Home
-(com.google.android.vr.home) need to be installed before running tests. These
-are downloaded into test-apks/vr_services and test-apks/daydream_home,
-respectively. The downloaded APKs are the release APKs that are or were
-publicly available via the Play Store.
-
-- In order to run automated end-to-end tests that involve a Daydream controller,
-controller_test_api.aar needs to be present. This allows us to send controller
-events using broadcasts like a real controller sends them over Bluetooth. The
-library is open-sourced similar to the other .aars, but since it's only useful
-for Chromium at the moment, it is uploaded to storage instead of to GitHub like
-the GVR SDK.
diff --git a/third_party/gvr-android-sdk/controller_test_api_java.info b/third_party/gvr-android-sdk/controller_test_api_java.info
deleted file mode 100644
index 02a8986..0000000
--- a/third_party/gvr-android-sdk/controller_test_api_java.info
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated by //build/android/gyp/aar.py
-# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
-
-aidl = []
-assets = []
-has_classes_jar = true
-has_native_libraries = false
-has_proguard_flags = false
-has_r_text_file = false
-is_manifest_empty = true
-manifest_package = "com.google.vr.testframework.controller"
-resources = []
-subjar_tuples = []
-subjars = []
diff --git a/third_party/gvr-android-sdk/display_synchronizer_jni.h b/third_party/gvr-android-sdk/display_synchronizer_jni.h
deleted file mode 100644
index 0a76439..0000000
--- a/third_party/gvr-android-sdk/display_synchronizer_jni.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is of the same format as file that generated by
-//     third_party/jni_zero/jni_zero.py
-// For
-//     com/google/vr/cardboard/DisplaySynchronizer
-
-// Local modification includes:
-// 1. Remove all implementation, only keep definition.
-// 2. Use absolute path instead of relative path.
-// 3. Removed all helper functions such as: Create.
-// 4. Added function RegisterDisplaySynchronizerNatives at the end of this file.
-// 5. Added "vr" as an argument to base::android::LazyGetClass.
-
-#ifndef com_google_vr_cardboard_DisplaySynchronizer_JNI
-#define com_google_vr_cardboard_DisplaySynchronizer_JNI
-
-#include "base/android/jni_android.h"
-// ----------------------------------------------------------------------------
-// Native JNI methods
-// ----------------------------------------------------------------------------
-#include <jni.h>
-#include <atomic>
-#include <type_traits>
-
-#include "third_party/jni_zero/jni_int_wrapper.h"
-#include "third_party/jni_zero/jni_zero_helper.h"
-
-// Step 1: forward declarations.
-namespace {
-
-const char kDisplaySynchronizerClassPath[] =
-    "com/google/vr/cardboard/DisplaySynchronizer";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-std::atomic<jclass> g_DisplaySynchronizer_clazz __attribute__((unused))
-    (nullptr);
-#define DisplaySynchronizer_clazz(env)                                  \
-  base::android::LazyGetClass(env, kDisplaySynchronizerClassPath, "vr", \
-                              &g_DisplaySynchronizer_clazz)
-
-}  // namespace
-
-namespace DisplaySynchronizer {
-
-extern "C" __attribute__((visibility("default"))) jlong
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate(
-    JNIEnv* env,
-    jobject jcaller,
-    jclass classLoader,
-    jobject appContext);
-
-// Step 2: method stubs.
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer);
-
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer,
-    jlong expectedInterval,
-    jlong vsyncOffset);
-
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer,
-    jlong syncTime,
-    jint currentRotation);
-
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged(
-    JNIEnv* env,
-    jobject obj,
-    jlong native_object);
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsDisplaySynchronizer[] = {
-    {"nativeCreate",
-     "("
-     "Ljava/lang/ClassLoader;"
-     "Landroid/content/Context;"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate)},
-    {"nativeDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy)},
-    {"nativeReset",
-     "("
-     "J"
-     "J"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset)},
-    {"nativeUpdate",
-     "("
-     "J"
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate)},
-    {"nativeOnMetricsChanged",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged)},
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
-  const int kMethodsDisplaySynchronizerSize =
-      std::extent<decltype(kMethodsDisplaySynchronizer)>();
-
-  if (env->RegisterNatives(DisplaySynchronizer_clazz(env),
-                           kMethodsDisplaySynchronizer,
-                           kMethodsDisplaySynchronizerSize) < 0) {
-    jni_generator::HandleRegistrationError(env, DisplaySynchronizer_clazz(env),
-                                           __FILE__);
-    return false;
-  }
-
-  return true;
-}
-
-static bool RegisterDisplaySynchronizerNatives(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
-}  // namespace DisplaySynchronizer
-
-#endif  // com_google_vr_cardboard_DisplaySynchronizer_JNI
diff --git a/third_party/gvr-android-sdk/gvr_api_jni.h b/third_party/gvr-android-sdk/gvr_api_jni.h
deleted file mode 100644
index b4cde5ed..0000000
--- a/third_party/gvr-android-sdk/gvr_api_jni.h
+++ /dev/null
@@ -1,1745 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is of the same format as file that generated by
-//     base/android/jni_generator/jni_generator.py
-// For
-//     com/google/vr/ndk/base/GvrApi
-
-// Local modification includes:
-// 1. Remove all implementation, only keep definition.
-// 2. Use absolute path instead of relative path.
-// 3. Removed all helper functions such as: Create.
-// 4. Removed external functions that don't have implementation in shim file.
-// 5. Changed RectF, Point, and PoseTracker to correct package name.
-// 6. Added function RegisterGvrApiNatives at the end of this file.
-// 7. Added "vr" as an argument to base::android::LazyGetClass.
-
-#ifndef com_google_vr_ndk_base_GvrApi_JNI
-#define com_google_vr_ndk_base_GvrApi_JNI
-
-#include "base/android/jni_android.h"
-// ----------------------------------------------------------------------------
-// Native JNI methods
-// ----------------------------------------------------------------------------
-#include <jni.h>
-#include <atomic>
-#include <type_traits>
-
-#include "third_party/jni_zero/jni_int_wrapper.h"
-#include "third_party/jni_zero/jni_zero_helper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kGvrApiClassPath[] = "com/google/vr/ndk/base/GvrApi";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-std::atomic<jclass> g_GvrApi_clazz __attribute__((unused)) (nullptr);
-#define GvrApi_clazz(env) \
-  base::android::LazyGetClass(env, kGvrApiClassPath, "vr", &g_GvrApi_clazz)
-
-}  // namespace
-
-namespace GvrApi {
-// Step 2: method stubs.
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListCreate(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListDestroy(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewportList);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetSize(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewportList);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetItem(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewportList,
-    jint index,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListSetItem(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewportList,
-    jint index,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportCreate(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportDestroy(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceUv(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jobject out);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceUv(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jfloat left,
-    jfloat top,
-    jfloat right,
-    jfloat bottom);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceFov(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jobject out);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceFov(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jfloat left,
-    jfloat top,
-    jfloat right,
-    jfloat bottom);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTransform(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jfloatArray matrix);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTransform(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jfloatArray matrix);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportEqual(JNIEnv* env,
-                                                             jclass jcaller,
-                                                             jlong nativeA,
-                                                             jlong nativeB);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTargetEye(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTargetEye(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jint eye);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceBufferIndex(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceBufferIndex(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jint index);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetExternalSurfaceId(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurfaceId(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jint id);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurface(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jlong nativeExternalSurface);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetReprojection(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetReprojection(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jint reprojection);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceLayer(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferViewport,
-    jint layerIndex);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecCreate(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecDestroy(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSize(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jobject size);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSize(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jint width,
-    jint height);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetColorFormat(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jint format);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetDepthStencilFormat(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jint format);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetMultiviewLayers(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jint numLayers);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSamples(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSamples(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec,
-    jint samples);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceCreateWithListeners(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeGvrContext,
-    jobject surfaceListener,
-    jobject frameListener,
-    jobject handler);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceDestroy(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetId(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec);
-
-JNI_BOUNDARY_EXPORT jobject
-Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetSurface(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeBufferSpec);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainCreate(JNIEnv* env,
-                                                         jclass jcaller,
-                                                         jlong nativeContext,
-                                                         jlongArray specs);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainDestroy(JNIEnv* env,
-                                                          jclass jcaller,
-                                                          jlong nativeContext);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferCount(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeSwapChain);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferSize(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeSwapChain,
-    jint bufferIndex,
-    jobject size);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainResizeBuffer(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeSwapChain,
-    jint bufferIndex,
-    jint width,
-    jint height);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainAcquireFrame(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeSwapChain);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeFrameBindBuffer(JNIEnv* env,
-                                                         jclass jcaller,
-                                                         jlong nativeFrame,
-                                                         jint bufferIndex);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeFrameUnbind(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeFrame);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetFramebufferObject(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeFrame,
-    jint bufferIndex);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetBufferSize(JNIEnv* env,
-                                                            jclass jcaller,
-                                                            jlong nativeFrame,
-                                                            jint bufferIndex,
-                                                            jobject size);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeFrameSubmit(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeFrame,
-    jlong nativeBufferViewportList,
-    jfloatArray headSpaceFromStartSpace);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeUsingDynamicLibrary(JNIEnv* env,
-                                                             jclass jcaller);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeUsingShimLibrary(JNIEnv* env,
-                                                          jclass jcaller);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetApplicationState(JNIEnv* env,
-                                                             jclass jcaller,
-                                                             jclass classLoader,
-                                                             jobject context);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetDynamicLibraryLoadingEnabled(
-    JNIEnv* env,
-    jclass jcaller,
-    jboolean enabled);
-
-JNI_BOUNDARY_EXPORT jlong Java_com_google_vr_ndk_base_GvrApi_nativeCreate(
-    JNIEnv* env,
-    jobject jcaller,
-    jclass classLoader,
-    jobject context,
-    jlong synchronizer,
-    jint widthPixels,
-    jint heightPixels,
-    jfloat xDpi,
-    jfloat yDpi,
-    jobject optionalPoseTrackingForTesting);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeRequestContextSharing(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jobject eglListener);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeGetError(JNIEnv* env,
-                                                  jobject jcaller,
-                                                  jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeClearError(JNIEnv* env,
-                                                    jobject jcaller,
-                                                    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jstring
-Java_com_google_vr_ndk_base_GvrApi_nativeGetErrorString(JNIEnv* env,
-                                                        jclass jcaller,
-                                                        jint errorCode);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeGetUserPrefs(JNIEnv* env,
-                                                      jobject jcaller,
-                                                      jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeUserPrefsGetControllerHandedness(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeUserPrefs);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativePause(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeResume(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeReleaseGvrContext(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeInitializeGl(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceCreatedReprojectionThread(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceChangedReprojectionThread(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetRecommendedBufferViewports(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jlong nativeBufferViewportList);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenBufferViewports(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jlong nativeBufferViewportList);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetMaximumEffectiveRenderTargetSize(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jobject size);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenTargetSize(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jobject size);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeDistortToScreen(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint textureId,
-    jlong nativeBufferViewportList,
-    jfloatArray headSpaceFromStartSpace,
-    jlong timeNs);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultFramebufferActive(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jobject
-Java_com_google_vr_ndk_base_GvrApi_nativeRenderReprojectionThread(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeOnPauseReprojectionThread(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceRotation(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jfloatArray outRotation,
-    jlong timeNs);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceTransform(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jfloatArray outTransform,
-    jlong timeNs);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetIgnoreManualPauseResumeTracker(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jboolean shouldIgnore);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativePauseTracking(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jbyteArray
-Java_com_google_vr_ndk_base_GvrApi_nativePauseTrackingGetState(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeResumeTracking(JNIEnv* env,
-                                                        jobject jcaller,
-                                                        jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeResumeTrackingSetState(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jbyteArray trackerStateBytes);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeResetTracking(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeRecenterTracking(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetEyeFromHeadMatrix(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint eye,
-    jfloatArray out);
-
-JNI_BOUNDARY_EXPORT jintArray
-Java_com_google_vr_ndk_base_GvrApi_nativeGetWindowBounds(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jfloatArray
-Java_com_google_vr_ndk_base_GvrApi_nativeComputeDistortedPoint(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint eyeType,
-    jfloatArray uvIn);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultViewerProfile(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jstring viewerProfileUri);
-
-JNI_BOUNDARY_EXPORT jstring
-Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerVendor(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jstring
-Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerModel(JNIEnv* env,
-                                                        jobject jcaller,
-                                                        jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerType(JNIEnv* env,
-                                                       jobject jcaller,
-                                                       jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeSetAsyncReprojectionEnabled(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jboolean enabled);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeGetAsyncReprojectionEnabled(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeIsFeatureSupported(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint feature);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeReconnectSensors(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetIdleListener(JNIEnv* env,
-                                                         jobject jcaller,
-                                                         jlong nativeGvrContext,
-                                                         jobject idleListener);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeSetViewerParams(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jbyteArray serializedViewerParams);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetDisplayMetrics(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint widthPixels,
-    jint heightPixels,
-    jfloat xDpi,
-    jfloat yDpi);
-
-JNI_BOUNDARY_EXPORT jfloat
-Java_com_google_vr_ndk_base_GvrApi_nativeGetBorderSizeMeters(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeSetSurfaceSize(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jint surfaceWidthPixels,
-    jint surfaceHeightPixels);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeSetLensOffset(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext,
-    jfloat x,
-    jfloat y,
-    jfloat rotation);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDumpDebugData(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeUsingVrDisplayService(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeGvrContext);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeCreateEvent(JNIEnv* env, jclass clazz);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeCreateValue(JNIEnv* env, jclass clazz);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDestroyEvent(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDestroyValue(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeGetCurrentProperties(
-    JNIEnv* env,
-    jobject object,
-    jlong native_object);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeGetEventFlags(JNIEnv* env,
-                                                       jclass clazz,
-                                                       jlong native_object);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeGetEventTimestamp(JNIEnv* env,
-                                                           jclass clazz,
-                                                           jlong native_object);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeGetEventType(JNIEnv* env,
-                                                      jclass clazz,
-                                                      jlong native_object);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativeGetProperty(JNIEnv* env,
-                                                     jclass clazz,
-                                                     jlong native_properties,
-                                                     jint property_key,
-                                                     jlong native_value);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventFlags(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object,
-    jfloatArray rotation_out_array);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventType(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object);
-
-JNI_BOUNDARY_EXPORT jboolean
-Java_com_google_vr_ndk_base_GvrApi_nativePollEvent(JNIEnv* env,
-                                                   jobject object,
-                                                   jlong native_object,
-                                                   jlong event_out);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFlags(JNIEnv* env,
-                                                      jclass clazz,
-                                                      jlong native_object);
-
-JNI_BOUNDARY_EXPORT jfloat
-Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFloat(JNIEnv* env,
-                                                      jclass clazz,
-                                                      jlong native_object);
-
-JNI_BOUNDARY_EXPORT jint
-Java_com_google_vr_ndk_base_GvrApi_nativeValueAsInt(JNIEnv* env,
-                                                    jclass clazz,
-                                                    jlong native_object);
-
-JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeValueAsMat4f(
-    JNIEnv* env,
-    jclass clazz,
-    jlong native_object,
-    jfloatArray mat4_out_array);
-
-JNI_BOUNDARY_EXPORT jlong
-Java_com_google_vr_ndk_base_GvrApi_nativeValueGetFlags(JNIEnv* env,
-                                                       jclass clazz,
-                                                       jlong native_object);
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsGvrApi[] = {
-    {"nativeBufferViewportListCreate",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListCreate)},
-    {"nativeBufferViewportListDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListDestroy)},
-    {"nativeBufferViewportListGetSize",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetSize)},
-    {"nativeBufferViewportListGetItem",
-     "("
-     "J"
-     "I"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetItem)},
-    {"nativeBufferViewportListSetItem",
-     "("
-     "J"
-     "I"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListSetItem)},
-    {"nativeBufferViewportCreate",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportCreate)},
-    {"nativeBufferViewportDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportDestroy)},
-    {"nativeBufferViewportGetSourceUv",
-     "("
-     "J"
-     "Landroid/graphics/RectF;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceUv)},
-    {"nativeBufferViewportSetSourceUv",
-     "("
-     "J"
-     "F"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceUv)},
-    {"nativeBufferViewportGetSourceFov",
-     "("
-     "J"
-     "Landroid/graphics/RectF;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceFov)},
-    {"nativeBufferViewportSetSourceFov",
-     "("
-     "J"
-     "F"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceFov)},
-    {"nativeBufferViewportGetTransform",
-     "("
-     "J"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTransform)},
-    {"nativeBufferViewportSetTransform",
-     "("
-     "J"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTransform)},
-    {"nativeBufferViewportEqual",
-     "("
-     "J"
-     "J"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportEqual)},
-    {"nativeBufferViewportGetTargetEye",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTargetEye)},
-    {"nativeBufferViewportSetTargetEye",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTargetEye)},
-    {"nativeBufferViewportGetSourceBufferIndex",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceBufferIndex)},
-    {"nativeBufferViewportSetSourceBufferIndex",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceBufferIndex)},
-    {"nativeBufferViewportGetExternalSurfaceId",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetExternalSurfaceId)},
-    {"nativeBufferViewportSetExternalSurfaceId",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurfaceId)},
-    {"nativeBufferViewportSetExternalSurface",
-     "("
-     "J"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurface)},
-    {"nativeBufferViewportGetReprojection",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetReprojection)},
-    {"nativeBufferViewportSetReprojection",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetReprojection)},
-    {"nativeBufferViewportSetSourceLayer",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceLayer)},
-    {"nativeBufferSpecCreate",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecCreate)},
-    {"nativeBufferSpecDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecDestroy)},
-    {"nativeBufferSpecGetSize",
-     "("
-     "J"
-     "Landroid/graphics/Point;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSize)},
-    {"nativeBufferSpecSetSize",
-     "("
-     "J"
-     "I"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSize)},
-    {"nativeBufferSpecSetColorFormat",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetColorFormat)},
-    {"nativeBufferSpecSetDepthStencilFormat",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetDepthStencilFormat)},
-    {"nativeBufferSpecSetMultiviewLayers",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetMultiviewLayers)},
-    {"nativeBufferSpecGetSamples",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSamples)},
-    {"nativeBufferSpecSetSamples",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSamples)},
-    {"nativeExternalSurfaceCreateWithListeners",
-     "("
-     "J"
-     "Ljava/lang/Runnable;"
-     "Ljava/lang/Runnable;"
-     "Landroid/os/Handler;"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceCreateWithListeners)},
-    {"nativeExternalSurfaceDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceDestroy)},
-    {"nativeExternalSurfaceGetId",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetId)},
-    {"nativeExternalSurfaceGetSurface",
-     "("
-     "J"
-     ")"
-     "Landroid/view/Surface;",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetSurface)},
-    {"nativeSwapChainCreate",
-     "("
-     "J"
-     "[J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainCreate)},
-    {"nativeSwapChainDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainDestroy)},
-    {"nativeSwapChainGetBufferCount",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferCount)},
-    {"nativeSwapChainGetBufferSize",
-     "("
-     "J"
-     "I"
-     "Landroid/graphics/Point;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferSize)},
-    {"nativeSwapChainResizeBuffer",
-     "("
-     "J"
-     "I"
-     "I"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainResizeBuffer)},
-    {"nativeSwapChainAcquireFrame",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainAcquireFrame)},
-    {"nativeFrameBindBuffer",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeFrameBindBuffer)},
-    {"nativeFrameUnbind",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeFrameUnbind)},
-    {"nativeFrameGetFramebufferObject",
-     "("
-     "J"
-     "I"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetFramebufferObject)},
-    {"nativeFrameGetBufferSize",
-     "("
-     "J"
-     "I"
-     "Landroid/graphics/Point;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetBufferSize)},
-    {"nativeFrameSubmit",
-     "("
-     "J"
-     "J"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeFrameSubmit)},
-    {"nativeUsingDynamicLibrary",
-     "("
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeUsingDynamicLibrary)},
-    {"nativeUsingShimLibrary",
-     "("
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeUsingShimLibrary)},
-    {"nativeSetApplicationState",
-     "("
-     "Ljava/lang/ClassLoader;"
-     "Landroid/content/Context;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetApplicationState)},
-    {"nativeSetDynamicLibraryLoadingEnabled",
-     "("
-     "Z"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetDynamicLibraryLoadingEnabled)},
-    {"nativeCreate",
-     "("
-     "Ljava/lang/ClassLoader;"
-     "Landroid/content/Context;"
-     "J"
-     "I"
-     "I"
-     "F"
-     "F"
-     "Lcom/google/vr/ndk/base/GvrApi$PoseTracker;"
-     ")"
-     "J",
-     reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativeCreate)},
-    {"nativeRequestContextSharing",
-     "("
-     "J"
-     "Lcom/google/vr/cardboard/EglReadyListener;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeRequestContextSharing)},
-    {"nativeGetError",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetError)},
-    {"nativeClearError",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeClearError)},
-    {"nativeGetErrorString",
-     "("
-     "I"
-     ")"
-     "Ljava/lang/String;",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetErrorString)},
-    {"nativeGetUserPrefs",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetUserPrefs)},
-    {"nativeUserPrefsGetControllerHandedness",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeUserPrefsGetControllerHandedness)},
-    {"nativePause",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativePause)},
-    {"nativeResume",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativeResume)},
-    {"nativeReleaseGvrContext",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeReleaseGvrContext)},
-    {"nativeInitializeGl",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeInitializeGl)},
-    {"nativeOnSurfaceCreatedReprojectionThread",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceCreatedReprojectionThread)},
-    {"nativeOnSurfaceChangedReprojectionThread",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceChangedReprojectionThread)},
-    {"nativeGetRecommendedBufferViewports",
-     "("
-     "J"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetRecommendedBufferViewports)},
-    {"nativeGetScreenBufferViewports",
-     "("
-     "J"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenBufferViewports)},
-    {"nativeGetMaximumEffectiveRenderTargetSize",
-     "("
-     "J"
-     "Landroid/graphics/Point;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetMaximumEffectiveRenderTargetSize)},
-    {"nativeGetScreenTargetSize",
-     "("
-     "J"
-     "Landroid/graphics/Point;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenTargetSize)},
-    {"nativeDistortToScreen",
-     "("
-     "J"
-     "I"
-     "J"
-     "[F"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeDistortToScreen)},
-    {"nativeSetDefaultFramebufferActive",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultFramebufferActive)},
-    {"nativeRenderReprojectionThread",
-     "("
-     "J"
-     ")"
-     "Landroid/graphics/Point;",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeRenderReprojectionThread)},
-    {"nativeOnPauseReprojectionThread",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeOnPauseReprojectionThread)},
-    {"nativeGetHeadSpaceFromStartSpaceRotation",
-     "("
-     "J"
-     "[F"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceRotation)},
-    {"nativeGetHeadSpaceFromStartSpaceTransform",
-     "("
-     "J"
-     "[F"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceTransform)},
-    {"nativeSetIgnoreManualPauseResumeTracker",
-     "("
-     "J"
-     "Z"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetIgnoreManualPauseResumeTracker)},
-    {"nativePauseTracking",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativePauseTracking)},
-    {"nativePauseTrackingGetState",
-     "("
-     "J"
-     ")"
-     "[B",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativePauseTrackingGetState)},
-    {"nativeResumeTracking",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeResumeTracking)},
-    {"nativeResumeTrackingSetState",
-     "("
-     "J"
-     "[B"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeResumeTrackingSetState)},
-    {"nativeResetTracking",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeResetTracking)},
-    {"nativeRecenterTracking",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeRecenterTracking)},
-    {"nativeGetEyeFromHeadMatrix",
-     "("
-     "J"
-     "I"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetEyeFromHeadMatrix)},
-    {"nativeGetWindowBounds",
-     "("
-     "J"
-     ")"
-     "[I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetWindowBounds)},
-    {"nativeComputeDistortedPoint",
-     "("
-     "J"
-     "I"
-     "[F"
-     ")"
-     "[F",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeComputeDistortedPoint)},
-    {"nativeSetDefaultViewerProfile",
-     "("
-     "J"
-     "Ljava/lang/String;"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultViewerProfile)},
-    {"nativeGetViewerVendor",
-     "("
-     "J"
-     ")"
-     "Ljava/lang/String;",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerVendor)},
-    {"nativeGetViewerModel",
-     "("
-     "J"
-     ")"
-     "Ljava/lang/String;",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerModel)},
-    {"nativeGetViewerType",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerType)},
-    {"nativeSetAsyncReprojectionEnabled",
-     "("
-     "J"
-     "Z"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetAsyncReprojectionEnabled)},
-    {"nativeGetAsyncReprojectionEnabled",
-     "("
-     "J"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetAsyncReprojectionEnabled)},
-    {"nativeIsFeatureSupported",
-     "("
-     "J"
-     "I"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeIsFeatureSupported)},
-    {"nativeReconnectSensors",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeReconnectSensors)},
-    {"nativeSetIdleListener",
-     "("
-     "J"
-     "Lcom/google/vr/ndk/base/GvrApi$IdleListener;"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetIdleListener)},
-    {"nativeSetViewerParams",
-     "("
-     "J"
-     "[B"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetViewerParams)},
-    {"nativeSetDisplayMetrics",
-     "("
-     "J"
-     "I"
-     "I"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetDisplayMetrics)},
-    {"nativeGetBorderSizeMeters",
-     "("
-     "J"
-     ")"
-     "F",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetBorderSizeMeters)},
-    {"nativeSetSurfaceSize",
-     "("
-     "J"
-     "I"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetSurfaceSize)},
-    {"nativeSetLensOffset",
-     "("
-     "J"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeSetLensOffset)},
-    {"nativeDumpDebugData",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeDumpDebugData)},
-    {"nativeUsingVrDisplayService",
-     "("
-     "J"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeUsingVrDisplayService)},
-    {"nativeCreateEvent",
-     "("
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeCreateEvent)},
-    {"nativeCreateValue",
-     "("
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeCreateValue)},
-    {"nativeDestroyEvent",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeDestroyEvent)},
-    {"nativeDestroyValue",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeDestroyValue)},
-    {"nativeGetCurrentProperties",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetCurrentProperties)},
-    {"nativeGetEventFlags",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetEventFlags)},
-    {"nativeGetEventTimestamp",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetEventTimestamp)},
-    {"nativeGetEventType",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetEventType)},
-    {"nativeGetProperty",
-     "("
-     "J"
-     "I"
-     "J"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetProperty)},
-    {"nativeGetRecenterEventFlags",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventFlags)},
-    {"nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform",
-     "("
-     "J"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform)},
-    {"nativeGetRecenterEventType",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventType)},
-    {"nativePollEvent",
-     "("
-     "J"
-     "J"
-     ")"
-     "Z",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativePollEvent)},
-    {"nativeValueAsFlags",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFlags)},
-    {"nativeValueAsFloat",
-     "("
-     "J"
-     ")"
-     "F",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFloat)},
-    {"nativeValueAsInt",
-     "("
-     "J"
-     ")"
-     "I",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeValueAsInt)},
-    {"nativeValueAsMat4f",
-     "("
-     "J"
-     "[F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeValueAsMat4f)},
-    {"nativeValueGetFlags",
-     "("
-     "J"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_ndk_base_GvrApi_nativeValueGetFlags)},
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
-  const int kMethodsGvrApiSize = std::extent<decltype(kMethodsGvrApi)>();
-
-  if (env->RegisterNatives(GvrApi_clazz(env), kMethodsGvrApi,
-                           kMethodsGvrApiSize) < 0) {
-    jni_generator::HandleRegistrationError(env, GvrApi_clazz(env), __FILE__);
-    return false;
-  }
-
-  return true;
-}
-
-static bool RegisterGvrApiNatives(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
-}  // namespace GvrApi
-
-#endif  // com_google_vr_ndk_base_GvrApi_JNI
diff --git a/third_party/gvr-android-sdk/gvr_common_java.info b/third_party/gvr-android-sdk/gvr_common_java.info
deleted file mode 100644
index 788e67c..0000000
--- a/third_party/gvr-android-sdk/gvr_common_java.info
+++ /dev/null
@@ -1,87 +0,0 @@
-# Generated by //build/android/gyp/aar.py
-# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
-
-aidl = []
-assets = []
-has_classes_jar = true
-has_native_libraries = false
-has_proguard_flags = false
-has_r_text_file = true
-is_manifest_empty = true
-manifest_package = "com.google.vr.cardboard"
-resources = [
-  "res/drawable-hdpi-v4/quantum_ic_close_white_24.png",
-  "res/drawable-hdpi-v4/quantum_ic_settings_white_24.png",
-  "res/drawable-hdpi-v4/transition.png",
-  "res/drawable-mdpi-v4/quantum_ic_close_white_24.png",
-  "res/drawable-mdpi-v4/quantum_ic_settings_white_24.png",
-  "res/drawable-mdpi-v4/transition.png",
-  "res/drawable-v21/rippleable.xml",
-  "res/drawable-xhdpi-v4/quantum_ic_close_white_24.png",
-  "res/drawable-xhdpi-v4/quantum_ic_settings_white_24.png",
-  "res/drawable-xxhdpi-v4/quantum_ic_close_white_24.png",
-  "res/drawable-xxhdpi-v4/quantum_ic_settings_white_24.png",
-  "res/drawable-xxxhdpi-v4/quantum_ic_close_white_24.png",
-  "res/drawable-xxxhdpi-v4/quantum_ic_settings_white_24.png",
-  "res/drawable/rippleable.xml",
-  "res/layout-land/back_button.xml",
-  "res/layout-land/settings_button.xml",
-  "res/layout-land/ui_layer_with_portrait_support.xml",
-  "res/layout-ldrtl-land-v17/back_button.xml",
-  "res/layout-ldrtl-land-v17/settings_button.xml",
-  "res/layout-ldrtl-v17/back_button.xml",
-  "res/layout-ldrtl-v17/settings_button.xml",
-  "res/layout/back_button.xml",
-  "res/layout/settings_button.xml",
-  "res/layout/transition_view.xml",
-  "res/layout/ui_layer.xml",
-  "res/layout/ui_layer_with_portrait_support.xml",
-  "res/values-ar/values.xml",
-  "res/values-bg/values.xml",
-  "res/values-ca/values.xml",
-  "res/values-cs/values.xml",
-  "res/values-da/values.xml",
-  "res/values-de/values.xml",
-  "res/values-el/values.xml",
-  "res/values-en-rGB/values.xml",
-  "res/values-es-rUS/values.xml",
-  "res/values-es/values.xml",
-  "res/values-fa/values.xml",
-  "res/values-fi/values.xml",
-  "res/values-fr-rCA/values.xml",
-  "res/values-fr/values.xml",
-  "res/values-hi/values.xml",
-  "res/values-hr/values.xml",
-  "res/values-hu/values.xml",
-  "res/values-id/values.xml",
-  "res/values-it/values.xml",
-  "res/values-iw/values.xml",
-  "res/values-ja/values.xml",
-  "res/values-ko/values.xml",
-  "res/values-land/values.xml",
-  "res/values-lt/values.xml",
-  "res/values-lv/values.xml",
-  "res/values-nb/values.xml",
-  "res/values-nl/values.xml",
-  "res/values-pl/values.xml",
-  "res/values-pt-rBR/values.xml",
-  "res/values-pt-rPT/values.xml",
-  "res/values-ro/values.xml",
-  "res/values-ru/values.xml",
-  "res/values-sk/values.xml",
-  "res/values-sl/values.xml",
-  "res/values-sr/values.xml",
-  "res/values-sv/values.xml",
-  "res/values-th/values.xml",
-  "res/values-tl/values.xml",
-  "res/values-tr/values.xml",
-  "res/values-uk/values.xml",
-  "res/values-v19/values.xml",
-  "res/values-v21/values.xml",
-  "res/values-vi/values.xml",
-  "res/values-zh-rCN/values.xml",
-  "res/values-zh-rTW/values.xml",
-  "res/values/values.xml"
-]
-subjar_tuples = []
-subjars = []
diff --git a/third_party/gvr-android-sdk/gvr_controller_java.info b/third_party/gvr-android-sdk/gvr_controller_java.info
deleted file mode 100644
index f647256a..0000000
--- a/third_party/gvr-android-sdk/gvr_controller_java.info
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated by //build/android/gyp/aar.py
-# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
-
-aidl = []
-assets = []
-has_classes_jar = true
-has_native_libraries = false
-has_proguard_flags = false
-has_r_text_file = false
-is_manifest_empty = true
-manifest_package = "com.google.vr.sdk.controller"
-resources = []
-subjar_tuples = []
-subjars = []
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1
deleted file mode 100644
index ebe5e82..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-ccef696b378b176b6dcd9817132b0ed72343f952
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1
deleted file mode 100644
index 0b493c06..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-1a8e9cb3f8fbd6242d2cc473501540a88949fe08
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1
deleted file mode 100644
index d34fbb7..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-feb715a379bcc857747166979b5dca8ec66f5d88
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1
deleted file mode 100644
index 4475b1b..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-200852f7657291f0547cd8a35b9a7259edc2878f
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/native_callbacks_jni.h b/third_party/gvr-android-sdk/native_callbacks_jni.h
deleted file mode 100644
index d8cc90f..0000000
--- a/third_party/gvr-android-sdk/native_callbacks_jni.h
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is of the same format as file that generated by
-//     third_party/jni_zero/jni_zero.py
-// For
-//     com/google/vr/internal/controller/NativeCallbacks
-
-// Local modification includes:
-// 1. Remove all implementation, only keep definition.
-// 2. Use absolute path instead of relative path.
-// 3. Removed all helper functions such as: Create.
-// 4. Removed external functions that don't have implementation in shim file.
-// 5. Replace all nativeHandle to handle. This is because jni_generator.py
-// require jni functions start with "native" prefix. So we add the prefix to
-// generate the file. But the real jni functions in the static library
-// doesn't have the prefix.
-// 6. Added function RegisterNativeCallbacksNatives at the end of this file.
-// 7. Added "vr" as an argument to base::android::LazyGetClass.
-
-#ifndef com_google_vr_internal_controller_NativeCallbacks_JNI
-#define com_google_vr_internal_controller_NativeCallbacks_JNI
-
-#include "base/android/jni_android.h"
-// ----------------------------------------------------------------------------
-// Native JNI methods
-// ----------------------------------------------------------------------------
-#include <jni.h>
-#include <atomic>
-#include <type_traits>
-
-#include "third_party/jni_zero/jni_int_wrapper.h"
-#include "third_party/jni_zero/jni_zero_helper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kNativeCallbacksClassPath[] =
-    "com/google/vr/internal/controller/NativeCallbacks";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-std::atomic<jclass> g_NativeCallbacks_clazz __attribute__((unused)) (nullptr);
-#define NativeCallbacks_clazz(env)                                  \
-  base::android::LazyGetClass(env, kNativeCallbacksClassPath, "vr", \
-                              &g_NativeCallbacks_clazz)
-
-}  // namespace
-
-namespace NativeCallbacks {
-// Step 2: method stubs.
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleStateChanged(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jint newState);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleControllerRecentered(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jfloat qx,
-    jfloat qy,
-    jfloat qz,
-    jfloat qw);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleTouchEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jint action,
-    jfloat x,
-    jfloat y);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleOrientationEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jfloat qx,
-    jfloat qy,
-    jfloat qz,
-    jfloat qw);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleButtonEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jint buttonCode,
-    jboolean down);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleAccelEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jfloat x,
-    jfloat y,
-    jfloat z);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleGyroEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jfloat x,
-    jfloat y,
-    jfloat z);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handlePositionEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jfloat x,
-    jfloat y,
-    jfloat z);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleBatteryEvent(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint controllerIndex,
-    jlong timestampNanos,
-    jboolean isCharging,
-    jint batteryLevelBucket);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceInitFailed(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint failureReason);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceFailed(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceUnavailable(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceConnected(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData,
-    jint flags);
-
-JNI_BOUNDARY_EXPORT void
-Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceDisconnected(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong userData);
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsNativeCallbacks[] = {
-    {"handleStateChanged",
-     "("
-     "J"
-     "I"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleStateChanged)},
-    {"handleControllerRecentered",
-     "("
-     "J"
-     "I"
-     "J"
-     "F"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleControllerRecentered)},
-    {"handleTouchEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "I"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleTouchEvent)},
-    {"handleOrientationEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "F"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleOrientationEvent)},
-    {"handleButtonEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "I"
-     "Z"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleButtonEvent)},
-    {"handleAccelEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleAccelEvent)},
-    {"handleGyroEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleGyroEvent)},
-    {"handlePositionEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "F"
-     "F"
-     "F"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handlePositionEvent)},
-    {"handleBatteryEvent",
-     "("
-     "J"
-     "I"
-     "J"
-     "Z"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleBatteryEvent)},
-    {"handleServiceInitFailed",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceInitFailed)},
-    {"handleServiceFailed",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceFailed)},
-    {"handleServiceUnavailable",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceUnavailable)},
-    {"handleServiceConnected",
-     "("
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceConnected)},
-    {"handleServiceDisconnected",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceDisconnected)},
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
-  const int kMethodsNativeCallbacksSize =
-      std::extent<decltype(kMethodsNativeCallbacks)>();
-
-  if (env->RegisterNatives(NativeCallbacks_clazz(env), kMethodsNativeCallbacks,
-                           kMethodsNativeCallbacksSize) < 0) {
-    jni_generator::HandleRegistrationError(env, NativeCallbacks_clazz(env),
-                                           __FILE__);
-    return false;
-  }
-
-  return true;
-}
-
-static bool RegisterNativeCallbacksNatives(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
-}  // namespace NativeCallbacks
-
-#endif  // com_google_vr_internal_controller_NativeCallbacks_JNI
diff --git a/third_party/gvr-android-sdk/proguard-gvr-chromium.txt b/third_party/gvr-android-sdk/proguard-gvr-chromium.txt
deleted file mode 100644
index c9e4cf6e..0000000
--- a/third_party/gvr-android-sdk/proguard-gvr-chromium.txt
+++ /dev/null
@@ -1,7 +0,0 @@
--dontwarn com.google.common.logging.nano.Vr$**
--dontwarn com.google.vr.**
-
-# Since we manually register, we need to keep every native method.
--keepclasseswithmembers,includedescriptorclasses class com.google.vr.** {
-    native <methods>;
-}
diff --git a/third_party/gvr-android-sdk/src b/third_party/gvr-android-sdk/src
deleted file mode 160000
index 233e7fe..0000000
--- a/third_party/gvr-android-sdk/src
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 233e7fe922a543e0bc55382d64cacd047307d0e7
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt
deleted file mode 100644
index a4b42cda..0000000
--- a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-History of Daydream Home APK hashes
-v1.0 2737c1d56854a2eb15df3c28697fa5267af5c558
-v1.1 12e7c98d6db3ab31a6f9c7e6f07351a9e4b85565
-v1.2 5400db0e25a24e0df9635ab268ef1058a60dfec2
-v1.3 db5eaf6e83a10e809b96375212d5c9dbbe517624
-v1.4 9afe32eb4676d4bcceae81605a3be6aa0e5be3d5
-v1.5 a02e2f95aa6f741f2be0ae03a4829e21fd749cf3
-v1.6 43b876df3398687dfa1ae059ef2f64009c76254e
-v1.7 d5c72438acffe723e7717c45deedd8431bc613e7
-v1.8 cbc81aa4db5986f25d2c967f9b1e247cf07cd75e
-v1.10 eea1bf917782ba00f9194a14e51a7ba1bdc8b896
-v1.12 ac838d3379a1cc5cefe254173d2a463b2df5b5d0
-v1.13 269adc6d3bbceffcdb200c39a5dc32f69f2ada10
-v1.14 34251a8e603ea9fac61dd1841757c23dd9534d63
-v1.15 d56e9ff51188bab2bc9c843aae60bd15b2fcbb96
-v1.16 a19b7e8feaa32a9d5e37de53414e8951e2b87ce7
-v1.17 686bbb327b689972721953121295becb4f5389c6
-v1.19 53d6c9f8cd18d6b48f1b62884d019914f453dfb3
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1
deleted file mode 100644
index 4bbe003b..0000000
--- a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1
+++ /dev/null
@@ -1 +0,0 @@
-53d6c9f8cd18d6b48f1b62884d019914f453dfb3
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/update.py b/third_party/gvr-android-sdk/test-apks/update.py
deleted file mode 100644
index d90a51f..0000000
--- a/third_party/gvr-android-sdk/test-apks/update.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import os
-import subprocess
-import sys
-
-THIS_DIR = os.path.abspath(os.path.dirname(__file__))
-DAYDREAM_DIR = os.path.abspath(os.path.join(THIS_DIR, 'daydream_home'))
-VR_SERVICES_DIR = os.path.abspath(os.path.join(THIS_DIR, 'vr_services'))
-VR_KEYBOARD_DIR = os.path.abspath(os.path.join(THIS_DIR, 'vr_keyboard'))
-
-def main():
-  # VR environment variable is deprecated, use the XR one going forward.
-  if not any(v in os.environ for v in ('DOWNLOAD_VR_TEST_APKS',
-                                       'DOWNLOAD_XR_TEST_APKS')):
-    return 0
-  subprocess.check_call(['download_from_google_storage',
-                                '--bucket', 'chrome-vr-test-apks/daydream_home',
-                                '-d', DAYDREAM_DIR])
-  subprocess.check_call(['download_from_google_storage',
-                                 '--bucket', 'chrome-vr-test-apks/vr_services',
-                                 '-d', VR_SERVICES_DIR])
-  subprocess.check_call(['download_from_google_storage',
-                                 '--bucket', 'chrome-vr-test-apks/vr_keyboard',
-                                 '-d', VR_KEYBOARD_DIR])
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt
deleted file mode 100644
index 7b97d38..0000000
--- a/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-v1.12 a31ceb898c8179e8bda976ff45e497848b9ba0be
-v1.13 0fe388ce58b14909cdc9ee045f07076581491629
-v1.16 56ca300b7d28a752ea24f89c1685f28e83a04002
-v1.17 18ab8790479447a9d0b7768c7eb5420ecbfd70a2
-v1.19 e1626c5ef68812f278ec067038577dbf74238e4d
diff --git a/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1
deleted file mode 100644
index 5840a15..0000000
--- a/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1
+++ /dev/null
@@ -1 +0,0 @@
-e1626c5ef68812f278ec067038577dbf74238e4d
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt
deleted file mode 100644
index 124affd7..0000000
--- a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-History of VR Services APK hashes
-v1.0 33e2c2bb1045fa1e0c3816fd6e8fb0ce6cbd56d4
-v1.1 524b48921472c133183d68a78a8dc675ea4cad35
-v1.2 982709c5cc24922c381413fa32b9cb8e9f004165
-v1.3 8233707ffc519460e1d21f8e1a5364a6336227f2
-v1.4 3024ad78653f11b53d9f15191eab9f11f70610e2
-^^^ 32-bit
-vvv 64-bit
-v1.4 3e0cc24655847c7b922149754324a189e7092310
-v1.5 5d6d55728c7c728cef5416f37b0b71615719474e
-v1.6 abcdae2281956a76aa3b98d2e8f05a1975170dd0
-v1.7 fcfa178173a2c0cab9c7d51829c2ee76ab66e1d9
-v1.8 f8f45ebf1963c5f9862218baca120ea974b87a08
-v1.10 d288911f89f70a459b9fae4720bd3c2ecea26920
-v1.101 6bb3d2b3bc098a60ed255d74d904157fb223df8d
-v1.12 42eebcfe73c4a24d3df6c0513332e93ff3bf6f8c
-v1.13 d2137424d2b6aa84dccabcc59270c89a999de4b9
-v1.14 97b24557b761f02d0d2224d097552a95dae44349
-v1.15 712140d07ac97444cf9d1407b2bafd497e7df1fa
-v1.16 96b849029526f7d980fe66e40ee0c5641774f897
-v1.17 a8554dcd83afd1d9718bc7d341c82f3ffba2efbb
-v1.19 7378cd3efa4386491df7b010b070470f936f2e9e
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1
deleted file mode 100644
index b86450f2..0000000
--- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1
+++ /dev/null
@@ -1 +0,0 @@
-7378cd3efa4386491df7b010b070470f936f2e9e
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1
deleted file mode 100644
index 79552110..0000000
--- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1
+++ /dev/null
@@ -1 +0,0 @@
-524b48921472c133183d68a78a8dc675ea4cad35
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 b/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1
deleted file mode 100644
index c69cf50..0000000
--- a/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-81cecc241ebe1e9d07f09850d0f83082ad52f225
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-libraries/proguard.txt b/third_party/gvr-android-sdk/test-libraries/proguard.txt
deleted file mode 100644
index 9c85a88..0000000
--- a/third_party/gvr-android-sdk/test-libraries/proguard.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# Suppress some warnings that block compilation in release builds, but don't
-# actually affect anything
--dontwarn java.awt.**
--dontwarn javax.lang.model.element.Modifier
diff --git a/third_party/perfetto b/third_party/perfetto
index 905fb0a..7a68d15 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 905fb0a0357086378dc057f82a2e6926bf1341be
+Subproject commit 7a68d15808c7e9714206112aaecbcd90ca1f1c18
diff --git a/third_party/selenium-atoms/README.chromium b/third_party/selenium-atoms/README.chromium
index a05c890..b44aed9 100644
--- a/third_party/selenium-atoms/README.chromium
+++ b/third_party/selenium-atoms/README.chromium
@@ -8,7 +8,6 @@
 License: Apache 2
 License File: LICENSE
 
-
 Description:
   Standard implementation of some WebDriver functions.
 
@@ -46,3 +45,38 @@
 
 Local Modifications:
 - Applied changes in patch.diff to the selenium tree prior to building the atoms.
+
+
+-------------------- DEPENDENCY DIVIDER --------------------
+
+Name: Sizzle
+URL: https://sizzlejs.com/
+Version: N/A
+Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c
+Security Critical: no
+Shipped: yes
+License: MIT, BSD, GPL v2
+License File: LICENSE.sizzle
+
+-------------------- DEPENDENCY DIVIDER --------------------
+
+Name: Wicked Good XPath
+Short Name: wgxpath
+URL: https://github.com/google/wicked-good-xpath
+Version: N/A
+Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c
+Security Critical: no
+Shipped: yes
+License: MIT
+License File: LICENSE.wgxpath
+
+-------------------- DEPENDENCY DIVIDER --------------------
+
+Name: Closure Library
+URL: https://developers.google.com/closure/library
+Version: N/A
+Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c
+Security Critical: no
+Shipped: yes
+License: Apache 2.0
+License File: LICENSE.closure
diff --git a/third_party/skia b/third_party/skia
index f0987bd..d0f09ad 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit f0987bd082ac9bc3d5ed6257c9ecfad18d9b0467
+Subproject commit d0f09ad481f7d8afd73259b1f46ad0dc8d8a1e6b
diff --git a/third_party/webrtc b/third_party/webrtc
index b2e9bab..f698a39 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit b2e9babeb7aac43e3e27bb7f211b8bf994128720
+Subproject commit f698a39eecd1c58108d56d0b541430deebc74a25
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py
index 30f81dd2b..13454b2b 100755
--- a/tools/licenses/licenses.py
+++ b/tools/licenses/licenses.py
@@ -43,7 +43,8 @@
 import action_helpers
 
 METADATA_FILE_NAMES = frozenset({
-    "README.chromium",
+    "README.chromium", "README.crashpad", "README.v8", "README.pdfium",
+    "README.angle"
 })
 
 # Paths from the root of the tree to directories to skip.
@@ -403,28 +404,6 @@
         "License": "Apache 2.0",
         "License File": ["//third_party/dawn/third_party/khronos/LICENSE"],
     },
-    # Dependencies of Selenium Atoms
-    os.path.join('third_party', 'selenium-atoms', 'sizzle'): {
-        "Name": "Sizzle",
-        "URL": "https://sizzlejs.com/",
-        "Shipped": "yes",
-        "License": "MIT, BSD and GPL v2",
-        "License File": ["//third_party/selenium-atoms/LICENSE.sizzle"],
-    },
-    os.path.join('third_party', 'selenium-atoms', 'wgxpath'): {
-        "Name": "Wicked Good XPath",
-        "URL": "https://github.com/google/wicked-good-xpath",
-        "Shipped": "yes",
-        "License": "MIT",
-        "License File": ["//third_party/selenium-atoms/LICENSE.wgxpath"],
-    },
-    os.path.join('third_party', 'selenium-atoms', 'closure-lib'): {
-        "Name": "Closure Library",
-        "URL": "https://developers.google.com/closure/library",
-        "Shipped": "yes",
-        "License": "Apache 2.0",
-        "License File": ["//third_party/selenium-atoms/LICENSE.closure"],
-    },
 }
 
 # These buildtools/third_party directories only contain
@@ -1065,7 +1044,8 @@
   def MetadataToTemplateEntry(metadata, entry_template):
     licenses = []
     for filepath in metadata['License File']:
-      licenses.append(codecs.open(filepath, encoding='utf-8').read())
+      licenses.append(
+          codecs.open(filepath, errors="replace", encoding='utf-8').read())
     license_content = '\n\n'.join(licenses)
 
     env = {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 1cb2eee8..20492a3 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11422,6 +11422,10 @@
   <int value="119" label="Console insight closed"/>
   <int value="120" label="Console insight generation errored"/>
   <int value="121" label="Console insight hover button was shown"/>
+  <int value="122" label="Self-XSS warning shown in console"/>
+  <int value="123" label="Self-XSS warning dialog shown"/>
+  <int value="124" label="Self-XSS pasting allowed in console"/>
+  <int value="125" label="Self-XSS pasting allowed in dialog"/>
 </enum>
 
 <enum name="DevToolsAnimationPlaybackRateChanged">
@@ -30659,6 +30663,7 @@
   <int value="-1187251500" label="OmniboxPedalsBatch2NonEnglish:disabled"/>
   <int value="-1186760297" label="ForceSpectreVariant2Mitigation:disabled"/>
   <int value="-1185833629" label="AppCollectionFolderRefresh:enabled"/>
+  <int value="-1185656634" label="FileSystemProviderContentCache:enabled"/>
   <int value="-1185477291" label="ImeDecoderWithSandbox:enabled"/>
   <int value="-1184904651" label="enable-npapi"/>
   <int value="-1184775907" label="CommercePriceTrackingChipExperiment:enabled"/>
@@ -36848,6 +36853,7 @@
   <int value="1757894817" label="PrinterStatusDialog:disabled"/>
   <int value="1758262950"
       label="OmniboxUIExperimentVerticalMarginLimitToNonTouchOnly:disabled"/>
+  <int value="1758331078" label="FileSystemProviderContentCache:disabled"/>
   <int value="1758688616" label="OmniboxModernizeVisualUpdate:disabled"/>
   <int value="1759193892" label="SafetyCheckExtensions:disabled"/>
   <int value="1759323272" label="DefaultCalculatorWebApp:disabled"/>
@@ -42308,6 +42314,7 @@
   <int value="1205" label="Input"/>
   <int value="1206" label="Customize spell check"/>
   <int value="1207" label="Manage user dictionary"/>
+  <int value="1208" label="App languages"/>
   <int value="1300" label="Network File Shares"/>
   <int value="1301" label="Office Files"/>
   <int value="1302" label="Google Drive"/>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index cae56c46..e20371e 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -701,6 +701,16 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.CommitDocumentLoaderTime" units="ms"
+    expires_after="2024-03-19">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>chrome-loading@google.com</owner>
+  <summary>
+    Measures the time it takes to commit a new document in Blink. Collected once
+    per navigation when a frame is loaded.
+  </summary>
+</histogram>
+
 <histogram base="true" name="Blink.CompositingCommit.UpdateTime"
     units="microseconds" expires_after="2024-06-01">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" -->
@@ -3262,6 +3272,26 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.PrepareToStopParsingTime" units="ms"
+    expires_after="2024-03-19">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>chrome-loading@google.com</owner>
+  <summary>
+    Measures the time it takes to tokenize the HTML document, if necessary, and
+    perform other tasks around parsing completion. Logged every time there is an
+    update to the HTML document.
+  </summary>
+</histogram>
+
+<histogram name="Blink.PumpTokenizerTime" units="ms" expires_after="2024-03-19">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>chrome-loading@google.com</owner>
+  <summary>
+    Measures the time it takes to tokenize an HTML document in Blink. Collected
+    once per update to HTML document.
+  </summary>
+</histogram>
+
 <histogram name="Blink.ResourceRequest.BackgroundResourceFetchSupportStatus"
     enum="BackgroundResourceFetchSupportStatus" expires_after="2024-01-31">
   <owner>horo@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index b91f224..3e609d2a 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -2570,18 +2570,27 @@
   </summary>
 </histogram>
 
-<histogram name="Extensions.InjectedScriptExecutionTime" units="ms"
-    expires_after="never">
+<histogram name="Extensions.InjectedScriptExecutionTime{UserScriptRunLocation}"
+    units="ms" expires_after="never">
 <!-- expires-never: Monitoring performance of a core extension API. -->
 
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
     Time taken to execute all scripts for one location within an extension.
-    Recorded every time content scripts injected by extensions are executed.
-    Unlike Extensions.InjectScriptTime, this includes execution time of
-    asynchronously injected scripts.
+    Recorded every time content scripts injected by extensions are executed
+    {UserScriptRunLocation}. Unlike Extensions.InjectScriptTime, this includes
+    execution time of asynchronously injected scripts.
   </summary>
+  <token key="UserScriptRunLocation">
+    <variant name="" summary="for all script run locations"/>
+    <variant name=".DocumentEnd"
+        summary="with run location of `run_at: document_end`"/>
+    <variant name=".DocumentIdle"
+        summary="with run location of `run_at: document_idle`"/>
+    <variant name=".DocumentStart"
+        summary="with run location of `run_at: document_start`"/>
+  </token>
 </histogram>
 
 <histogram name="Extensions.InjectEnd_BlockingScriptCount" units="units"
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index 853b144..0c8f254 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -1327,12 +1327,6 @@
   <affected-histogram name="Net.QuicSession.SendPacketSize"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ExtensionSource" separator="_" ordering="prefix">
-  <suffix name="OffStore" label="Extension hosted off the Chrome Web Store"/>
-  <suffix name="WebStore" label="Extension from the Chrome Web Store"/>
-  <affected-histogram name="Extensions.ForceInstalledFailureReason3"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="FeedLoadLatencyStep" separator=".">
   <suffix name="ActionUpload"
       label="Time taken read stored actions and upload them if necessary."/>
@@ -4611,13 +4605,6 @@
   <affected-histogram name="Setup.Install.LzmaUnPackStatus"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="UserScriptRunLocation" separator=".">
-  <suffix name="DocumentEnd" label="Scripts with run_at: document_end."/>
-  <suffix name="DocumentIdle" label="Scripts with run_at: document_idle."/>
-  <suffix name="DocumentStart" label="Scripts with run_at: document_start."/>
-  <affected-histogram name="Extensions.InjectedScriptExecutionTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="V8SpecialApps" separator=".">
   <suffix name="calendar" label="Custom histogram for Calendar"/>
   <suffix name="docs" label="Custom histogram for Google Docs and Drive"/>
@@ -4741,13 +4728,6 @@
   <affected-histogram name="Net.WebSocket.ErrorCodes"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="WebStoreLinkExperiment" separator="_">
-  <suffix name="Disabled" label="Neither extra webstore link is visible"/>
-  <suffix name="FooterLink" label="Link in bottom right of footer"/>
-  <suffix name="PlusIcon" label="Plus icon in apps page"/>
-  <affected-histogram name="Extensions.AppLaunch"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="WebUITabStripTabCount" separator=".">
   <suffix name="01_05" label="1 to 5 tabs"/>
   <suffix name="06_20" label="6 to 20 tabs"/>
diff --git a/tools/metrics/histograms/metadata/optimization/enums.xml b/tools/metrics/histograms/metadata/optimization/enums.xml
index 475cda5..a63e2af 100644
--- a/tools/metrics/histograms/metadata/optimization/enums.xml
+++ b/tools/metrics/histograms/metadata/optimization/enums.xml
@@ -289,6 +289,9 @@
   <int value="9" label="Used on-device, but output considered unsafe">
     On-device model was used, it completed successfully, but considered unsafe.
   </int>
+  <int value="10" label="Used on-device, but output contained PII">
+    On-device model was used, but was cancelled because it surfaced PII.
+  </int>
 </enum>
 
 <enum name="OptimizationGuideOnDeviceModelEligibilityReason">
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index ba585cbf..7257879 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -553,6 +553,21 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Signin.BoundSessionCredentials.SessionRegistrationGenerateRegistrationTokenDuration"
+    units="ms" expires_after="2024-04-28">
+  <owner>alexilin@chromium.org</owner>
+  <owner>msalama@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    Records how long the generation of a registration token for the bound
+    session registration has taken. Recorded every time Chrome attempts to
+    register a bound session after an invitation from the server via an HTTP
+    header. This will not be recorded if Chrome couldn't parse the server
+    invitation or just decided to ignore it.
+  </summary>
+</histogram>
+
 <histogram name="Signin.BoundSessionCredentials.SessionRegistrationResult"
     enum="BoundSessionCredentialsSessionRegistrationResult"
     expires_after="2024-04-28">
@@ -567,6 +582,20 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Signin.BoundSessionCredentials.SessionRegistrationTotalDuration"
+    units="ms" expires_after="2024-04-28">
+  <owner>alexilin@chromium.org</owner>
+  <owner>msalama@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    Records how long the bound session registration flow has taken. Recorded
+    every time Chrome attempts to register a bound session after an invitation
+    from the server via an HTTP header. This will not be recorded if Chrome
+    couldn't parse the server invitation or just decided to ignore it.
+  </summary>
+</histogram>
+
 <histogram name="Signin.BoundSessionCredentials.SessionTerminationTrigger"
     enum="SessionTerminationTrigger" expires_after="2024-05-26">
   <owner>alexilin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index dfe137d..0494789a 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc2.EstimatedNoiseLevel" units="dBFS (negated)"
-    expires_after="2023-12-31">
+    expires_after="2024-05-05">
   <owner>alessiob@chromium.org</owner>
   <owner>silen@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index d707f6d4..298f1bc 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -8916,6 +8916,51 @@
   </metric>
 </event>
 
+<event name="Event.Scroll">
+  <owner>woa-performance@google.com</owner>
+  <summary>
+    Metrics related to scroll and scroll jank,
+  </summary>
+  <metric name="FrameCount">
+    <summary>
+      The number of frames that are presented during the scroll. If this is less
+      than or equal to 16, then the presented frame count is considered small;
+      if this is greater than 16 and less than or equal to 64 presented frames,
+      then it is considered medium; if this is greater than 64 presented frames,
+      then it is considered large.
+    </summary>
+  </metric>
+  <metric name="PredictorJankyFrameCount">
+    <summary>
+      The number of frames that are deemed janky to the human eye after Chrome
+      has applied its scroll prediction algorithm..
+    </summary>
+  </metric>
+  <metric name="ScrollJank.DelayedFrameCount">
+    <summary>
+      The number of delayed frames.
+    </summary>
+  </metric>
+  <metric name="ScrollJank.MissedVsyncsMax">
+    <summary>
+      The maximum number of vsyncs missed during any and all janks.
+    </summary>
+  </metric>
+  <metric name="ScrollJank.MissedVsyncsSum">
+    <summary>
+      The total number of vsyncs missed during any and all janks that occurred.
+    </summary>
+  </metric>
+  <metric name="VsyncCount">
+    <summary>
+      The number of vsyncs that occur during the scroll. If this is less than or
+      equal to 16, then the number of vsyncs is considered small; if this is
+      greater than 16 and less than or equal to 64 vsyncs, then it is considered
+      medium; if this is greater than 64 vsyncs, then is considered large.
+    </summary>
+  </metric>
+</event>
+
 <event name="Event.ScrollBegin.Touch">
   <owner>nzolghadr@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 0c8446fe..deb085e 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/3e53e144bee271ec558363df2e561a77d7e0b789/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "7c56c118b715ffeccedd9399ef6dd40130eed9f0",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6e600a104c0d4e59e2647e63ecf075078b5bc3e2/trace_processor_shell.exe"
+            "hash": "1b1f9a9eba84a60170f6bb2bbcdcd3161f61a47c",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/7a68d15808c7e9714206112aaecbcd90ca1f1c18/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "8aa911491cd365131216862ae495e18424ebe1b2",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "10da8a96ca3688e2f43a717c3898576820e25b26",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/905fb0a0357086378dc057f82a2e6926bf1341be/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/7a68d15808c7e9714206112aaecbcd90ca1f1c18/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts b/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts
index 9d59af0..abb2c10 100644
--- a/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts
+++ b/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts
@@ -249,7 +249,6 @@
     if (!this.volumeManager_) {
       return;
     }
-    // TODO(crbug.com/972849): Consider using EventTracker instead.
     this.volumeManager_.removeEventListener(
         'drive-connection-changed', this.onEventBound_);
     this.volumeManager_.removeEventListener(
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts b/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts
deleted file mode 100644
index c3ef675b..0000000
--- a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import type {MetadataParser} from './metadata_parser.js';
-
-/**
- * To invoke steps in parallel.
- */
-export class FunctionParallel {
-  private failed_ = false;
-  private remaining_: number;
-  nextStep: () => void;
-  onError: (err: string) => void;
-
-  /**
-   * @param steps_ Array of functions to invoke in parallel.
-   * @param logger_ Logger object.
-   * @param callback_ Callback to invoke on success.
-   * @param failureCallback_ Callback to invoke on failure.
-   */
-  constructor(
-      private steps_: Function[], private logger_: MetadataParser,
-      private callback_: VoidCallback,
-      private failureCallback_: (err: string) => void) {
-    this.remaining_ = this.steps_.length;
-    this.nextStep = this.nextStep_.bind(this);
-    this.onError = this.onError_.bind(this);
-  }
-
-  /**
-   * Error handling function, which fires error callback.
-   * @param err Error message.
-   */
-  private onError_(err: string) {
-    if (!this.failed_) {
-      this.failed_ = true;
-      this.failureCallback_(err);
-    }
-  }
-
-  /**
-   * Advances to next step. This method should not be used externally. In
-   * external cases should be used nextStep function, which is defined in
-   * closure and thus has access to internal variables of functionsequence.
-   */
-  private nextStep_() {
-    if (--this.remaining_ == 0 && !this.failed_) {
-      this.callback_();
-    }
-  }
-
-  /**
-   * This function should be called only once on start, so start all the
-   * children at once
-   * @param args Arguments to be passed to all the steps.
-   */
-  start(...args: object[]) {
-    this.logger_.vlog(
-        'Starting [' + this.steps_.length + '] parallel tasks ' +
-        'with ' + args.length + ' argument(s)');
-    if (this.logger_.verbose) {
-      for (const arg of args) {
-        this.logger_.vlog(arg);
-      }
-    }
-    for (const step of this.steps_) {
-      this.logger_.vlog('Attempting to start step [' + step.name + ']');
-      try {
-        step.apply(this, args);
-      } catch (e) {
-        this.onError(e!.toString());
-      }
-    }
-  }
-}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts b/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts
deleted file mode 100644
index 9c4ada4..0000000
--- a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {MetadataParser} from './metadata_parser.js';
-
-/**
- * Invoke steps in sequence.
- */
-export class FunctionSequence {
-  private currentStepIdx_ = -1;
-  private failed_ = false;
-
-  started = false;
-  onError: (err: string) => void;
-  finish: () => void;
-  nextStep: (...args: unknown[]) => void;
-
-  /**
-   * @param steps Array of functions to invoke in sequence.
-   * @param logger Logger object.
-   * @param callback Callback to invoke on success.
-   * @param failureCallback Callback to invoke on failure.
-   */
-  constructor(
-      private steps_: Function[], public logger: MetadataParser,
-      private callback_: VoidCallback,
-      private failureCallback_: (error: string) => void) {
-    this.onError = this.onError_.bind(this);
-    this.finish = this.finish_.bind(this);
-    this.nextStep = this.nextStep_.bind(this);
-  }
-
-  /**
-   * Sets new callback
-   *
-   * @param callback New callback to call on succeed.
-   */
-  setCallback(callback: VoidCallback) {
-    this.callback_ = callback;
-  }
-
-  /**
-   * Sets new error callback
-   *
-   * @param failureCallback New callback to call on failure.
-   */
-  setFailureCallback(failureCallback: (error: string) => void) {
-    this.failureCallback_ = failureCallback;
-  }
-
-
-  /**
-   * Error handling function, which traces current error step, stops sequence
-   * advancing and fires error callback.
-   *
-   * @param err Error message.
-   */
-  private onError_(err: string) {
-    this.logger.vlog(
-        'Failed step: ' + this.steps_[this.currentStepIdx_]?.name + ': ' + err);
-    if (!this.failed_) {
-      this.failed_ = true;
-      this.failureCallback_(err);
-    }
-  }
-
-  /**
-   * Finishes sequence processing and jumps to the last step.
-   * This method should not be used externally. In external
-   * cases should be used finish function, which is defined in closure and thus
-   * has access to internal variables of functionsequence.
-   */
-  private finish_() {
-    if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) {
-      this.currentStepIdx_ = this.steps_.length;
-      this.callback_();
-    }
-  }
-
-  /**
-   * Advances to next step.
-   * This method should not be used externally. In external cases should be used
-   * nextStep function, which is defined in closure and thus has access to
-   * internal variables of functionsequence.
-   * @param args Arguments to be passed to the next step.
-   */
-  private nextStep_(...args: unknown[]) {
-    if (this.failed_) {
-      return;
-    }
-
-    if (++this.currentStepIdx_ >= this.steps_.length) {
-      this.logger.vlog('Sequence ended');
-      this.callback_.apply(this);
-    } else {
-      this.logger.vlog(
-          'Attempting to start step [' +
-          this.steps_[this.currentStepIdx_]?.name + ']');
-      try {
-        this.steps_[this.currentStepIdx_]?.apply(this, args);
-      } catch (e) {
-        this.onError(e!.toString());
-      }
-    }
-  }
-
-  /**
-   * This function should be called only once on start, so start sequence
-   * pipeline
-   * @param args Arguments to be passed to the first step.
-   */
-  start(...args: unknown[]) {
-    if (this.started) {
-      throw new Error('"Start" method of FunctionSequence was called twice');
-    }
-
-    this.logger.log('Starting sequence with ' + args.length + ' arguments');
-
-    this.started = true;
-    this.nextStep.apply(this, args);
-  }
-}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts
index 66e77e4..9a357b2f 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts
+++ b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts
@@ -3,8 +3,6 @@
 // found in the LICENSE file.
 
 import {ByteReader, SeekOrigin} from './byte_reader.js';
-import {FunctionParallel} from './function_parallel.js';
-import {FunctionSequence} from './function_sequence.js';
 import {Id3v2Frame, ParserMetadata} from './metadata_item.js';
 import {MetadataParser, MetadataParserLogger} from './metadata_parser.js';
 
@@ -238,8 +236,131 @@
   }
 
   /**
-   * @param file File object to parse.
-   * @param metadata Metadata object of the file.
+   * Parse the `file` and attempt to extract id3v1 metadata from it, and place
+   * these properties on the `metadata` object.
+   * @param file Input File object to parse.
+   * @param metadata Output metadata object of the file.
+   */
+  private async parseId3v1(file: File, metadata: ParserMetadata) {
+    // Reads last 128 bytes of file in bytebuffer, which passes further. In
+    // last 128 bytes should be placed ID3v1 tag if available.
+    const reader =
+        await MetadataParser.readFileBytes(file, file.size - 128, file.size);
+
+    // Attempts to extract ID3v1 tag from 128 bytes long ByteBuffer
+    if (reader.readString(3) == 'TAG') {
+      this.vlog('id3v1 found');
+      const title = reader.readNullTerminatedString(30).trim();
+
+      if (title.length > 0) {
+        metadata.title = title;
+      }
+
+      reader.seek(3 + 30, SeekOrigin.SEEK_BEG);
+
+      const artist = reader.readNullTerminatedString(30).trim();
+      if (artist.length > 0) {
+        metadata.artist = artist;
+      }
+
+      reader.seek(3 + 30 + 30, SeekOrigin.SEEK_BEG);
+
+      const album = reader.readNullTerminatedString(30).trim();
+      if (album.length > 0) {
+        metadata.album = album;
+      }
+    }
+  }
+
+  /**
+   * Parse the `file` and attempt to extract id3v2 metadata from it, and place
+   * these properties on the `metadata` object.
+   * @param file Input File object to parse.
+   * @param metadata Output metadata object of the file.
+   */
+  private async parseId3v2(file: File, metadata: ParserMetadata) {
+    let reader = await MetadataParser.readFileBytes(file, 0, 10);
+
+    // Check if the first 10 bytes contains ID3 header.
+    if (reader.readString(3) !== 'ID3') {
+      return;
+    }
+    this.vlog('id3v2 found');
+    const major = reader.readScalar(1, false);
+    const minor = reader.readScalar(1, false);
+    const flags = reader.readScalar(1, false);
+    const size = Id3Parser.readSynchSafe_(reader, 4);
+    const id3v2 = metadata.id3v2 = {
+      majorVersion: major,
+      minorVersion: minor,
+      flags: flags,
+      size: size,
+      frames: {} as {[frameName: string]: Id3v2Frame},
+    };
+
+    // Extract all ID3v2 frames
+    reader = await MetadataParser.readFileBytes(file, 10, 10 + id3v2.size);
+
+    if ((id3v2.majorVersion > 2) &&
+        ((id3v2.flags & Id3Parser.V2.FLAG_EXTENDED_HEADER) != 0)) {
+      // Skip extended header if found
+      if (id3v2.majorVersion == 3) {
+        reader.seek(reader.readScalar(4, false) - 4);
+      } else if (id3v2.majorVersion == 4) {
+        reader.seek(Id3Parser.readSynchSafe_(reader, 4) - 4);
+      }
+    }
+
+    let frame;
+    while (frame = this.readFrame_(reader, id3v2.majorVersion)) {
+      id3v2.frames[frame.name] = frame;
+    }
+    if (id3v2.frames['APIC']) {
+      metadata.thumbnailURL = id3v2.frames['APIC'].imageUrl;
+    } else if (id3v2.frames['PIC']) {
+      metadata.thumbnailURL = id3v2.frames['PIC'].imageUrl;
+    }
+
+    // Adds 'description' object to metadata. 'description' is used to unify
+    // different parsers and make metadata parser-aware. The key of each
+    // description item should be used to properly format the value before
+    // displaying to users.
+    metadata.description = [];
+
+    for (const [key, frame] of Object.entries(id3v2.frames)) {
+      const mappedKey = Id3Parser.V2.MAPPERS[key];
+      if (mappedKey && frame.value && frame.value.trim().length > 0) {
+        metadata.description.push({
+          key: mappedKey,
+          value: frame.value.trim(),
+        });
+      }
+    }
+
+    function extract(
+        propName: 'album'|'title'|'artist', ...tagNames: string[]) {
+      for (const tagName of tagNames) {
+        const tag = id3v2.frames[tagName];
+        if (tag && tag.value) {
+          metadata[propName] = tag.value;
+          break;
+        }
+      }
+    }
+
+    extract('album', 'TALB', 'TAL');
+    extract('title', 'TIT2', 'TT2');
+    extract('artist', 'TPE1', 'TP1');
+
+    metadata.description.sort((a, b) => {
+      return Id3Parser.METADATA_ORDER.indexOf(a.key) -
+          Id3Parser.METADATA_ORDER.indexOf(b.key);
+    });
+  }
+
+  /**
+   * @param file Input File object to parse.
+   * @param metadata Output metadata object of the file.
    * @param callback Success callback.
    * @param onError Error callback.
    */
@@ -247,192 +368,16 @@
       file: File, metadata: ParserMetadata,
       callback: (metadata: ParserMetadata) => void,
       onError: (error: string) => void) {
-    const self = this;
-
     this.log('Starting id3 parser for ' + file.name);
 
-    const id3v1Parser = new FunctionSequence(
-        [
-          /**
-           * Reads last 128 bytes of file in bytebuffer,
-           * which passes further.
-           * In last 128 bytes should be placed ID3v1 tag if available.
-           * @param file File which bytes to read.
-           */
-          function readTail(this: FunctionSequence, file: File) {
-            MetadataParser.readFileBytes(
-                file, file.size - 128, file.size, this.nextStep, this.onError);
-          },
-
-          /**
-           * Attempts to extract ID3v1 tag from 128 bytes long ByteBuffer
-           * @param file File which tags are being extracted. Could be
-           *     used for logging purposes.
-           * @param reader ByteReader of 128 bytes.
-           */
-          function extractId3v1(
-              this: FunctionSequence, _file: File, reader: ByteReader) {
-            if (reader.readString(3) == 'TAG') {
-              this.logger.vlog('id3v1 found');
-              const title = reader.readNullTerminatedString(30).trim();
-
-              if (title.length > 0) {
-                metadata.title = title;
-              }
-
-              reader.seek(3 + 30, SeekOrigin.SEEK_BEG);
-
-              const artist = reader.readNullTerminatedString(30).trim();
-              if (artist.length > 0) {
-                metadata.artist = artist;
-              }
-
-              reader.seek(3 + 30 + 30, SeekOrigin.SEEK_BEG);
-
-              const album = reader.readNullTerminatedString(30).trim();
-              if (album.length > 0) {
-                metadata.album = album;
-              }
-            }
-            this.nextStep();
-          },
-        ],
-        this, () => {}, _error => {});
-
-    const id3v2Parser = new FunctionSequence(
-        [
-          function readHead(this: FunctionSequence, file: File) {
-            MetadataParser.readFileBytes(
-                file, 0, 10, this.nextStep, this.onError);
-          },
-
-          /**
-           * Check if passed array of 10 bytes contains ID3 header.
-           * @param file File to check and continue reading if ID3
-           *     metadata found.
-           * @param reader Reader to fill with stream bytes.
-           */
-          function checkId3v2(
-              this: FunctionSequence, file: File, reader: ByteReader) {
-            if (reader.readString(3) == 'ID3') {
-              this.logger.vlog('id3v2 found');
-              const major = reader.readScalar(1, false);
-              const minor = reader.readScalar(1, false);
-              const flags = reader.readScalar(1, false);
-              const size = Id3Parser.readSynchSafe_(reader, 4);
-              const id3v2 = metadata.id3v2 = {
-                majorVersion: major,
-                minorVersion: minor,
-                flags: flags,
-                size: size,
-                frames: {},
-              };
-
-              MetadataParser.readFileBytes(
-                  file, 10, 10 + id3v2.size, this.nextStep, this.onError);
-            } else {
-              this.finish();
-            }
-          },
-
-          /**
-           * Extracts all ID3v2 frames from given bytebuffer.
-           * @param file File being parsed.
-           * @param reader Reader to use for metadata extraction.
-           */
-          function extractFrames(
-              this: FunctionSequence, _file: File, reader: ByteReader) {
-            const id3v2 = metadata.id3v2!;
-
-            if ((id3v2.majorVersion > 2) &&
-                ((id3v2.flags & Id3Parser.V2.FLAG_EXTENDED_HEADER) != 0)) {
-              // Skip extended header if found
-              if (id3v2.majorVersion == 3) {
-                reader.seek(reader.readScalar(4, false) - 4);
-              } else if (id3v2.majorVersion == 4) {
-                reader.seek(Id3Parser.readSynchSafe_(reader, 4) - 4);
-              }
-            }
-
-            let frame;
-
-            while (frame = self.readFrame_(reader, id3v2.majorVersion)) {
-              id3v2.frames[frame.name] = frame;
-            }
-
-            this.nextStep();
-          },
-
-          /**
-           * Adds 'description' object to metadata.
-           * 'description' used to unify different parsers and make
-           * metadata parser-aware.
-           * Description is array if value-type pairs. Type should be used
-           * to properly format value before displaying to user.
-           */
-          function prepareDescription(this: FunctionSequence) {
-            const id3v2 = metadata.id3v2!;
-
-            if (id3v2.frames['APIC']) {
-              metadata.thumbnailURL = id3v2.frames['APIC'].imageUrl;
-            } else if (id3v2.frames['PIC']) {
-              metadata.thumbnailURL = id3v2.frames['PIC'].imageUrl;
-            }
-
-            metadata.description = [];
-
-            for (const [key, frame] of Object.entries(id3v2.frames)) {
-              const mappedKey = Id3Parser.V2.MAPPERS[key];
-              if (mappedKey && frame.value && frame.value.trim().length > 0) {
-                metadata.description.push({
-                  key: mappedKey,
-                  value: frame.value.trim(),
-                });
-              }
-            }
-
-            function extract(
-                propName: 'album'|'title'|'artist', ...tagNames: string[]) {
-              for (const tagName of tagNames) {
-                const tag = id3v2.frames[tagName];
-                if (tag && tag.value) {
-                  metadata[propName] = tag.value;
-                  break;
-                }
-              }
-            }
-
-            extract('album', 'TALB', 'TAL');
-            extract('title', 'TIT2', 'TT2');
-            extract('artist', 'TPE1', 'TP1');
-
-            metadata.description.sort((a, b) => {
-              return Id3Parser.METADATA_ORDER.indexOf(a.key) -
-                  Id3Parser.METADATA_ORDER.indexOf(b.key);
-            });
-            this.nextStep();
-          },
-        ],
-        this, () => {}, _error => {});
-
-    const metadataParser = new FunctionParallel(
-        [
-          id3v1Parser.start.bind(id3v1Parser),
-          id3v2Parser.start.bind(id3v2Parser),
-        ],
-        this, () => {
-          callback.call(null, metadata);
-        }, onError);
-
-    id3v1Parser.setCallback(metadataParser.nextStep);
-    id3v2Parser.setCallback(metadataParser.nextStep);
-
-    id3v1Parser.setFailureCallback(metadataParser.onError);
-    id3v2Parser.setFailureCallback(metadataParser.onError);
-
-    this.vlog('Passed argument : ' + file);
-
-    metadataParser.start(file);
+    Promise
+        .all([this.parseId3v1(file, metadata), this.parseId3v2(file, metadata)])
+        .then(() => {
+          callback(metadata);
+        })
+        .catch((e: unknown) => {
+          onError(e!.toString());
+        });
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts
index 7112831..c70d4fd 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts
+++ b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts
@@ -33,15 +33,14 @@
       file: File, metadata: ParserMetadata,
       callback: (metadata: ParserMetadata) => void,
       errorCallback: (error: string) => void) {
-    const self = this;
-    MetadataParser.readFileBytes(file, 0, this.headerSize, (_file, br) => {
-      try {
-        self.parseHeader(metadata, br);
-        callback(metadata);
-      } catch (e) {
-        errorCallback(e!.toString());
-      }
-    }, errorCallback);
+    MetadataParser.readFileBytes(file, 0, this.headerSize)
+        .then(byteReader => {
+          this.parseHeader(metadata, byteReader);
+          callback(metadata);
+        })
+        .catch((e: unknown) => {
+          errorCallback(e!.toString());
+        });
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts
index 6d3fd71..f2dc804 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts
@@ -78,25 +78,14 @@
   }
 
   /**
-   * Utility function to read specified range of bytes from file
+   * Get a ByteReader for a range of bytes from file. Rejects on error.
    * @param file The file to read.
-   * @param begin Starting byte(included).
-   * @param end Last byte(excluded).
-   * @param callback Callback to invoke.
-   * @param onError Error handler.
+   * @param begin Starting byte (included).
+   * @param end Last byte (excluded).
    */
-  static readFileBytes(
-      file: File, begin: number, end: number,
-      callback: (file: File, byteReader: ByteReader) => void,
-      onError: (s: string) => void) {
-    const fileReader = new FileReader();
-    fileReader.onerror = event => {
-      onError(event.type);
-    };
-    fileReader.onloadend = () => {
-      callback(file, new ByteReader(fileReader.result as ArrayBuffer));
-    };
-    fileReader.readAsArrayBuffer(file.slice(begin, end));
+  static async readFileBytes(file: File, begin: number, end: number):
+      Promise<ByteReader> {
+    return new ByteReader(await file.slice(begin, end).arrayBuffer());
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js
deleted file mode 100644
index c849009..0000000
--- a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
-
-import {InstallLinuxPackageDialog} from './install_linux_package_dialog.js';
-
-export function testInstallButtonHiddenUntilInfoReady() {
-  // Polyfill chrome.app.window.current().
-  // @ts-ignore: error TS2339: Property 'app' does not exist on type 'typeof
-  // chrome'.
-  chrome.app = {window: {current: () => null}};
-
-  let getInfoCallback;
-  // @ts-ignore: error TS2740: Type '{ getLinuxPackageInfo: (entry:
-  // FileSystemEntry, callback: (arg0: LinuxPackageInfo) => void) => void; }' is
-  // missing the following properties from type 'typeof fileManagerPrivate':
-  // setPreferences, getDriveConnectionState, PreferencesChange,
-  // DriveConnectionStateType, and 185 more.
-  chrome.fileManagerPrivate = {
-    // @ts-ignore: error TS6133: 'entry' is declared but its value is never
-    // read.
-    getLinuxPackageInfo: (entry, callback) => {
-      getInfoCallback = callback;
-    },
-  };
-
-  const info = {name: 'n', version: 'v', info: 'i', summary: 's'};
-  const dialogElement = document.createElement('dialog');
-  document.body.append(dialogElement);
-  const dialog = new InstallLinuxPackageDialog(dialogElement);
-
-  // Show dialog and verify that the install button is disabled.
-  dialog.showInstallLinuxPackageDialog(/** @type {!Entry} */ ({}));
-  const installButton = document.querySelector('.cr-dialog-ok');
-  // @ts-ignore: error TS2339: Property 'disabled' does not exist on type
-  // 'Element'.
-  assertTrue(installButton.disabled);
-
-  // The install button should become enabled once info is ready.
-  // @ts-ignore: error TS2722: Cannot invoke an object which is possibly
-  // 'undefined'.
-  getInfoCallback(info);
-  // @ts-ignore: error TS2339: Property 'disabled' does not exist on type
-  // 'Element'.
-  assertFalse(installButton.disabled);
-}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts
new file mode 100644
index 0000000..3ea22655
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
+
+import {installMockChrome} from '../../../common/js/mock_chrome.js';
+
+import {InstallLinuxPackageDialog} from './install_linux_package_dialog.js';
+
+export function testInstallButtonHiddenUntilInfoReady() {
+  let getInfoCallback:
+      Parameters<typeof chrome.fileManagerPrivate.getLinuxPackageInfo>[1] =
+          () => {};
+  installMockChrome({
+    fileManagerPrivate: {
+      getLinuxPackageInfo: (_, callback) => {
+        getInfoCallback = callback;
+      },
+    },
+  });
+
+  const info: chrome.fileManagerPrivate.LinuxPackageInfo =
+      {name: 'n', version: 'v', summary: 's', description: 'd'};
+  const dialogElement = document.createElement('dialog');
+  document.body.append(dialogElement);
+  const dialog = new InstallLinuxPackageDialog(dialogElement);
+
+  // Show dialog and verify that the install button is disabled.
+  dialog.showInstallLinuxPackageDialog({} as Entry);
+  const installButton =
+      document.querySelector<HTMLButtonElement>('.cr-dialog-ok')!;
+  assertTrue(installButton.disabled);
+
+  // The install button should become enabled once info is ready.
+  getInfoCallback(info);
+  assertFalse(installButton.disabled);
+}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts
index 50fcd19..456a18b 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {EventTracker} from 'chrome://resources/js/event_tracker.js';
-
 import {Menu} from './menu.js';
 import {MenuItem, MenuItemActivationEvent} from './menu_item.js';
 
@@ -50,12 +48,14 @@
    */
   private menuEndGap_: number = 0;
 
-  private showingEvents_: EventTracker|null = null;
+  /**
+   * AbortController allows for global aborting of all event listeners and thus
+   * their removal from the DOM.
+   */
+  private abortController_: AbortController|null = null;
 
   override initialize() {
     super.initialize();
-    // Event tracker for the sub-menu specific listeners.
-    this.showingEvents_ = new EventTracker();
     this.currentMenu = this;
     this.menuEndGap_ = 18;  // padding on cr.menu + 2px
   }
@@ -333,33 +333,26 @@
       if (subMenuId) {
         const subMenu = document.querySelector(subMenuId);
         if (subMenu) {
-          const self = this.asEventListener();
-          this.showingEvents_!.add(subMenu, 'activate', self);
+          subMenu.addEventListener(
+              'activate', this, {signal: this.abortController_?.signal});
         }
       }
     });
   }
 
-  // TODO: Split the handleEvent() in multiple methods to remove this cast.
-  asEventListener(): EventListener {
-    return this as unknown as EventListener;
-  }
-
   override show(mouseDownPos?: {x: number, y: number}) {
     super.show(mouseDownPos);
     // When the menu is shown we steal all keyboard events.
     const doc = this.ownerDocument;
-    const showingEvents = this.showingEvents_!;
-    // TODO: Split the handleEvent() in multiple methods to remove the cast
-    // below.
-    const self = this as unknown as EventListener;
+    this.abortController_ = new AbortController();
+    const signal = this.abortController_.signal;
     if (doc) {
-      showingEvents.add(doc, 'keydown', self, true);
+      doc.addEventListener('keydown', this, {capture: true, signal});
     }
-    showingEvents.add(this, 'activate', self, true);
+    this.addEventListener('activate', this, {capture: true, signal});
     // Handle mouse-over to trigger sub menu opening on hover.
-    showingEvents.add(this, 'mouseover', self);
-    showingEvents.add(this, 'mouseout', self);
+    this.addEventListener('mouseover', this, {signal});
+    this.addEventListener('mouseout', this, {signal});
     this.addSubMenuListeners();
   }
 
@@ -383,7 +376,7 @@
   }
 
   override hide() {
-    this.showingEvents_!.removeAll();
+    this.abortController_?.abort();
     // Hide any visible sub-menus first
     this.hideSubMenu_();
     super.hide();
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts
index 99357ed..a09ffd2 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {EventTracker} from 'chrome://resources/ash/common/event_tracker.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {assert} from 'chrome://resources/js/assert.js';
 
@@ -38,7 +37,7 @@
    */
   private menuEndGap_: number = 0;  // padding on cr.menu + 2px
 
-  private showingEvents_: EventTracker|null = null;
+  private abortController_: AbortController|null = null;
   private menu_: MultiMenu|null = null;
   private observer_: ResizeObserver|null = null;
   private observedElement_: HTMLElement|null = null;
@@ -71,10 +70,6 @@
     this.observer_ = new ResizeObserver(() => {
       this.positionMenu_();
     });
-
-    // An event tracker for events we only connect to while the menu is
-    // displayed.
-    this.showingEvents_ = new EventTracker();
   }
 
   get menu(): MultiMenu|null {
@@ -279,16 +274,16 @@
     const doc = this.ownerDocument;
     assert(doc.defaultView);
     const win = doc.defaultView;
-    const self = this as unknown as EventListener;
-    assert(this.showingEvents_);
-    this.showingEvents_.add(doc, 'keydown', self, true);
-    this.showingEvents_.add(doc, 'mousedown', self, true);
-    this.showingEvents_.add(doc, 'focus', self, true);
-    this.showingEvents_.add(doc, 'scroll', self, true);
-    this.showingEvents_.add(win, 'popstate', self);
-    this.showingEvents_.add(win, 'resize', self);
-    this.showingEvents_.add(this.menu, 'contextmenu', self);
-    this.showingEvents_.add(this.menu, 'activate', self);
+    this.abortController_ = new AbortController();
+    const signal = this.abortController_.signal;
+    doc.addEventListener('keydown', this, {capture: true, signal});
+    doc.addEventListener('mousedown', this, {capture: true, signal});
+    doc.addEventListener('focus', this, {capture: true, signal});
+    doc.addEventListener('scroll', this, {capture: true, signal});
+    win.addEventListener('popstate', this, {signal});
+    win.addEventListener('resize', this, {signal});
+    this.menu.addEventListener('contextmenu', this, {signal});
+    this.menu.addEventListener('activate', this, {signal});
     this.observedElement_ = this.parentElement;
 
     assert(this.observedElement_);
@@ -337,7 +332,6 @@
     this.setAttribute('aria-expanded', 'false');
     this.removeAttribute('menu-shown');
     assert(this.menu);
-    assert(this.showingEvents_);
     assert(this.observer_);
     assert(this.observedElement_);
 
@@ -348,7 +342,7 @@
     }
     this.menu.hide();
 
-    this.showingEvents_.removeAll();
+    this.abortController_?.abort();
     if (shouldTakeFocus) {
       this.focus();
     }
diff --git a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
index 7c712d9e..c280831 100644
--- a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
+++ b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
@@ -6,16 +6,17 @@
 
 import {MockVolumeManager} from '../../background/js/mock_volume_manager.js';
 import {FakeEntryImpl, GuestOsPlaceholder, VolumeEntry} from '../../common/js/files_app_entry_types.js';
+import {MockFileSystem} from '../../common/js/mock_entry.js';
 import {waitUntil} from '../../common/js/test_error_reporting.js';
 import {RootType, VolumeType} from '../../common/js/volume_manager_types.js';
 import {FileData, State} from '../../externs/ts/state.js';
 import type {VolumeInfo} from '../../externs/volume_info.js';
-import {convertEntryToFileData} from '../ducks/all_entries.js';
+import {convertEntryToFileData, readSubDirectories} from '../ducks/all_entries.js';
 import {createFakeVolumeMetadata, setUpFileManagerOnWindow, setupStore, waitDeepEquals} from '../for_tests.js';
-import {getEmptyState} from '../store.js';
+import {getEmptyState, getEntry} from '../store.js';
 
 import {addUiEntry, removeUiEntry} from './ui_entries.js';
-import {convertVolumeInfoAndMetadataToVolume} from './volumes.js';
+import {addVolume, convertVolumeInfoAndMetadataToVolume} from './volumes.js';
 
 export function setUp() {
   // sortEntries() from addUiEntry() reducer requires volumeManager and
@@ -308,3 +309,60 @@
 
   done();
 }
+
+/**
+ * Test MyFiles children should include PlayFiles even PlayFiles ui entry is
+ * added when there's an ongoing scanning call for MyFiles.
+ */
+export async function testPlayFilesAddedDuringScanningMyFiles() {
+  const store = setupStore();
+  const {volumeInfo} = createMyFilesDataWithVolumeEntry();
+  const myFilesEntry = new VolumeEntry(volumeInfo);
+  // Populate one sub folder for MyFiles.
+  const downloadsFS = volumeInfo.fileSystem as MockFileSystem;
+  downloadsFS.populate([
+    '/sub-dir/',
+  ]);
+  const subDirEntry = downloadsFS.entries['/sub-dir']!;
+  // Add MyFiles to the store.
+  store.dispatch(addVolume(
+      {volumeInfo, volumeMetadata: createFakeVolumeMetadata(volumeInfo)}));
+  await waitUntil(() => {
+    return !!store.getState().allEntries[myFilesEntry.toURL()];
+  });
+  const myFilesEntryInStore =
+      getEntry(store.getState(), myFilesEntry.toURL()) as VolumeEntry;
+
+  // Dispatch an action to read children of MyFiles. At this moment, the
+  // UiChildren of MyFiles is empty so no `StaticReader` will be added to
+  // MyFiles.
+  store.dispatch(readSubDirectories(myFilesEntryInStore));
+
+  // Dispatch an action to add an ui entry at the same time.
+  const playFilesUiEntry = new GuestOsPlaceholder(
+      'Play files', 0, chrome.fileManagerPrivate.VmType.ARCVM);
+  store.dispatch(addUiEntry(playFilesUiEntry));
+
+  // Expect PlayFiles should be in the store eventually.
+  myFilesEntry.addEntry(playFilesUiEntry);
+  const want: Partial<State> = {
+    allEntries: {
+      [myFilesEntry.toURL()]: {
+        ...convertEntryToFileData(myFilesEntry),
+        children: [
+          subDirEntry.toURL(),
+          playFilesUiEntry.toURL(),
+        ],
+      },
+      [playFilesUiEntry.toURL()]: convertEntryToFileData(playFilesUiEntry),
+      [subDirEntry.toURL()]: convertEntryToFileData(subDirEntry),
+    },
+  };
+
+  await waitDeepEquals(store, want, (state) => ({
+                                      allEntries: state.allEntries,
+                                    }));
+  const uiChildren = myFilesEntryInStore.getUiChildren();
+  assertEquals(1, uiChildren.length);
+  assertEquals(playFilesUiEntry, uiChildren[0]);
+}
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index c939d16..2e913c0 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -345,8 +345,6 @@
   "file_manager/foreground/js/metadata/exif_parser.ts",
   "file_manager/foreground/js/metadata/external_metadata_provider.ts",
   "file_manager/foreground/js/metadata/file_system_metadata_provider.ts",
-  "file_manager/foreground/js/metadata/function_parallel.ts",
-  "file_manager/foreground/js/metadata/function_sequence.ts",
   "file_manager/foreground/js/metadata/id3_parser.ts",
   "file_manager/foreground/js/metadata/image_parsers.ts",
   "file_manager/foreground/js/metadata/metadata_cache_item.ts",
@@ -537,6 +535,7 @@
   "file_manager/foreground/js/ui/file_table_list_unittest.ts",
   "file_manager/foreground/js/ui/file_table_unittest.ts",
   "file_manager/foreground/js/ui/grid_unittest.ts",
+  "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts",
   "file_manager/foreground/js/ui/menu_unittest.ts",
   "file_manager/foreground/js/ui/multi_menu_unittest.ts",
   "file_manager/foreground/js/ui/list_single_selection_model_unittest.ts",
@@ -626,7 +625,6 @@
 unittest_files = [
   # Foreground:
   "file_manager/foreground/js/ui/file_tap_handler_unittest.js",
-  "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js",
   "file_manager/foreground/js/ui/directory_tree_unittest.js",
   "file_manager/foreground/js/navigation_list_model_unittest.js",
 
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index a4dcb0f..57adcf7 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -141,7 +141,10 @@
     return false;
   }
 
-  VLOG(1) << "Starting DND session.";
+  VLOG(1) << "Starting Drag-and-Drop session. tracker_id=" << serial->value
+          << ", data_source="
+          << (source == DragEventSource::kMouse ? "mouse" : "touch")
+          << ", serial tracker=" << connection_->serial_tracker().ToString();
 
   // Create new data source and offers |data|.
   SetOfferedExchangeDataProvider(data);
diff --git a/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc b/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc
index 2f0a7084..437e3d7 100644
--- a/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc
+++ b/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc
@@ -70,7 +70,7 @@
     if (!serial) {
       out << "<none>";
     } else {
-      out << "serial=" << serial->value << ", time=" << serial->timestamp;
+      out << "tracker_id=" << serial->value << ", time=" << serial->timestamp;
     };
   };
   std::ostringstream out;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
index 8f262de..86b8f52 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -131,7 +131,7 @@
     return false;
   }
 
-  VLOG(1) << "Starting DND session. serial=" << serial->value
+  VLOG(1) << "Starting Window Drag session. tracker_id=" << serial->value
           << ", data_source="
           << (drag_source == DragEventSource::kMouse ? "mouse" : "touch")
           << ", serial tracker=" << connection_->serial_tracker().ToString();
diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc
index 1d0c1c7..33bc04d 100644
--- a/ui/views/layout/box_layout.cc
+++ b/ui/views/layout/box_layout.cc
@@ -85,6 +85,29 @@
   return view_->GetVisible() && !view_->GetProperty(kViewIgnoredByLayoutKey);
 }
 
+// BoxLayoutFlexSpecification --------------------------------------------------
+
+BoxLayoutFlexSpecification::BoxLayoutFlexSpecification() = default;
+
+BoxLayoutFlexSpecification BoxLayoutFlexSpecification::WithWeight(
+    int weight) const {
+  DCHECK_GE(weight, 0);
+  BoxLayoutFlexSpecification spec = *this;
+  spec.weight_ = weight;
+  return spec;
+}
+
+BoxLayoutFlexSpecification BoxLayoutFlexSpecification::UseMinSize(
+    bool use_min_size) const {
+  BoxLayoutFlexSpecification spec = *this;
+  spec.use_min_size_ = use_min_size;
+  return spec;
+}
+
+BoxLayoutFlexSpecification::~BoxLayoutFlexSpecification() = default;
+
+// BoxLayout --------------------------------------------------
+
 BoxLayout::BoxLayout(BoxLayout::Orientation orientation,
                      const gfx::Insets& inside_border_insets,
                      int between_child_spacing,
@@ -125,13 +148,15 @@
   DCHECK(view);
   DCHECK_EQ(host_, view->parent());
   DCHECK_GE(flex_weight, 0);
-  flex_map_[view].flex_weight = flex_weight;
-  flex_map_[view].use_min_size = use_min_size;
+  const_cast<View*>(view)->SetProperty(kBoxLayoutFlexKey,
+                                       BoxLayoutFlexSpecification()
+                                           .WithWeight(flex_weight)
+                                           .UseMinSize(use_min_size));
 }
 
 void BoxLayout::ClearFlexForView(const View* view) {
   DCHECK(view);
-  flex_map_.erase(view);
+  const_cast<View*>(view)->ClearProperty(kBoxLayoutFlexKey);
 }
 
 void BoxLayout::SetDefaultFlex(int default_flex) {
@@ -382,12 +407,8 @@
 }
 
 int BoxLayout::GetFlexForView(const View* view) const {
-  // Give precedence to flex provided via the layout.
-  if (auto it = flex_map_.find(view); it != flex_map_.end()) {
-    return it->second.flex_weight;
-  }
-  // Respect flex provided via the `kFlexBehaviorKey`.
-  if (auto* flex_behavior_key = view->GetProperty(kFlexBehaviorKey)) {
+  // Respect flex provided via the `kBoxLayoutFlexKey`.
+  if (auto* flex_behavior_key = view->GetProperty(kBoxLayoutFlexKey)) {
     return flex_behavior_key->weight();
   }
   // Fall back to default.
@@ -395,9 +416,10 @@
 }
 
 int BoxLayout::GetMinimumSizeForView(const View* view) const {
-  auto it = flex_map_.find(view);
-  if (it == flex_map_.end() || !it->second.use_min_size)
+  auto* flex_behavior_key = view->GetProperty(kBoxLayoutFlexKey);
+  if (!flex_behavior_key || !flex_behavior_key->use_min_size()) {
     return 0;
+  }
 
   return (orientation_ == Orientation::kHorizontal)
              ? view->GetMinimumSize().width()
diff --git a/ui/views/layout/box_layout.h b/ui/views/layout/box_layout.h
index dcdb9847..38a712d 100644
--- a/ui/views/layout/box_layout.h
+++ b/ui/views/layout/box_layout.h
@@ -5,8 +5,6 @@
 #ifndef UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
 #define UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
 
-#include <map>
-
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "ui/gfx/geometry/insets.h"
@@ -20,6 +18,25 @@
 
 namespace views {
 
+class VIEWS_EXPORT BoxLayoutFlexSpecification {
+ public:
+  BoxLayoutFlexSpecification();
+  ~BoxLayoutFlexSpecification();
+
+  // Makes a copy of this specification with a different weight.
+  BoxLayoutFlexSpecification WithWeight(int weight) const;
+
+  // Whether to use minimum values to make copies of this specification.
+  BoxLayoutFlexSpecification UseMinSize(bool use_min_size) const;
+
+  int weight() const { return weight_; }
+  bool use_min_size() const { return use_min_size_; }
+
+ private:
+  int weight_ = 1;
+  bool use_min_size_ = false;
+};
+
 // A Layout manager that arranges child views vertically or horizontally in a
 // side-by-side fashion with spacing around and between the child views. The
 // child views are always sized according to their preferred size. If the
@@ -219,13 +236,6 @@
     gfx::Insets margins_;
   };
 
-  struct Flex {
-    int flex_weight;
-    bool use_min_size;
-  };
-
-  using FlexMap = std::map<const View*, Flex>;
-
   // Returns the flex for the specified |view|.
   int GetFlexForView(const View* view) const;
 
@@ -343,9 +353,6 @@
   // kStretch by default.
   CrossAxisAlignment cross_axis_alignment_ = CrossAxisAlignment::kStretch;
 
-  // A map of views to their flex weights.
-  FlexMap flex_map_;
-
   // The flex weight for views if none is set. Defaults to 0.
   int default_flex_ = 0;
 
diff --git a/ui/views/layout/box_layout_unittest.cc b/ui/views/layout/box_layout_unittest.cc
index a64ad8f..6c97d70 100644
--- a/ui/views/layout/box_layout_unittest.cc
+++ b/ui/views/layout/box_layout_unittest.cc
@@ -726,17 +726,18 @@
   EXPECT_EQ(gfx::Rect(0, 0, 20, 50).ToString(), v1->bounds().ToString());
   EXPECT_EQ(gfx::Rect(0, 50, 20, 50).ToString(), v2->bounds().ToString());
 
-  // Set `kFlexBehaviorKey` so that the first view fills 2/3 of the available
-  // space. Flex set via `kFlexBehaviorKey` takes higher precedence than default
-  // flex.
-  v1->SetProperty(kFlexBehaviorKey, FlexSpecification().WithWeight(2));
+  // Set `kBoxLayoutFlexKey` so that the first view fills 2/3 of the available
+  // space. Flex set via `kBoxLayoutFlexKey` takes higher precedence than
+  // default flex.
+  v1->SetProperty(kBoxLayoutFlexKey,
+                  BoxLayoutFlexSpecification().WithWeight(2));
   HandleHostLayoutManagerChanges();
   EXPECT_EQ(gfx::Rect(0, 0, 20, 60).ToString(), v1->bounds().ToString());
   EXPECT_EQ(gfx::Rect(0, 60, 20, 40).ToString(), v2->bounds().ToString());
 
   // Set flex so that the first view fills 3/4 of the available space. Flex for
   // a view set on the `layout` takes higher precedence than flex set via
-  // `kFlexBehaviorKey`.
+  // `kBoxLayoutFlexKey`.
   layout->SetFlexForView(v1, 3);
   HandleHostLayoutManagerChanges();
   EXPECT_EQ(gfx::Rect(0, 0, 20, 65).ToString(), v1->bounds().ToString());
diff --git a/ui/views/view_class_properties.cc b/ui/views/view_class_properties.cc
index 65639cc..134c3c7c 100644
--- a/ui/views/view_class_properties.cc
+++ b/ui/views/view_class_properties.cc
@@ -8,6 +8,7 @@
 #include "ui/gfx/geometry/insets.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 #include "ui/views/controls/highlight_path_generator.h"
+#include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/flex_layout_types.h"
 
 #if !defined(USE_AURA)
@@ -21,6 +22,8 @@
 DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::DialogDelegate*)
 
 DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT,
+                                       views::BoxLayoutFlexSpecification*)
+DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT,
                                        views::HighlightPathGenerator*)
 DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::FlexSpecification*)
 DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::LayoutAlignment*)
@@ -34,6 +37,9 @@
 DEFINE_UI_CLASS_PROPERTY_KEY(views::DialogDelegate*,
                              kAnchoredDialogKey,
                              nullptr)
+DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(BoxLayoutFlexSpecification,
+                                   kBoxLayoutFlexKey,
+                                   nullptr)
 DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(views::HighlightPathGenerator,
                                    kHighlightPathGeneratorKey,
                                    nullptr)
diff --git a/ui/views/view_class_properties.h b/ui/views/view_class_properties.h
index 986396a..fc6daa3 100644
--- a/ui/views/view_class_properties.h
+++ b/ui/views/view_class_properties.h
@@ -21,6 +21,7 @@
 class DialogDelegate;
 class FlexSpecification;
 class HighlightPathGenerator;
+class BoxLayoutFlexSpecification;
 
 // The hit test component (e.g. HTCLIENT) for a View in a window frame. Defaults
 // to HTNOWHERE.
@@ -48,13 +49,18 @@
 VIEWS_EXPORT extern const ui::ClassProperty<DialogDelegate*>* const
     kAnchoredDialogKey;
 
+// A property to store how a view should flex when placed in a layout.
+// Only supported by BoxLayout.
+VIEWS_EXPORT extern const ui::ClassProperty<BoxLayoutFlexSpecification*>* const
+    kBoxLayoutFlexKey;
+
 // A property to store a highlight-path generator. This generator is used to
 // generate a highlight path for focus rings or ink-drop effects.
 VIEWS_EXPORT extern const ui::ClassProperty<HighlightPathGenerator*>* const
     kHighlightPathGeneratorKey;
 
 // A property to store how a view should flex when placed in a layout.
-// Currently only fully supported by FlexLayout. BoxLayout supports weight.
+// Currently only supported by FlexLayout.
 VIEWS_EXPORT extern const ui::ClassProperty<FlexSpecification*>* const
     kFlexBehaviorKey;
 
diff --git a/v8 b/v8
index 3970923..fccd7ef 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 3970923e265f3f8a2420cefd55ee1bdabe44e6a4
+Subproject commit fccd7efb786d611b5d6d2903e6900c562aaa7dd4